GoFigure2-v0.9.0/0000755000175000017500000000000011667757442013374 5ustar mathieumathieuGoFigure2-v0.9.0/KWStyle/0000755000175000017500000000000011667757442014736 5ustar mathieumathieuGoFigure2-v0.9.0/KWStyle/GOFIGURE2_Files.txt.in0000644000175000017500000000071311667757442020520 0ustar mathieumathieu@GOFIGURE2_SOURCE_DIR@/Code/GUI/lib/*.h @GOFIGURE2_SOURCE_DIR@/Code/GUI/lib/*.cxx @GOFIGURE2_SOURCE_DIR@/Code/IO/*.h @GOFIGURE2_SOURCE_DIR@/Code/IO/*.cxx @GOFIGURE2_SOURCE_DIR@/Code/IO/*.txx @GOFIGURE2_SOURCE_DIR@/Code/Filters/*.h @GOFIGURE2_SOURCE_DIR@/Code/Filters/*.txx @GOFIGURE2_SOURCE_DIR@/Code/Filters/*.cxx @GOFIGURE2_SOURCE_DIR@/Interfaces/*.h @GOFIGURE2_SOURCE_DIR@/Interfaces/*.cxx @GOFIGURE2_SOURCE_DIR@/Main/*.h @GOFIGURE2_SOURCE_DIR@/Main/*.cxx GoFigure2-v0.9.0/KWStyle/KWStyle.cmake0000644000175000017500000000744511667757442017314 0ustar mathieumathieuOPTION(GOFIGURE2_USE_KWSTYLE "Enable the use of KWStyle for checking coding style." OFF) IF(GOFIGURE2_USE_KWSTYLE) # Set the required KWStyle version SET(KWSTYLE_REQ_MAJOR 1) SET(KWSTYLE_REQ_MINOR 0) SET(KWSTYLE_REQ_PATCH 1) OPTION(KWSTYLE_USE_VIM_FORMAT "Set KWStyle to generate errors with a VIM-compatible format." OFF) OPTION(KWSTYLE_USE_MSVC_FORMAT "Set KWStyle to generate errors with a VisualStudio-compatible format." OFF) FIND_PROGRAM(KWSTYLE_EXECUTABLE NAMES KWStyle PATHS /usr/local/bin ) IF(KWSTYLE_EXECUTABLE) EXECUTE_PROCESS( COMMAND ${KWSTYLE_EXECUTABLE} -version OUTPUT_VARIABLE KWSTYLE_VERSION_TEXT ) string(STRIP ${KWSTYLE_VERSION_TEXT} KWSTYLE_VERSION_TEXT) IF(KWSTYLE_VERSION_TEXT STREQUAL "Version: Not defined") MESSAGE("This project requires a newer version of KWStyle. Please upgrade the KWStyle executable.") ELSE(${KWSTYLE_VERSION_TEXT} STREQUAL "Version: Not defined") string(LENGTH ${KWSTYLE_VERSION_TEXT} KWSTYLE_VERSION_LENGTH) math(EXPR KWSTYLE_VERSION_FINAL_LENGTH "${KWSTYLE_VERSION_LENGTH}-9") string(SUBSTRING ${KWSTYLE_VERSION_TEXT} 9 ${KWSTYLE_VERSION_FINAL_LENGTH} KWSTYLE_VERSION) # now parse the parts of the user given version string into variables STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" KWSTYLE_MAJOR_VERSION "${KWSTYLE_VERSION}") STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" KWSTYLE_MINOR_VERSION "${KWSTYLE_VERSION}") STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" KWSTYLE_PATCH_VERSION "${KWSTYLE_VERSION}") MATH(EXPR KWSTYLE_REQ_VERSION "${KWSTYLE_REQ_MAJOR}*10000 + ${KWSTYLE_REQ_MINOR}*100 + ${KWSTYLE_REQ_PATCH}") MATH(EXPR KWSTYLE_LONG_VERSION "${KWSTYLE_MAJOR_VERSION}*10000 + ${KWSTYLE_MINOR_VERSION}*100 + ${KWSTYLE_PATCH_VERSION}") # Set the minimum require version for batchmake IF(KWSTYLE_LONG_VERSION LESS KWSTYLE_REQ_VERSION) MESSAGE(FATAL_ERROR "This project requires a newer version of KWStyle. Please upgrade the KWStyle executable.") ELSE(KWSTYLE_LONG_VERSION LESS KWSTYLE_REQ_VERSION) SET(KWSTYLE_FOUND 1) ENDIF(KWSTYLE_LONG_VERSION LESS KWSTYLE_REQ_VERSION) ENDIF(KWSTYLE_VERSION_TEXT STREQUAL "Version: Not defined") IF(KWSTYLE_FOUND) # # Define file names # SET(KWSTYLE_CONFIGURATION_FILE ${GOFIGURE2_BINARY_DIR}/KWStyle/GOFIGURE2.kws.xml) SET(KWSTYLE_GOFIGURE2_FILES_LIST ${GOFIGURE2_BINARY_DIR}/KWStyle/GOFIGURE2_Files.txt) SET(KWSTYLE_GOFIGURE2_OVERWRITE_FILE ${GOFIGURE2_SOURCE_DIR}/KWStyle/GOFIGURE2_Overwrite.txt ) # # Configure the files # CONFIGURE_FILE( ${GOFIGURE2_SOURCE_DIR}/KWStyle/GOFIGURE2_Files.txt.in ${KWSTYLE_GOFIGURE2_FILES_LIST} ) CONFIGURE_FILE( ${GOFIGURE2_SOURCE_DIR}/KWStyle/GOFIGURE2.kws.xml.in ${KWSTYLE_CONFIGURATION_FILE} ) # # Define formatting for error messages # SET(KWSTYLE_EDITOR_FORMAT " ") SET(KWSTYLE_EDITOR_FORMAT "") IF(${CMAKE_CXX_COMPILER} MATCHES "cl.exe$") SET(KWSTYLE_USE_MSVC_FORMAT 1) ENDIF(${CMAKE_CXX_COMPILER} MATCHES "cl.exe$") IF(${CMAKE_C_COMPILER} MATCHES "g[cx][cx]$") SET(KWSTYLE_USE_VIM_FORMAT 1) ENDIF(${CMAKE_C_COMPILER} MATCHES "g[cx][cx]$") IF(KWSTYLE_USE_VIM_FORMAT) SET(KWSTYLE_EDITOR_FORMAT -vim) ENDIF(KWSTYLE_USE_VIM_FORMAT) IF(KWSTYLE_USE_MSVC_FORMAT) SET(KWSTYLE_EDITOR_FORMAT -msvc) ENDIF(KWSTYLE_USE_MSVC_FORMAT) SET(KWSTYLE_ARGUMENTS_CODE -xml ${KWSTYLE_CONFIGURATION_FILE} -v -D ${KWSTYLE_GOFIGURE2_FILES_LIST} -o ${KWSTYLE_GOFIGURE2_OVERWRITE_FILE} ${KWSTYLE_EDITOR_FORMAT} ) ADD_CUSTOM_COMMAND( OUTPUT ${GOFIGURE2_BINARY_DIR}/KWStyleCodeReport.txt COMMAND ${KWSTYLE_EXECUTABLE} ARGS ${KWSTYLE_ARGUMENTS_CODE} COMMENT "Coding Style Checker" ) ADD_CUSTOM_TARGET(StyleCheckCode DEPENDS ${GOFIGURE2_BINARY_DIR}/KWStyleCodeReport.txt) ADD_TEST(KWStyleCodeTest ${KWSTYLE_EXECUTABLE} ${KWSTYLE_ARGUMENTS_CODE}) ENDIF(KWSTYLE_FOUND) ENDIF(KWSTYLE_EXECUTABLE) ENDIF(GOFIGURE2_USE_KWSTYLE) GoFigure2-v0.9.0/KWStyle/GOFIGURE2_Overwrite.txt0000644000175000017500000000000011667757442021024 0ustar mathieumathieuGoFigure2-v0.9.0/KWStyle/CopyrightSource.txt0000644000175000017500000000341611667757442020634 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ GoFigure2-v0.9.0/KWStyle/CMakeLists.txt0000644000175000017500000000072011667757442017475 0ustar mathieumathieu#----------------------------------------------------------------------------- # uses KWStyle for checking the coding style INCLUDE(KWStyle.cmake) IF(UNIX) CONFIGURE_FILE(${GOFIGURE2_SOURCE_DIR}/KWStyle/doAllStyle.csh.in ${GOFIGURE2_BINARY_DIR}/doAllStyle.csh @ONLY IMMEDIATE) EXEC_PROGRAM(chmod ARGS 755 \"${GOFIGURE2_BINARY_DIR}/doAllStyle.csh\" OUTPUT_VARIABLE ITK_EXEC_PLEASE_BE_QUIET) ENDIF(UNIX) GoFigure2-v0.9.0/KWStyle/GOFIGURE2.kws.xml.in0000644000175000017500000000241711667757442020165 0ustar mathieumathieu GoFigure2 @GOFIGURE2_SOURCE_DIR@/Resources/fig/splash.jpg /home/ajg23/CVSROOT/KWStyle/Web/images/TitleBar.jpg 120 0 1 2 [A-Z] m_[A-Z] 0 [a-z] 0 1 1 3 /** * */ false
@GOFIGURE2_SOURCE_DIR@/KWStyle/Header.h false true
SPACE 2 true true __[NameOfClass]_[Extension] 2 1 1
GoFigure2-v0.9.0/KWStyle/uncrustify.sh0000755000175000017500000000613211667757442017512 0ustar mathieumathieu#!/bin/sh # # # ========================================================================= # Modifications were made by the GoFigure Dev. Team. # while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 # # Copyright (c) 2009-11, President and Fellows of Harvard College. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # Neither the name of the President and Fellows of Harvard College # nor the names of its contributors may be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ========================================================================= # # # Linux Shell Script to run ITK tests in linux # function local_uncrustify { configuration_file=$1; directory=$2; # find cxx files for i in `find $directory -name *.cxx`; do echo "Correcting file style: $i"; uncrustify -c $configuration_file -f $i -o $i; echo "Done"; done; # find cxx.in files for i in `find $directory -name *.cxx.in`; do echo "Correcting file style: $i"; uncrustify -c $configuration_file -f $i -o $i; echo "Done"; done; # find h files for i in `find $directory -name *.h`; do echo "Correcting file style: $i"; uncrustify -c $configuration_file -f $i -o $i; echo "Done"; done; # find h.in files for i in `find $directory -name *.h.in`; do echo "Correcting file style: $i"; uncrustify -c $configuration_file -f $i -o $i; echo "Done"; done; # find txx files for i in `find $directory -name *.txx`; do echo "Correcting file style: $i"; uncrustify -c $configuration_file -f $i -o $i; echo "Done"; done; } working_directory=`pwd`; configuration_file="$working_directory"/uncrustify.cfg; local_uncrustify $configuration_file "$working_directory"/../Code local_uncrustify $configuration_file "$working_directory"/../Examples local_uncrustify $configuration_file "$working_directory"/../Main GoFigure2-v0.9.0/KWStyle/uncrustify.cfg0000644000175000017500000016554211667757442017647 0ustar mathieumathieu# Uncrustify 0.56 # # General options # # The type of line endings newlines = auto # auto/lf/crlf/cr # The original size of tabs in the input input_tab_size = 2 # number # The size of tabs in the output (only used if align_with_tabs=true) output_tab_size = 2 # number # The ASCII value of the string escape char, usually 92 (\) or 94 (^). (Pawn) string_escape_char = 92 # number # Alternate string escape char for Pawn. Only works right before the quote char. string_escape_char2 = 0 # number # # Indenting # # The number of columns to indent per level. # Usually 2, 3, 4, or 8. indent_columns = 2 # number # The continuation indent. If non-zero, this overrides the indent of '(' and '=' continuation indents. # For FreeBSD, this is set to 4. indent_continue = 0 # number # How to use tabs when indenting code # 0=spaces only # 1=indent with tabs to brace level, align with spaces # 2=indent and align with tabs, using spaces when not on a tabstop indent_with_tabs = 0 # number # Comments that are not a brace level are indented with tabs on a tabstop. # Requires indent_with_tabs=2. If false, will use spaces. indent_cmt_with_tabs = false # false/true # Whether to indent strings broken by '\' so that they line up indent_align_string = false # false/true # The number of spaces to indent multi-line XML strings. # Requires indent_align_string=True indent_xml_string = 0 # number # Spaces to indent '{' from level indent_brace = 0 # number # Whether braces are indented to the body level indent_braces = true # false/true # Disabled indenting function braces if indent_braces is true indent_braces_no_func = true # false/true # Disabled indenting class braces if indent_braces is true indent_braces_no_class = true # false/true # Disabled indenting struct braces if indent_braces is true indent_braces_no_struct = false # false/true # Indent based on the size of the brace parent, i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. indent_brace_parent = false # false/true # Whether the 'namespace' body is indented indent_namespace = false # false/true # The number of spaces to indent a namespace block indent_namespace_level = 0 # number # If the body of the namespace is longer than this number, it won't be indented. # Requires indent_namespace=true. Default=0 (no limit) indent_namespace_limit = 3 # number # Whether the 'extern "C"' body is indented indent_extern = false # false/true # Whether the 'class' body is indented indent_class = true # false/true # Whether to indent the stuff after a leading class colon indent_class_colon = false # false/true # False=treat 'else\nif' as 'else if' for indenting purposes # True=indent the 'if' one level indent_else_if = false # false/true # Amount to indent variable declarations after a open brace. neg=relative, pos=absolute indent_var_def_blk = 0 # number # Indent continued variable declarations instead of aligning. indent_var_def_cont = true # false/true # True: indent continued function call parameters one indent level # False: align parameters under the open paren indent_func_call_param = false # false/true # Same as indent_func_call_param, but for function defs indent_func_def_param = false # false/true # Same as indent_func_call_param, but for function protos indent_func_proto_param = false # false/true # Same as indent_func_call_param, but for class declarations indent_func_class_param = false # false/true # Same as indent_func_call_param, but for class variable constructors indent_func_ctor_var_param = false # false/true # Same as indent_func_call_param, but for templates indent_template_param = false # false/true # Double the indent for indent_func_xxx_param options indent_func_param_double = false # false/true # Indentation column for standalone 'const' function decl/proto qualifier indent_func_const = 0 # number # Indentation column for standalone 'throw' function decl/proto qualifier indent_func_throw = 0 # number # The number of spaces to indent a continued '->' or '.' # Usually set to 0, 1, or indent_columns. indent_member = 0 # number # Spaces to indent single line ('//') comments on lines before code indent_sing_line_comments = 0 # number # If set, will indent trailing single line ('//') comments relative # to the code instead of trying to keep the same absolute column indent_relative_single_line_comments = false # false/true # Spaces to indent 'case' from 'switch' # Usually 0 or indent_columns. indent_switch_case = 2 # number # Spaces to shift the 'case' line, without affecting any other lines # Usually 0. indent_case_shift = 0 # number # Spaces to indent '{' from 'case'. # By default, the brace will appear under the 'c' in case. # Usually set to 0 or indent_columns. indent_case_brace = 0 # number # Whether to indent comments found in first column indent_col1_comment = false # false/true # How to indent goto labels # >0 : absolute column where 1 is the leftmost column # <=0 : subtract from brace indent indent_label = 1 # number # Same as indent_label, but for access specifiers that are followed by a colon indent_access_spec = 1 # number # Indent the code after an access specifier by one level. # If set, this option forces 'indent_access_spec=0' indent_access_spec_body = false # false/true # If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended) indent_paren_nl = false # false/true # Controls the indent of a close paren after a newline. # 0: Indent to body level # 1: Align under the open paren # 2: Indent to the brace level indent_paren_close = 0 # number # Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren indent_comma_paren = false # false/true # Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren indent_bool_paren = false # false/true # If 'indent_bool_paren' is true, controls the indent of the first expression. If TRUE, aligns the first expression to the following ones indent_first_bool_expr = false # false/true # If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended) indent_square_nl = false # false/true # Don't change the relative indent of ESQL/C 'EXEC SQL' bodies indent_preserve_sql = false # false/true # Align continued statements at the '='. Default=True # If FALSE or the '=' is followed by a newline, the next line is indent one tab. indent_align_assign = false # false/true # # Spacing options # # Add or remove space around arithmetic operator '+', '-', '/', '*', etc sp_arith = ignore # ignore/add/remove/force # Add or remove space around assignment operator '=', '+=', etc sp_assign = ignore # ignore/add/remove/force # Add or remove space around assignment operator '=' in a prototype sp_assign_default = ignore # ignore/add/remove/force # Add or remove space before assignment operator '=', '+=', etc. Overrides sp_assign. sp_before_assign = ignore # ignore/add/remove/force # Add or remove space after assignment operator '=', '+=', etc. Overrides sp_assign. sp_after_assign = ignore # ignore/add/remove/force # Add or remove space around assignment '=' in enum sp_enum_assign = ignore # ignore/add/remove/force # Add or remove space before assignment '=' in enum. Overrides sp_enum_assign. sp_enum_before_assign = ignore # ignore/add/remove/force # Add or remove space after assignment '=' in enum. Overrides sp_enum_assign. sp_enum_after_assign = ignore # ignore/add/remove/force # Add or remove space around preprocessor '##' concatenation operator. Default=Add sp_pp_concat = ignore # ignore/add/remove/force # Add or remove space after preprocessor '#' stringify operator. Default=Add sp_pp_stringify = ignore # ignore/add/remove/force # Add or remove space around boolean operators '&&' and '||' sp_bool = ignore # ignore/add/remove/force # Add or remove space around compare operator '<', '>', '==', etc sp_compare = ignore # ignore/add/remove/force # Add or remove space inside '(' and ')' sp_inside_paren = ignore # ignore/add/remove/force # Add or remove space between nested parens sp_paren_paren = add # ignore/add/remove/force # Whether to balance spaces inside nested parens sp_balance_nested_parens = false # false/true # Style Guide Section 3.7.4. # Add or remove space between ')' and '{' sp_paren_brace = add # ignore/add/remove/force # Add or remove space before pointer star '*' sp_before_ptr_star = ignore # ignore/add/remove/force # Add or remove space before pointer star '*' that isn't followed by a variable name # If set to 'ignore', sp_before_ptr_star is used instead. sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force # Add or remove space between pointer stars '*' sp_between_ptr_star = ignore # ignore/add/remove/force # Add or remove space after pointer star '*', if followed by a word. sp_after_ptr_star = ignore # ignore/add/remove/force # Add or remove space after a pointer star '*', if followed by a func proto/def. sp_after_ptr_star_func = ignore # ignore/add/remove/force # Add or remove space before a pointer star '*', if followed by a func proto/def. sp_before_ptr_star_func = ignore # ignore/add/remove/force # Add or remove space before a reference sign '&' sp_before_byref = ignore # ignore/add/remove/force # Add or remove space before a reference sign '&' that isn't followed by a variable name # If set to 'ignore', sp_before_byref is used instead. sp_before_unnamed_byref = ignore # ignore/add/remove/force # Add or remove space after reference sign '&', if followed by a word. sp_after_byref = ignore # ignore/add/remove/force # Add or remove space after a reference sign '&', if followed by a func proto/def. sp_after_byref_func = ignore # ignore/add/remove/force # Add or remove space before a reference sign '&', if followed by a func proto/def. sp_before_byref_func = ignore # ignore/add/remove/force # Add or remove space between type and word. Default=Force sp_after_type = add # ignore/add/remove/force # Add or remove space in 'template <' vs 'template<'. # If set to ignore, sp_before_angle is used. sp_template_angle = ignore # ignore/add/remove/force # Add or remove space before '<>' sp_before_angle = ignore # ignore/add/remove/force # Add or remove space inside '<' and '>' sp_inside_angle = ignore # ignore/add/remove/force # Add or remove space after '<>' sp_after_angle = ignore # ignore/add/remove/force # Add or remove space between '<>' and '(' as found in 'new List();' sp_angle_paren = ignore # ignore/add/remove/force # Add or remove space between '<>' and a word as in 'List m;' sp_angle_word = add # ignore/add/remove/force # Add or remove space before '(' of 'if', 'for', 'switch', and 'while' sp_before_sparen = ignore # ignore/add/remove/force # Add or remove space inside if-condition '(' and ')' sp_inside_sparen = ignore # ignore/add/remove/force # Add or remove space before if-condition ')'. Overrides sp_inside_sparen. sp_inside_sparen_close = ignore # ignore/add/remove/force # Add or remove space after ')' of 'if', 'for', 'switch', and 'while' sp_after_sparen = ignore # ignore/add/remove/force # Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while' sp_sparen_brace = ignore # ignore/add/remove/force # Add or remove space between 'invariant' and '(' in the D language. sp_invariant_paren = ignore # ignore/add/remove/force # Add or remove space after the ')' in 'invariant (C) c' in the D language. sp_after_invariant_paren = ignore # ignore/add/remove/force # Add or remove space before empty statement ';' on 'if', 'for' and 'while' sp_special_semi = ignore # ignore/add/remove/force # Add or remove space before ';'. Default=Remove sp_before_semi = ignore # ignore/ignore/remove/force # Add or remove space before ';' in non-empty 'for' statements sp_before_semi_for = ignore # ignore/add/remove/force # Add or remove space before a semicolon of an empty part of a for statement. sp_before_semi_for_empty = ignore # ignore/add/remove/force # Add or remove space after ';', except when followed by a comment. Default=Add sp_after_semi = ignore # ignore/add/remove/force # Add or remove space after ';' in non-empty 'for' statements. Default=Force sp_after_semi_for = ignore # ignore/add/remove/force # Add or remove space after the final semicolon of an empty part of a for statement: for ( ; ; ). sp_after_semi_for_empty = ignore # ignore/add/remove/force # Add or remove space before '[' (except '[]') sp_before_square = ignore # ignore/add/remove/force # Add or remove space before '[]' sp_before_squares = ignore # ignore/add/remove/force # Add or remove space inside '[' and ']' sp_inside_square = ignore # ignore/add/remove/force # Add or remove space after ',' sp_after_comma = ignore # ignore/add/remove/force # Add or remove space before ',' sp_before_comma = ignore # ignore/add/remove/force # Add or remove space before the variadic '...' when preceded by a non-punctuator sp_before_ellipsis = ignore # ignore/add/remove/force # Add or remove space after class ':' sp_after_class_colon = ignore # ignore/add/remove/force # Add or remove space before class ':' sp_before_class_colon = ignore # ignore/add/remove/force # Add or remove space before case ':'. Default=Remove sp_before_case_colon = remove # ignore/add/remove/force # Add or remove space between 'operator' and operator sign sp_after_operator = ignore # ignore/add/remove/force # Add or remove space between the operator symbol and the open paren, as in 'operator ++(' sp_after_operator_sym = ignore # ignore/add/remove/force # Add or remove space after C/D cast, i.e. 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a' sp_after_cast = ignore # ignore/add/remove/force # Add or remove spaces inside cast parens sp_inside_paren_cast = ignore # ignore/add/remove/force # Add or remove space between the type and open paren in a C++ cast, i.e. 'int(exp)' vs 'int (exp)' sp_cpp_cast_paren = ignore # ignore/add/remove/force # Add or remove space between 'sizeof' and '(' sp_sizeof_paren = ignore # ignore/add/remove/force # Add or remove space after the tag keyword (Pawn) sp_after_tag = ignore # ignore/add/remove/force # Add or remove space inside enum '{' and '}' sp_inside_braces_enum = ignore # ignore/add/remove/force # Add or remove space inside struct/union '{' and '}' sp_inside_braces_struct = ignore # ignore/add/remove/force # Add or remove space inside '{' and '}' sp_inside_braces = ignore # ignore/add/remove/force # Add or remove space inside '{}' sp_inside_braces_empty = ignore # ignore/add/remove/force # Add or remove space between return type and function name # A minimum of 1 is forced except for pointer return types. sp_type_func = add # ignore/add/remove/force # Style Guide Section 3.7.3. # Add or remove space between function name and '(' on function declaration sp_func_proto_paren = remove # ignore/add/remove/force # Style Guide Section 3.7.3. # Add or remove space between function name and '(' on function definition sp_func_def_paren = remove # ignore/add/remove/force # Style Guide Section 3.7.3. # Add or remove space inside empty function '()' sp_inside_fparens = remove # ignore/add/remove/force # Add or remove space inside function '(' and ')' sp_inside_fparen = ignore # ignore/add/remove/force # Add or remove space between ']' and '(' when part of a function call. sp_square_fparen = ignore # ignore/add/remove/force # Add or remove space between ')' and '{' of function sp_fparen_brace = ignore # ignore/add/remove/force # Add or remove space between function name and '(' on function calls sp_func_call_paren = ignore # ignore/add/remove/force # Add or remove space between the user function name and '(' on function calls # You need to set a keyword to be a user function, like this: 'set func_call_user _' in the config file. sp_func_call_user_paren = ignore # ignore/add/remove/force # Add or remove space between a constructor/destructor and the open paren sp_func_class_paren = ignore # ignore/add/remove/force # Add or remove space between 'return' and '(' sp_return_paren = ignore # ignore/add/remove/force # Add or remove space between '__attribute__' and '(' sp_attribute_paren = ignore # ignore/add/remove/force # Add or remove space between 'defined' and '(' in '#if defined (FOO)' sp_defined_paren = ignore # ignore/add/remove/force # Add or remove space between 'throw' and '(' in 'throw (something)' sp_throw_paren = ignore # ignore/add/remove/force # Add or remove space between macro and value sp_macro = ignore # ignore/add/remove/force # Add or remove space between macro function ')' and value sp_macro_func = ignore # ignore/add/remove/force # Style Guide Section 3.7.4. # Add or remove space between 'else' and '{' if on the same line sp_else_brace = add # ignore/add/remove/force # Style Guide Section 3.7.4. # Add or remove space between '}' and 'else' if on the same line sp_brace_else = add # ignore/add/remove/force # Add or remove space between '}' and the name of a typedef on the same line sp_brace_typedef = ignore # ignore/add/remove/force # Add or remove space between 'catch' and '{' if on the same line sp_catch_brace = ignore # ignore/add/remove/force # Add or remove space between '}' and 'catch' if on the same line sp_brace_catch = ignore # ignore/add/remove/force # Add or remove space between 'finally' and '{' if on the same line sp_finally_brace = ignore # ignore/add/remove/force # Add or remove space between '}' and 'finally' if on the same line sp_brace_finally = ignore # ignore/add/remove/force # Add or remove space between 'try' and '{' if on the same line sp_try_brace = ignore # ignore/add/remove/force # Add or remove space between get/set and '{' if on the same line sp_getset_brace = ignore # ignore/add/remove/force # Style Guide Section 3.7.3. # Add or remove space before the '::' operator sp_before_dc = remove # ignore/add/remove/force # Style Guide Section 3.7.3. # Add or remove space after the '::' operator sp_after_dc = remove # ignore/add/remove/force # Add or remove around the D named array initializer ':' operator sp_d_array_colon = ignore # ignore/add/remove/force # Add or remove space after the '!' (not) operator. Default=Remove sp_not = remove # ignore/add/remove/force # Add or remove space after the '~' (invert) operator. Default=Remove sp_inv = remove # ignore/add/remove/force # Add or remove space after the '&' (address-of) operator. Default=Remove # This does not affect the spacing after a '&' that is part of a type. sp_addr = remove # ignore/add/remove/force # Add or remove space around the '.' or '->' operators. Default=Remove sp_member = remove # ignore/add/remove/force # Add or remove space after the '*' (dereference) operator. Default=Remove # This does not affect the spacing after a '*' that is part of a type. sp_deref = remove # ignore/add/remove/force # Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. Default=Remove sp_sign = remove # ignore/add/remove/force # Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'. Default=Remove sp_incdec = remove # ignore/add/remove/force # Add or remove space before a backslash-newline at the end of a line. Default=Add sp_before_nl_cont = add # ignore/add/remove/force # Add or remove space after the scope '+' or '-', as in '-(void) foo;' or '+(int) bar;' sp_after_oc_scope = ignore # ignore/add/remove/force # Add or remove space after the colon in message specs # '-(int) f:(int) x;' vs '-(int) f: (int) x;' sp_after_oc_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in message specs # '-(int) f: (int) x;' vs '-(int) f : (int) x;' sp_before_oc_colon = ignore # ignore/add/remove/force # Add or remove space after the colon in message specs # '[object setValue:1];' vs '[object setValue: 1];' sp_after_send_oc_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in message specs # '[object setValue:1];' vs '[object setValue :1];' sp_before_send_oc_colon = ignore # ignore/add/remove/force # Add or remove space after the (type) in message specs # '-(int)f: (int) x;' vs '-(int)f: (int)x;' sp_after_oc_type = ignore # ignore/add/remove/force # Add or remove space after the first (type) in message specs # '-(int) f:(int)x;' vs '-(int)f:(int)x;' sp_after_oc_return_type = ignore # ignore/add/remove/force # Add or remove space between '@selector' and '(' # '@selector(msgName)' vs '@selector (msgName)' # Also applies to @protocol() constructs sp_after_oc_at_sel = ignore # ignore/add/remove/force # Add or remove space between '@selector(x)' and the following word # '@selector(foo) a:' vs '@selector(foo)a:' sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force # Add or remove space inside '@selector' parens # '@selector(foo)' vs '@selector( foo )' # Also applies to @protocol() constructs sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force # Add or remove space before a block pointer caret # '^int (int arg){...}' vs. ' ^int (int arg){...}' sp_before_oc_block_caret = ignore # ignore/add/remove/force # Add or remove space after a block pointer caret # '^int (int arg){...}' vs. '^ int (int arg){...}' sp_after_oc_block_caret = ignore # ignore/add/remove/force # Add or remove space around the ':' in 'b ? t : f' sp_cond_colon = ignore # ignore/add/remove/force # Add or remove space around the '?' in 'b ? t : f' sp_cond_question = ignore # ignore/add/remove/force # Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make sense here. sp_case_label = ignore # ignore/add/remove/force # Control the space around the D '..' operator. sp_range = ignore # ignore/add/remove/force # Control the space after the opening of a C++ comment '// A' vs '//A' sp_cmt_cpp_start = ignore # ignore/add/remove/force # Controls the spaces between #else or #endif and a trailing comment sp_endif_cmt = ignore # ignore/add/remove/force # # Code alignment (not left column spaces/tabs) # # Whether to keep non-indenting tabs align_keep_tabs = false # false/true # Whether to use tabs for aligning align_with_tabs = false # false/true # Whether to bump out to the next tab when aligning align_on_tabstop = false # false/true # Whether to left-align numbers align_number_left = false # false/true # Align variable definitions in prototypes and functions align_func_params = false # false/true # Align parameters in single-line functions that have the same name. # The function names must already be aligned with each other. align_same_func_call_params = false # false/true # The span for aligning variable definitions (0=don't align) align_var_def_span = 1 # number # How to align the star in variable definitions. # 0=Part of the type 'void * foo;' # 1=Part of the variable 'void *foo;' # 2=Dangling 'void *foo;' align_var_def_star_style = 0 # number # How to align the '&' in variable definitions. # 0=Part of the type # 1=Part of the variable # 2=Dangling align_var_def_amp_style = 0 # number # The threshold for aligning variable definitions (0=no limit) align_var_def_thresh = 0 # number # The gap for aligning variable definitions align_var_def_gap = 1 # number # Whether to align the colon in struct bit fields align_var_def_colon = false # false/true # Whether to align any attribute after the variable name align_var_def_attribute = false # false/true # Whether to align inline struct/enum/union variable definitions align_var_def_inline = false # false/true # The span for aligning on '=' in assignments (0=don't align) align_assign_span = 0 # number # The threshold for aligning on '=' in assignments (0=no limit) align_assign_thresh = 0 # number # The span for aligning on '=' in enums (0=don't align) align_enum_equ_span = 0 # number # The threshold for aligning on '=' in enums (0=no limit) align_enum_equ_thresh = 0 # number # The span for aligning struct/union (0=don't align) align_var_struct_span = 0 # number # The threshold for aligning struct/union member definitions (0=no limit) align_var_struct_thresh = 0 # number # The gap for aligning struct/union member definitions align_var_struct_gap = 0 # number # The span for aligning struct initializer values (0=don't align) align_struct_init_span = 0 # number # The minimum space between the type and the synonym of a typedef align_typedef_gap = 1 # number # The span for aligning single-line typedefs (0=don't align) align_typedef_span = 1 # number # How to align typedef'd functions with other typedefs # 0: Don't mix them at all # 1: align the open paren with the types # 2: align the function type name with the other type names align_typedef_func = 2 # number # Controls the positioning of the '*' in typedefs. Just try it. # 0: Align on typedef type, ignore '*' # 1: The '*' is part of type name: typedef int *pint; # 2: The '*' is part of the type, but dangling: typedef int *pint; align_typedef_star_style = 0 # number # Controls the positioning of the '&' in typedefs. Just try it. # 0: Align on typedef type, ignore '&' # 1: The '&' is part of type name: typedef int &pint; # 2: The '&' is part of the type, but dangling: typedef int &pint; align_typedef_amp_style = 0 # number # The span for aligning comments that end lines (0=don't align) align_right_cmt_span = 2 # number # If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment align_right_cmt_mix = false # false/true # If a trailing comment is more than this number of columns away from the text it follows, # it will qualify for being aligned. This has to be > 0 to do anything. align_right_cmt_gap = 0 # number # Align trailing comment at or beyond column N; 'pulls in' comments as a bonus side effect (0=ignore) align_right_cmt_at_col = 0 # number # The span for aligning function prototypes (0=don't align) align_func_proto_span = 0 # number # Minimum gap between the return type and the function name. align_func_proto_gap = 0 # number # Align function protos on the 'operator' keyword instead of what follows align_on_operator = false # false/true # Whether to mix aligning prototype and variable declarations. # If true, align_var_def_XXX options are used instead of align_func_proto_XXX options. align_mix_var_proto = false # false/true # Align single-line functions with function prototypes, uses align_func_proto_span align_single_line_func = false # false/true # Aligning the open brace of single-line functions. # Requires align_single_line_func=true, uses align_func_proto_span align_single_line_brace = false # false/true # Gap for align_single_line_brace. align_single_line_brace_gap = 1 # number # The span for aligning ObjC msg spec (0=don't align) align_oc_msg_spec_span = 0 # number # Whether to align macros wrapped with a backslash and a newline. # This will not work right if the macro contains a multi-line comment. align_nl_cont = false # false/true # The minimum space between label and value of a preprocessor define align_pp_define_gap = 0 # number # The span for aligning on '#define' bodies (0=don't align) align_pp_define_span = 0 # number # Align lines that start with '<<' with previous '<<'. Default=true align_left_shift = true # false/true # Span for aligning parameters in an Obj-C message call on the ':' (0=don't align) align_oc_msg_colon_span = 0 # number # Aligning parameters in an Obj-C '+' or '-' declaration on the ':' align_oc_decl_colon = false # false/true # # Newline adding and removing options # # Whether to collapse empty blocks between '{' and '}' nl_collapse_empty_body = false # false/true # Don't split one-line braced assignments - 'foo_t f = { 1, 2 };' nl_assign_leave_one_liners = false # false/true # Don't split one-line braced statements inside a class xx { } body nl_class_leave_one_liners = false # false/true # Don't split one-line enums: 'enum foo { BAR = 15 };' nl_enum_leave_one_liners = false # false/true # Don't split one-line get or set functions nl_getset_leave_one_liners = false # false/true # Don't split one-line function definitions - 'int foo() { return 0; }' nl_func_leave_one_liners = false # false/true # Don't split one-line if/else statements - 'if(a) b++;' nl_if_leave_one_liners = false # false/true # Add or remove newlines at the start of the file nl_start_of_file = remove # ignore/add/remove/force # The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force' nl_start_of_file_min = 0 # number # Add or remove newline at the end of the file nl_end_of_file = remove # ignore/add/remove/force # The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force') nl_end_of_file_min = 1 # number # Add or remove newline between '=' and '{' nl_assign_brace = ignore # ignore/add/remove/force # Add or remove newline between '=' and '[' (D only) nl_assign_square = ignore # ignore/add/remove/force # Add or remove newline after '= [' (D only). Will also affect the newline before the ']' nl_after_square_assign = ignore # ignore/add/remove/force # The number of blank lines after a block of variable definitions nl_func_var_def_blk = 1 # number # Add or remove newline between a function call's ')' and '{', as in: # list_for_each(item, &list) { } nl_fcall_brace = ignore # ignore/add/remove/force # Add or remove newline between 'enum' and '{' nl_enum_brace = ignore # ignore/add/remove/force # Add or remove newline between 'struct and '{' nl_struct_brace = ignore # ignore/add/remove/force # Add or remove newline between 'union' and '{' nl_union_brace = ignore # ignore/add/remove/force # Add or remove newline between 'if' and '{' nl_if_brace = ignore # ignore/add/remove/force # Add or remove newline between '}' and 'else' nl_brace_else = ignore # ignore/add/remove/force # Add or remove newline between 'else if' and '{' # If set to ignore, nl_if_brace is used instead nl_elseif_brace = ignore # ignore/add/remove/force # Add or remove newline between 'else' and '{' nl_else_brace = ignore # ignore/add/remove/force # Add or remove newline between 'else' and 'if' nl_else_if = ignore # ignore/add/remove/force # Add or remove newline between '}' and 'finally' nl_brace_finally = ignore # ignore/add/remove/force # Add or remove newline between 'finally' and '{' nl_finally_brace = ignore # ignore/add/remove/force # Add or remove newline between 'try' and '{' nl_try_brace = ignore # ignore/add/remove/force # Add or remove newline between get/set and '{' nl_getset_brace = ignore # ignore/add/remove/force # Add or remove newline between 'for' and '{' nl_for_brace = ignore # ignore/add/remove/force # Add or remove newline between 'catch' and '{' nl_catch_brace = ignore # ignore/add/remove/force # Add or remove newline between '}' and 'catch' nl_brace_catch = ignore # ignore/add/remove/force # Add or remove newline between 'while' and '{' nl_while_brace = ignore # ignore/add/remove/force # Add or remove newline between 'using' and '{' nl_using_brace = ignore # ignore/add/remove/force # Add or remove newline between two open or close braces. # Due to general newline/brace handling, REMOVE may not work. nl_brace_brace = ignore # ignore/add/remove/force # Add or remove newline between 'do' and '{' nl_do_brace = ignore # ignore/add/remove/force # Add or remove newline between '}' and 'while' of 'do' statement nl_brace_while = ignore # ignore/add/remove/force # Add or remove newline between 'switch' and '{' nl_switch_brace = ignore # ignore/add/remove/force # Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc. # Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch, and nl_catch_brace. nl_multi_line_cond = false # false/true # Force a newline in a define after the macro name for multi-line defines. nl_multi_line_define = false # false/true # Whether to put a newline before 'case' statement nl_before_case = false # false/true # Add or remove newline between ')' and 'throw' nl_before_throw = ignore # ignore/add/remove/force # Whether to put a newline after 'case' statement nl_after_case = false # false/true # Newline between namespace and { nl_namespace_brace = ignore # ignore/add/remove/force # Add or remove newline between 'template<>' and whatever follows. nl_template_class = ignore # ignore/add/remove/force # Add or remove newline between 'class' and '{' nl_class_brace = ignore # ignore/add/remove/force # Add or remove newline after each ',' in the constructor member initialization nl_class_init_args = ignore # ignore/add/remove/force # Add or remove newline between return type and function name in a function definition nl_func_type_name = ignore # ignore/add/remove/force # Add or remove newline between return type and function name inside a class {} # Uses nl_func_type_name or nl_func_proto_type_name if set to ignore. nl_func_type_name_class = ignore # ignore/add/remove/force # Add or remove newline between function scope and name in a definition # Controls the newline after '::' in 'void A::f() { }' nl_func_scope_name = ignore # ignore/add/remove/force # Add or remove newline between return type and function name in a prototype nl_func_proto_type_name = ignore # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' nl_func_paren = ignore # ignore/add/remove/force # Add or remove newline after '(' in a function declaration nl_func_decl_start = ignore # ignore/add/remove/force # Overrides nl_func_decl_start when there is only one paramter. nl_func_decl_start_single = ignore # ignore/add/remove/force # Add or remove newline after each ',' in a function declaration nl_func_decl_args = ignore # ignore/add/remove/force # Add or remove newline before the ')' in a function declaration nl_func_decl_end = ignore # ignore/add/remove/force # Overrides nl_func_decl_end when there is only one paramter. nl_func_decl_end_single = ignore # ignore/add/remove/force # Add or remove newline between '()' in a function declaration. nl_func_decl_empty = ignore # ignore/add/remove/force # Add or remove newline between function signature and '{' nl_fdef_brace = ignore # ignore/add/remove/force # Whether to put a newline after 'return' statement nl_after_return = false # false/true # Add or remove a newline between the return keyword and return expression. nl_return_expr = ignore # ignore/add/remove/force # Whether to put a newline after semicolons, except in 'for' statements nl_after_semicolon = false # false/true # Whether to put a newline after brace open. # This also adds a newline before the matching brace close. nl_after_brace_open = false # false/true # If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is # placed between the open brace and a trailing single-line comment. nl_after_brace_open_cmt = false # false/true # Whether to put a newline after a virtual brace open with a non-empty body. # These occur in un-braced if/while/do/for statement bodies. nl_after_vbrace_open = false # false/true # Whether to put a newline after a virtual brace open with an empty body. # These occur in un-braced if/while/do/for statement bodies. nl_after_vbrace_open_empty = false # false/true # Whether to put a newline after a brace close. # Does not apply if followed by a necessary ';'. nl_after_brace_close = false # false/true # Whether to put a newline after a virtual brace close. # Would add a newline before return in: 'if (foo) a++; return;' nl_after_vbrace_close = false # false/true # Whether to alter newlines in '#define' macros nl_define_macro = false # false/true # Whether to not put blanks after '#ifxx', '#elxx', or before '#endif' nl_squeeze_ifdef = false # false/true # Add or remove blank line before 'if' nl_before_if = ignore # ignore/add/remove/force # Add or remove blank line after 'if' statement nl_after_if = ignore # ignore/add/remove/force # Add or remove blank line before 'for' nl_before_for = ignore # ignore/add/remove/force # Add or remove blank line after 'for' statement nl_after_for = ignore # ignore/add/remove/force # Add or remove blank line before 'while' nl_before_while = ignore # ignore/add/remove/force # Add or remove blank line after 'while' statement nl_after_while = ignore # ignore/add/remove/force # Add or remove blank line before 'switch' nl_before_switch = ignore # ignore/add/remove/force # Add or remove blank line after 'switch' statement nl_after_switch = ignore # ignore/add/remove/force # Add or remove blank line before 'do' nl_before_do = ignore # ignore/add/remove/force # Add or remove blank line after 'do/while' statement nl_after_do = ignore # ignore/add/remove/force # Whether to double-space commented-entries in struct/enum nl_ds_struct_enum_cmt = false # false/true # Whether to double-space before the close brace of a struct/union/enum # (lower priority than 'eat_blanks_before_close_brace') nl_ds_struct_enum_close_brace = false # false/true # Add or remove a newline around a class colon. # Related to pos_class_colon, nl_class_init_args, and pos_comma. nl_class_colon = ignore # ignore/add/remove/force # Change simple unbraced if statements into a one-liner # 'if(b)\n i++;' => 'if(b) i++;' nl_create_if_one_liner = false # false/true # Change simple unbraced for statements into a one-liner # 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);' nl_create_for_one_liner = false # false/true # Change simple unbraced while statements into a one-liner # 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);' nl_create_while_one_liner = false # false/true # # Positioning options # # The position of arithmetic operators in wrapped expressions pos_arith = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of assignment in wrapped expressions. # Do not affect '=' followed by '{' pos_assign = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of boolean operators in wrapped expressions pos_bool = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of comparison operators in wrapped expressions pos_compare = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of conditional (b ? t : f) operators in wrapped expressions pos_conditional = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of the comma in wrapped expressions pos_comma = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of the comma in the constructor initialization list pos_class_comma = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of colons between constructor and member initialization pos_class_colon = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # # Line Splitting options # # Try to limit code width to N number of columns code_width = 120 # number # Whether to fully split long 'for' statements at semi-colons ls_for_split_full = false # false/true # Whether to fully split long function protos/calls at commas ls_func_split_full = false # false/true # # Blank line options # # The maximum consecutive newlines nl_max = 2 # number # The number of newlines after a function prototype, if followed by another function prototype nl_after_func_proto = 2 # number # The number of newlines after a function prototype, if not followed by another function prototype nl_after_func_proto_group = 1 # number # The number of newlines after '}' of a multi-line function body nl_after_func_body = 2 # number # The number of newlines after '}' of a single line function body nl_after_func_body_one_liner = 0 # number # The minimum number of newlines before a multi-line comment. # Doesn't apply if after a brace open or another multi-line comment. nl_before_block_comment = 0 # number # The minimum number of newlines before a single-line C comment. # Doesn't apply if after a brace open or other single-line C comments. nl_before_c_comment = 0 # number # The minimum number of newlines before a CPP comment. # Doesn't apply if after a brace open or other CPP comments. nl_before_cpp_comment = 0 # number # Whether to force a newline after a multi-line comment. nl_after_multiline_comment = false # false/true # The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # Will not change the newline count if after a brace open. # 0 = No change. nl_before_access_spec = 1 # number # The number of newlines after a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # 0 = No change. nl_after_access_spec = 0 # number # The number of newlines between a function def and the function comment. # 0 = No change. nl_comment_func_def = 0 # number # The number of newlines after a try-catch-finally block that isn't followed by a brace close. # 0 = No change. nl_after_try_catch_finally = 0 # number # The number of newlines before and after a property, indexer or event decl. # 0 = No change. nl_around_cs_property = 0 # number # The number of newlines between the get/set/add/remove handlers in C#. # 0 = No change. nl_between_get_set = 0 # number # Whether to remove blank lines after '{' eat_blanks_after_open_brace = false # false/true # Whether to remove blank lines before '}' eat_blanks_before_close_brace = false # false/true # # Code modifying options (non-whitespace) # # Add or remove braces on single-line 'do' statement mod_full_brace_do = ignore # ignore/add/remove/force # Add or remove braces on single-line 'for' statement mod_full_brace_for = ignore # ignore/add/remove/force # Add or remove braces on single-line function definitions. (Pawn) mod_full_brace_function = ignore # ignore/add/remove/force # Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'. mod_full_brace_if = ignore # ignore/add/remove/force # Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if. # If any must be braced, they are all braced. If all can be unbraced, then the braces are removed. mod_full_brace_if_chain = false # false/true # Don't remove braces around statements that span N newlines mod_full_brace_nl = 0 # number # Add or remove braces on single-line 'while' statement mod_full_brace_while = ignore # ignore/add/remove/force # Add or remove braces on single-line 'using ()' statement mod_full_brace_using = ignore # ignore/add/remove/force # Add or remove unnecessary paren on 'return' statement mod_paren_on_return = ignore # ignore/add/remove/force # Whether to change optional semicolons to real semicolons mod_pawn_semicolon = false # false/true # Add parens on 'while' and 'if' statement around bools mod_full_paren_if_bool = false # false/true # Whether to remove superfluous semicolons mod_remove_extra_semicolon = false # false/true # If a function body exceeds the specified number of newlines and doesn't have a comment after # the close brace, a comment will be added. mod_add_long_function_closebrace_comment = 0 # number # If a switch body exceeds the specified number of newlines and doesn't have a comment after # the close brace, a comment will be added. mod_add_long_switch_closebrace_comment = 0 # number # If an #ifdef body exceeds the specified number of newlines and doesn't have a comment after # the #else, a comment will be added. mod_add_long_ifdef_endif_comment = 0 # number # If an #ifdef or #else body exceeds the specified number of newlines and doesn't have a comment after # the #endif, a comment will be added. mod_add_long_ifdef_else_comment = 0 # number # If TRUE, will sort consecutive single-line 'import' statements [Java, D] mod_sort_import = false # false/true # If TRUE, will sort consecutive single-line 'using' statements [C#] mod_sort_using = false # false/true # If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C] # This is generally a bad idea, as it may break your code. mod_sort_include = false # false/true # If TRUE, it will move a 'break' that appears after a fully braced 'case' before the close brace. mod_move_case_break = false # false/true # Will add or remove the braces around a fully braced case statement. # Will only remove the braces if there are no variable declarations in the block. mod_case_brace = ignore # ignore/add/remove/force # If TRUE, it will remove a void 'return;' that appears as the last statement in a function. mod_remove_empty_return = false # false/true # # Comment modifications # # Try to wrap comments at cmt_width columns cmt_width = 80 # number # Set the comment reflow mode (default: 0) # 0: no reflowing (apart from the line wrapping due to cmt_width) # 1: no touching at all # 2: full reflow cmt_reflow_mode = 0 # number # If false, disable all multi-line comment changes, including cmt_width. keyword substitution, and leading chars. # Default is true. cmt_indent_multi = false # false/true # Whether to group c-comments that look like they are in a block cmt_c_group = false # false/true # Whether to put an empty '/*' on the first line of the combined c-comment cmt_c_nl_start = false # false/true # Whether to put a newline before the closing '*/' of the combined c-comment cmt_c_nl_end = false # false/true # Whether to group cpp-comments that look like they are in a block cmt_cpp_group = false # false/true # Whether to put an empty '/*' on the first line of the combined cpp-comment cmt_cpp_nl_start = false # false/true # Whether to put a newline before the closing '*/' of the combined cpp-comment cmt_cpp_nl_end = false # false/true # Whether to change cpp-comments into c-comments cmt_cpp_to_c = false # false/true # Whether to put a star on subsequent comment lines cmt_star_cont = false # false/true # The number of spaces to insert at the start of subsequent comment lines cmt_sp_before_star_cont = 0 # number # The number of spaces to insert after the star on subsequent comment lines cmt_sp_after_star_cont = 0 # number # For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of # the comment are the same length. Default=True cmt_multi_check_last = false # false/true # The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment. # Will substitute $(filename) with the current file's name. cmt_insert_file_header = "" # string # The filename that contains text to insert at the end of a file if the file doesn't end with a C/C++ comment. # Will substitute $(filename) with the current file's name. cmt_insert_file_footer = "" # string # The filename that contains text to insert before a function implementation if the function isn't preceded with a C/C++ comment. # Will substitute $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff. # Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... } cmt_insert_func_header = "" # string # The filename that contains text to insert before a class if the class isn't preceded with a C/C++ comment. # Will substitute $(class) with the class name. cmt_insert_class_header = "" # string # If a preprocessor is encountered when stepping backwards from a function name, then # this option decides whether the comment should be inserted. # Affects cmt_insert_func_header and cmt_insert_class_header. cmt_insert_before_preproc = false # false/true # # Preprocessor options # # Control indent of preprocessors inside #if blocks at brace level 0 pp_indent = add # ignore/add/remove/force # Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false) pp_indent_at_level = false # false/true # If pp_indent_at_level=false, specifies the number of columns to indent per level. Default=1. pp_indent_count = 0 # number # Add or remove space after # based on pp_level of #if blocks pp_space = ignore # ignore/add/remove/force # Sets the number of spaces added with pp_space pp_space_count = 0 # number # The indent for #region and #endregion in C# and '#pragma region' in C/C++ pp_indent_region = 0 # number # Whether to indent the code between #region and #endregion pp_region_indent_code = false # false/true # If pp_indent_at_level=true, sets the indent for #if, #else, and #endif when not at file-level pp_indent_if = 2 # number # Control whether to indent the code between #if, #else and #endif when not at file-level pp_if_indent_code = false # false/true # Whether to indent '#define' at the brace level (true) or from column 1 (false) pp_define_at_level = false # false/true # You can force a token to be a type with the 'type' option. # Example: # type myfoo1 myfoo2 # # You can create custom macro-based indentation using macro-open, # macro-else and macro-close. # Example: # macro-open BEGIN_TEMPLATE_MESSAGE_MAP # macro-open BEGIN_MESSAGE_MAP # macro-close END_MESSAGE_MAP # # You can assign any keyword to any type with the set option. # set func_call_user _ N_ # # The full syntax description of all custom definition config entries # is shown below: # # define custom tokens as: # - embed whitespace in token using '' escape character, or # put token in quotes # - these: ' " and ` are recognized as quote delimiters # # type token1 token2 token3 ... # ^ optionally specify multiple tokens on a single line # define def_token output_token # ^ output_token is optional, then NULL is assumed # macro-open token # macro-close token # macro-else token # set id token1 token2 ... # ^ optionally specify multiple tokens on a single line # ^ id is one of the names in token_enum.h sans the CT_ prefix, # e.g. PP_PRAGMA # # all tokens are separated by any mix of ',' commas, '=' equal signs # and whitespace (space, tab) # GoFigure2-v0.9.0/KWStyle/doAllStyle.csh.in0000644000175000017500000000216011667757442020115 0ustar mathieumathieu#! /bin/tcsh -f # # Usage: @GOFIGURE2@/doAllStyle.csh # Run KWStyle on all files in a directory. # Creates a subdirectory kwstyle. This subdirectory has a # file called 'all' that contains a list of files that show # the style defects for files in the directory. For each file # that has style defects, there is a corresponding file in # kwstyle with a suffix .txt that contains a description of # the defects. rm -rf kwstyle mkdir kwstyle unalias -a set files=`ls -1 *.h *.txx *.cxx` rm -f defects.txt foreach file ( $files ) ##@KWSTYLE_EXECUTABLE@ -v -gcc -xml @GOFIGURE2_BINARY_DIR@/GOFIGURE2.kws.xml -o @ITK_SOURCE_DIR@/Utilities/KWStyle/ITKOverwrite.txt $file >kwstyle/$file.txt @KWSTYLE_EXECUTABLE@ -v -gcc -xml @GOFIGURE2_BINARY_DIR@/GOFIGURE2.kws.xml $file >kwstyle/$file.txt cat kwstyle/$file.txt >> defects.txt echo -n . end echo . cd kwstyle rm -f defectiveFiles set files=`ls -1 *.txt` foreach file ( $files ) set n=`grep " error: " $file | wc -l` if ( $n > 0 ) then echo `basename $file .txt` has $n style defects echo $file >>defectiveFiles endif end cd .. pwd GoFigure2-v0.9.0/KWStyle/Header.h0000644000175000017500000000341611667757442016303 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ GoFigure2-v0.9.0/GOFIGURE2CPack.cmake0000644000175000017500000000675211667757442016603 0ustar mathieumathieu# setup CPack INCLUDE( ${GOFIGURE2_SOURCE_DIR}/CMake/InstallSupportLibraries.cmake ) CONFIGURE_FILE( "${GOFIGURE2_SOURCE_DIR}/GOFIGURE2CPackOptions.cmake.in" "${GOFIGURE2_BINARY_DIR}/GOFIGURE2CPackOptions.cmake" @ONLY ) SET( CPACK_PROJECT_CONFIG_FILE "${GOFIGURE2_BINARY_DIR}/GOFIGURE2CPackOptions.cmake" ) SET( CPACK_PACKAGE_DESCRIPTION_SUMMARY "GoFigure2 is a cross-platform application for microscope image visualization and analysis" ) SET( CPACK_PACKAGE_VENDOR "Megason Lab, Systems Biology, HMS" ) SET( CPACK_PACKAGE_CONTACT "gofigure2-developers@lists.sourceforge.net" ) SET( CPACK_PACKAGE_DESCRIPTION_FILE "${GOFIGURE2_SOURCE_DIR}/ReadMe.rst") SET( CPACK_RESOURCE_FILE_LICENSE "${GOFIGURE2_SOURCE_DIR}/Licenses/Copyright.txt") SET( CPACK_RESOURCE_FILE_WELCOME "${GOFIGURE2_SOURCE_DIR}/CPack.GenericWelcome.txt" ) SET( CPACK_PACKAGE_VERSION_MAJOR ${GOFIGURE2_MAJOR_VERSION} ) SET( CPACK_PACKAGE_VERSION_MINOR ${GOFIGURE2_MINOR_VERSION} ) SET( CPACK_PACKAGE_VERSION_PATCH ${GOFIGURE2_WC_REVISION} ) SET( CPACK_PACKAGE_INSTALL_DIRECTORY "GoFigure2" ) SET( CPACK_SOURCE_PACKAGE_FILE_NAME "GoFigure2-${GOFIGURE2_VERSION}" ) # taken from CMake IF( NOT DEFINED CPACK_SYSTEM_NAME ) # make sure package is not Cygwin-unknown, for Cygwin just # cygwin is good for the system name IF("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN") SET( CPACK_SYSTEM_NAME Cygwin ) ELSE("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN") IF( CMAKE_SYSTEM_PROCESSOR MATCHES "unknown" ) EXEC_PROGRAM( uname ARGS "-m" OUTPUT_VARIABLE CMAKE_SYSTEM_PROCESSOR ) ENDIF( CMAKE_SYSTEM_PROCESSOR MATCHES "unknown" ) SET( CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR} ) ENDIF("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN") ENDIF( NOT DEFINED CPACK_SYSTEM_NAME ) #set up the package name on mac IF( ${CPACK_SYSTEM_NAME} MATCHES Darwin ) #use uname -m instead of uname -p #EXECUTE_PROCESS( COMMAND uname -m # OUTPUT_VARIABLE PLATFORM) #remove end of line character #STRING(REGEX REPLACE "/n" "" PLATFORM2 ${PLATFORM}) #set the system name IF( CMAKE_OSX_ARCHITECTURES ) SET( CPACK_SYSTEM_NAME Darwin-${CMAKE_OSX_ARCHITECTURES} ) ENDIF( CMAKE_OSX_ARCHITECTURES ) ENDIF( ${CPACK_SYSTEM_NAME} MATCHES Darwin ) #set up the package name on windows IF( ${CPACK_SYSTEM_NAME} MATCHES Windows ) IF( CMAKE_CL_64 ) SET( CPACK_SYSTEM_NAME win64-${CMAKE_SYSTEM_PROCESSOR} ) ELSE( CMAKE_CL_64 ) SET( CPACK_SYSTEM_NAME win32-${CMAKE_SYSTEM_PROCESSOR} ) ENDIF( CMAKE_CL_64 ) ENDIF( ${CPACK_SYSTEM_NAME} MATCHES Windows ) IF( NOT DEFINED CPACK_PACKAGE_FILE_NAME ) # if the CPACK_PACKAGE_FILE_NAME is not defined by the cache # default to source package - system, on cygwin system is not # needed IF( CYGWIN ) SET( CPACK_PACKAGE_FILE_NAME "${CPACK_SOURCE_PACKAGE_FILE_NAME}" ) ELSE( CYGWIN ) SET( CPACK_PACKAGE_FILE_NAME "${CPACK_SOURCE_PACKAGE_FILE_NAME}-${CPACK_SYSTEM_NAME}" ) ENDIF( CYGWIN ) ENDIF( NOT DEFINED CPACK_PACKAGE_FILE_NAME ) IF( WIN32 AND NOT UNIX ) INCLUDE( ${CPACK_PROJECT_CONFIG_FILE} ) ELSE( WIN32 AND NOT UNIX ) SET( CPACK_STRIP_FILES "bin/gofigure" ) SET( CPACK_SOURCE_STRIP_FILES "" ) ENDIF( WIN32 AND NOT UNIX ) SET( CPACK_PACKAGE_EXECUTABLES "gofigure" "GoFigure2" ) # # # # cygwin specific packaging stuff # # IF(CYGWIN) # # ENDIF( CYGWIN ) IF( WIN32 ) INSTALL( PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION bin COMPONENT Runtime ) ENDIF( WIN32 ) SET( CPACK_COMPONENTS_ALL Runtime Libraries # headers ) INCLUDE( CPack ) GoFigure2-v0.9.0/CPack.GenericWelcome.txt0000644000175000017500000000014011667757442020000 0ustar mathieumathieuWelcome to installation. This program will guide you through the installation of this software. GoFigure2-v0.9.0/GoFigure2IncludeDirectories.cmake0000644000175000017500000000314111667757442021667 0ustar mathieumathieuset( GOFIGURE2_INCLUDE_DIRS_SOURCE_TREE ${GOFIGURE2_SOURCE_DIR} ${GOFIGURE2_SOURCE_DIR}/Code/ ${GOFIGURE2_SOURCE_DIR}/Code/IO/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/ ${GOFIGURE2_SOURCE_DIR}/Code/Filters/ ${GOFIGURE2_SOURCE_DIR}/Main/ ) set( GOFIGURE2_INCLUDE_DIRS_MEGAVTK_SOURCE_TREE ${MEGAVTK2_SOURCE_DIR}/vtkItk ${MEGAVTK2_SOURCE_DIR}/vtkRenderingAddOn ${MEGAVTK2_SOURCE_DIR} ) set( GOFIGURE2_INCLUDE_DIRS_EXTERNAL_SOURCE_TREE ${GOFIGURE2_EXTERNAL_SOURCE_DIR} ${GOFIGURE2_EXTERNAL_SOURCE_DIR}/vtkLSM ${GOFIGURE2_EXTERNAL_SOURCE_DIR}/itkQt ${GOFIGURE2_EXTERNAL_SOURCE_DIR}/PoissonReconstruction ${GOFIGURE2_EXTERNAL_SOURCE_DIR}/ctk ) set( GOFIGURE2_INCLUDE_DIRS_BINARY_TRE ${GOFIGURE2_BINARY_DIR} ${GOFIGURE2_BINARY_DIR}/Code/ ${GOFIGURE2_BINARY_DIR}/Code/IO/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/ ${GOFIGURE2_BINARY_DIR}/Code/Filters/ ${GOFIGURE2_BINARY_DIR}/Main/ ) set( GOFIGURE2_INCLUDE_DIRS_MEGAVTK_BINARY_TREE ${MEGAVTK2_BINARY_DIR}/vtkItk ${MEGAVTK2_BINARY_DIR}/vtkRenderingAddOn ${MEGAVTK2_BINARY_DIR} ) set( GOFIGURE2_INCLUDE_DIRS_EXTERNAL_BINARY_TREE ${GOFIGURE2_EXTERNAL_BINARY_DIR} ${GOFIGURE2_EXTERNAL_BINARY_DIR}/vtkLSM ${GOFIGURE2_EXTERNAL_BINARY_DIR}/itkQt ${GOFIGURE2_EXTERNAL_BINARY_DIR}/PoissonReconstruction ${GOFIGURE2_EXTERNAL_BINARY_DIR}/ctk ) set( GOFIGURE2_INCLUDE_DIRS ${GOFIGURE2_INCLUDE_DIRS_SOURCE_TREE} ${GOFIGURE2_INCLUDE_DIRS_MEGAVTK_SOURCE_TREE} ${GOFIGURE2_INCLUDE_DIRS_EXTERNAL_SOURCE_TREE} ${GOFIGURE2_INCLUDE_DIRS_BINARY_TREE} ${GOFIGURE2_INCLUDE_DIRS_MEGAVTK_BINARY_TREE} ${GOFIGURE2_INCLUDE_DIRS_EXTERNAL_BINARY_TREE} ) GoFigure2-v0.9.0/Code/0000755000175000017500000000000011667757442014246 5ustar mathieumathieuGoFigure2-v0.9.0/Code/IO/0000755000175000017500000000000011667757442014555 5ustar mathieumathieuGoFigure2-v0.9.0/Code/IO/GoFigureFileInfoMultiIndexContainerHelper.cxx0000644000175000017500000001650511667757442025441 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoFigureFileInfoMultiIndexContainerHelper.h" // method to speed up the display std::map< unsigned int, std::list< std::string > > GetAllFileNamesForGivenTCoord( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const unsigned int & iT, const unsigned int & iMinCh, const unsigned int & iMaxCh ) { std::map< unsigned int, std::list< std::string > > oList; using boost::multi_index::index; using boost::multi_index::get; using boost::tuples::tie; index< GoFigureFileInfoHelperMultiIndexContainer, m_TCoord >::type::iterator it0, it1; tie(it0, it1) = get< m_TCoord >(iContainer).equal_range(iT); GoFigureFileInfoHelperChannelViewContainer subset; while ( it0 != it1 ) { subset.insert(&*it0); ++it0; } GoFigureFileInfoHelperChannelViewContainer::nth_index< 0 >::type::iterator ic0, ic1; ic0 = subset.get< 0 >().lower_bound(iMinCh); ic1 = subset.get< 0 >().upper_bound(iMaxCh); GoFigureFileInfoHelperZCoordViewContainer final_container; while ( ic0 != ic1 ) { final_container.insert(*ic0); ++ic0; } GoFigureFileInfoHelperZCoordViewContainer::iterator z_it0 = final_container.begin(); GoFigureFileInfoHelperZCoordViewContainer::iterator z_it1 = final_container.end(); while ( z_it0 != z_it1 ) { oList[( *z_it0 )->m_Channel].push_back( ( *z_it0 )->m_Filename ); ++z_it0; } return oList; } std::map< unsigned int, std::list< std::string > > GetAllFileNamesForGivenZCoord( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const unsigned int & iZ, const unsigned int & iMinCh, const unsigned int & iMaxCh ) { std::map< unsigned int, std::list< std::string > > oList; using boost::multi_index::index; using boost::multi_index::get; using boost::tuples::tie; index< GoFigureFileInfoHelperMultiIndexContainer, m_ZCoord >::type::iterator it0, it1; tie(it0, it1) = get< m_ZCoord >(iContainer).equal_range(iZ); GoFigureFileInfoHelperChannelViewContainer subset; while ( it0 != it1 ) { subset.insert(&*it0); ++it0; } GoFigureFileInfoHelperChannelViewContainer::nth_index< 0 >::type::iterator ic0, ic1; ic0 = subset.get< 0 >().lower_bound(iMinCh); ic1 = subset.get< 0 >().upper_bound(iMaxCh); GoFigureFileInfoHelperTCoordViewContainer final_container; while ( ic0 != ic1 ) { final_container.insert(*ic0); ++ic0; } GoFigureFileInfoHelperTCoordViewContainer::iterator z_it0 = final_container.begin(); GoFigureFileInfoHelperTCoordViewContainer::iterator z_it1 = final_container.end(); while ( z_it0 != z_it1 ) { oList[( *z_it0 )->m_Channel].push_back( ( *z_it0 )->m_Filename ); ++z_it0; } return oList; } std::list< std::string > GetAllFileNamesForGivenTCoordAndChannel( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const unsigned int & iT, const unsigned int & iCh) { std::list< std::string > oList; using boost::multi_index::index; using boost::multi_index::get; using boost::tuples::tie; index< GoFigureFileInfoHelperMultiIndexContainer, m_TCoord >::type::iterator it0, it1; tie(it0, it1) = get< m_TCoord >(iContainer).equal_range(iT); GoFigureFileInfoHelperChannelViewContainer subset; while ( it0 != it1 ) { subset.insert(&*it0); ++it0; } GoFigureFileInfoHelperChannelViewContainer::nth_index< 0 >::type::iterator ic0, ic1; ic0 = subset.get< 0 >().lower_bound(iCh); ic1 = subset.get< 0 >().upper_bound(iCh); GoFigureFileInfoHelperZCoordViewContainer final_container; while ( ic0 != ic1 ) { final_container.insert(*ic0); ++ic0; } GoFigureFileInfoHelperZCoordViewContainer::iterator z_it0 = final_container.begin(); GoFigureFileInfoHelperZCoordViewContainer::iterator z_it1 = final_container.end(); while ( z_it0 != z_it1 ) { oList.push_back( ( *z_it0 )->m_Filename ); ++z_it0; } return oList; } std::list< std::string > GetAllFileNamesForGivenZCoordPointAndChannel( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const unsigned int & iZ, const unsigned int & iCh) { std::list< std::string > oList; using boost::multi_index::index; using boost::multi_index::get; using boost::tuples::tie; index< GoFigureFileInfoHelperMultiIndexContainer, m_ZCoord >::type::iterator it0, it1; tie(it0, it1) = get< m_ZCoord >(iContainer).equal_range(iZ); GoFigureFileInfoHelperChannelViewContainer subset; while ( it0 != it1 ) { subset.insert(&*it0); ++it0; } GoFigureFileInfoHelperChannelViewContainer::nth_index< 0 >::type::iterator ic0, ic1; ic0 = subset.get< 0 >().lower_bound(iCh); ic1 = subset.get< 0 >().upper_bound(iCh); GoFigureFileInfoHelperTCoordViewContainer final_container; while ( ic0 != ic1 ) { final_container.insert(*ic0); ++ic0; } GoFigureFileInfoHelperTCoordViewContainer::iterator z_it0 = final_container.begin(); GoFigureFileInfoHelperTCoordViewContainer::iterator z_it1 = final_container.end(); while ( z_it0 != z_it1 ) { oList.push_back( ( *z_it0 )->m_Filename ); ++z_it0; } return oList; } std::map< unsigned int, std::list< std::string > > GetAllFileNamesForGivenChannelAndTCoords( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const unsigned int & iCh, const std::set< unsigned int > & iTCoordList ) { std::map< unsigned int, std::list< std::string > > oList; std::set< unsigned int >::const_iterator t_it = iTCoordList.begin(); while ( t_it != iTCoordList.end() ) { oList[*t_it] = GetAllFileNamesForGivenTCoordAndChannel(iContainer, *t_it, iCh); ++t_it; } return oList; }GoFigure2-v0.9.0/Code/IO/QueryDataBaseHelper.cxx0000644000175000017500000003515411667757442021143 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QueryDataBaseHelper.h" #include "vtkMySQLDatabase.h" #include "vtkSQLQuery.h" #include "vtkStdString.h" #include "vtkVariant.h" #include "QueryBuilderHelper.h" #include #include //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::pair< bool, vtkMySQLDatabase * > ConnectToServer(std::string ServerName, std::string login, std::string Password) { std::pair< bool, vtkMySQLDatabase * > ConnectionServer; vtkMySQLDatabase * ServerConnector = vtkMySQLDatabase::New(); ServerConnector->SetHostName( ServerName.c_str() ); ServerConnector->SetUser( login.c_str() ); ServerConnector->SetPassword( Password.c_str() ); if ( !ServerConnector->Open() ) { std::cout << "Could not connect to the server." << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; ConnectionServer.first = false; return ConnectionServer; } ConnectionServer.first = true; ConnectionServer.second = ServerConnector; return ConnectionServer; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::pair< bool, vtkMySQLDatabase * > ConnectToDatabase(std::string ServerName, std::string login, std::string Password, std::string DBName) { std::pair< bool, vtkMySQLDatabase * > ConnectionDatabase(false, (vtkMySQLDatabase *)0); vtkMySQLDatabase * DatabaseConnector = vtkMySQLDatabase::New(); DatabaseConnector->SetHostName( ServerName.c_str() ); DatabaseConnector->SetUser( login.c_str() ); DatabaseConnector->SetPassword( Password.c_str() ); DatabaseConnector->SetDatabaseName( DBName.c_str() ); if ( !DatabaseConnector->Open() ) { itkGenericExceptionMacro( << "Could not open database." << "DB will not be created."); std::cout << "Could not connect to the database." << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return ConnectionDatabase; } ConnectionDatabase.first = true; ConnectionDatabase.second = DatabaseConnector; return ConnectionDatabase; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ vtkMySQLDatabase * OpenDatabaseConnection( std::string ServerName, std::string login, std::string Password, std::string DBName) { std::pair< bool, vtkMySQLDatabase * > ConnectionDatabase = ConnectToDatabase( ServerName, login, Password, DBName); if ( !ConnectionDatabase.first ) { std::cout << "No connection open for QGoOpenOrCreateImgSession" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } return ConnectionDatabase.second; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool CloseDatabaseConnection( vtkMySQLDatabase *DatabaseConnector) { if ( DatabaseConnector != NULL ) { DatabaseConnector->Close(); DatabaseConnector->Delete(); return true; } return false; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void ExecuteQuery(vtkMySQLDatabase *iDatabaseConnector, std::string iQuery) { vtkSQLQuery *query = iDatabaseConnector->GetQueryInstance(); query->SetQuery( iQuery.c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "Execute query failed" << query->GetLastErrorText() ); iDatabaseConnector->Close(); iDatabaseConnector->Delete(); } query->Delete(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > ListDatabases(vtkMySQLDatabase *ServerConnector) { std::vector< std::string > result; vtkSQLQuery * query = ServerConnector->GetQueryInstance(); query->SetQuery("Show Databases;"); if ( !query->Execute() ) { itkGenericExceptionMacro( << "Show Databases query failed." << query->GetLastErrorText() ); query->Delete(); return result; } // all set, proceed // iterate over lines, we know there is only one column // and as many rows as there is databases while ( query->NextRow() ) { result.push_back( query->DataValue(0).ToString() ); } query->Delete(); return result; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > ListTables(vtkMySQLDatabase *DatabaseConnector) { std::vector< std::string > result; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); query->SetQuery("Show tables;"); if ( !query->Execute() ) { itkGenericExceptionMacro( << "Show tables query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return result; } // all set, proceed // iterate over lines, we know there is only one column // and as many rows as there is databases while ( query->NextRow() ) { result.push_back( query->DataValue(0).ToString() ); } query->Delete(); return result; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void DropDatabase(vtkMySQLDatabase *ServerConnector, std::string DBName) { vtkSQLQuery * query = ServerConnector->GetQueryInstance(); std::ostringstream insertQuery; insertQuery << "DROP DATABASE " << DBName; query->SetQuery( insertQuery.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "Drop query failed" << query->GetLastErrorText() ); query->Delete(); return; } query->Delete(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void DropTable(vtkMySQLDatabase *DatabaseConnector, std::string TableName) { vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::ostringstream insertQuery; insertQuery << "DROP TABLE " << TableName; query->SetQuery( insertQuery.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "Drop query failed" << query->GetLastErrorText() ); query->Delete(); return; } query->Delete(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void DeleteRow(vtkMySQLDatabase *DatabaseConnector, std::string TableName, std::string field, std::string value) { std::stringstream querystream; querystream << "DELETE FROM "; querystream << TableName; querystream << " WHERE "; querystream << field; querystream << " = '"; querystream << value; querystream << "';"; ExecuteQuery( DatabaseConnector, querystream.str() ); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void DeleteRows(vtkMySQLDatabase *DatabaseConnector, std::string TableName, std::string field, std::vector< std::string > VectorValues) { std::stringstream querystream; querystream << "DELETE FROM "; querystream << TableName; querystream << " WHERE ("; unsigned int i; for ( i = 0; i < VectorValues.size() - 1; i++ ) { querystream << field; querystream << " = '"; querystream << VectorValues[i]; querystream << "' OR "; } querystream << field; querystream << " = '"; querystream << VectorValues[i]; querystream << "');"; ExecuteQuery( DatabaseConnector, querystream.str() ); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool DoesDatabaseExist(vtkMySQLDatabase *ServerConnector, std::string DBName) { std::vector< std::string > list; list = ListDatabases(ServerConnector); std::string myString(DBName); std::vector< std::string >::iterator start = list.begin(); std::vector< std::string >::iterator end = list.end(); while ( start != end ) { if ( ( *start ) == myString ) { return true; } ++start; } return false; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool DoesTableExist(vtkMySQLDatabase *DatabaseConnector, std::string TableName) { std::vector< std::string > list; list = ListTables(DatabaseConnector); std::string myString(TableName); std::vector< std::string >::iterator start = list.begin(); std::vector< std::string >::iterator end = list.end(); while ( start != end ) { if ( ( *start ) == myString ) { return true; } ++start; } return false; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void UpdateValueInDB(vtkMySQLDatabase *DatabaseConnector, std::string iTableName, std::string iColumnName, std::string iNewValue, std::string iField, std::vector< unsigned int > iVectIDs) { std::stringstream querystream; querystream << "UPDATE "; querystream << iTableName; querystream << " SET "; querystream << iColumnName; querystream << " = '"; querystream << iNewValue; querystream << "' WHERE "; querystream << GetConditions< unsigned int >(iField, iVectIDs, "OR"); ExecuteQuery( DatabaseConnector, querystream.str() ); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void UpdateValueInDB(vtkMySQLDatabase *DatabaseConnector, std::string TableName, std::string field, std::string newValue, std::string ColumnName, std::string value) { std::stringstream querystream; querystream << "UPDATE "; querystream << TableName; querystream << " SET "; querystream << field; querystream << " = '"; querystream << newValue; querystream << "' WHERE "; querystream << ColumnName; querystream << " = '"; querystream << value; querystream << "';"; ExecuteQuery( DatabaseConnector, querystream.str() ); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void UpdateValueInDB(vtkMySQLDatabase *DatabaseConnector, std::string iTableName, std::string ifield, std::string inewValue, std::vector< unsigned int > iVectIDs) { std::stringstream querystream; querystream << "UPDATE "; querystream << iTableName; querystream << " SET "; querystream << ifield; querystream << " = '"; querystream << inewValue; querystream << " WHERE ("; unsigned int i; for ( i = 0; i < iVectIDs.size() - 1; i++ ) { querystream << ifield; querystream << " = '"; querystream << iVectIDs[i]; querystream << "' OR "; } querystream << ifield; querystream << " = '"; querystream << iVectIDs[i]; querystream << "');"; ExecuteQuery( DatabaseConnector, querystream.str() ); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > GetFieldNames(std::string TableName, vtkMySQLDatabase *DatabaseConnector) { std::vector< std::string > result; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream querystream; querystream << "DESCRIBE "; querystream << TableName; querystream << ";"; query->SetQuery( querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "describe table query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return result; } while ( query->NextRow() ) { result.push_back( query->DataValue(0).ToString() ); } query->Delete(); return result; } GoFigure2-v0.9.0/Code/IO/GoDBTraceInfoForVisu.h0000644000175000017500000000457211667757442020622 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBTraceInfoForVisu_h #define __GoDBTraceInfoForVisu_h #include "vtkPolyData.h" /**\brief structure to pass the information between the visualization and the Database*/ struct GoDBTraceInfoForVisu { unsigned int TraceID; vtkPolyData *Points; unsigned int Red; unsigned int Green; unsigned int Blue; unsigned int Alpha; unsigned int TimePoint; bool IsHighLighted; GoDBTraceInfoForVisu() : Points( NULL ) { TraceID = 0; Red = 0; Green = 0; Blue = 0; Alpha = 255; TimePoint = 0; IsHighLighted = false; } }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/0000755000175000017500000000000011667757442016020 5ustar mathieumathieuGoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBCellTypeRow.cxx0000644000175000017500000000731411667757442021456 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBCellTypeRow.h" #include "GoDBRecordSetHelper.h" GoDBCellTypeRow::GoDBCellTypeRow() : GoDBNameDescRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBCellTypeRow::InitializeMap() { this->m_TableName = "celltype"; this->m_TableIDName = "CellTypeID"; this->m_MapRow[this->m_TableIDName] = std::string( "0" );//ConvertToString< int >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBCellTypeRow::DoesThisEntityAlreadyExists( vtkMySQLDatabase *DatabaseConnector) { return DoesThisNameAlreadyExists(DatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*int GoDBCellTypeRow::DoesThisEntityAlreadyExists( vtkMySQLDatabase* DatabaseConnector, std::string& ioName) { int ID = DoesThisNameAlreadyExists(DatabaseConnector); if (ID == -1) { return ID; } ioName = ReturnOnlyOneValue(DatabaseConnector, this->m_TableName, "Name", this->m_TableIDName, ConvertToString(ID)); return ID; }*/ //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBCellTypeRow::SaveInDB(vtkMySQLDatabase *iDatabaseConnector) { /*int CellTypeID = this->DoesThisEntityAlreadyExists(DatabaseConnector); if (CellTypeID == -1) { CellTypeID = AddOnlyOneNewObjectInTable(DatabaseConnector, this->m_TableName, *this, this->m_TableIDName); } return CellTypeID;*/ return GoDBNameDescRow::SaveInDBTemplate< GoDBCellTypeRow >(iDatabaseConnector, *this); } GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBProjectRow.h0000644000175000017500000000443411667757442020770 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBProjectRow_h #define __GoDBProjectRow_h #include #include #include #include #include "GoDBRow.h" #include "ConvertToStringHelper.h" /** \class GoDBProjectRow \brief manages a map with keys matching fields of the gofiguredatabase Project table and values of the map matching a row of the Project table \ingroup DB */ class QGOIO_EXPORT GoDBProjectRow:public GoDBRow { public: GoDBProjectRow(); ~GoDBProjectRow() {} protected: virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBLineageRow.cxx0000644000175000017500000000775211667757442021307 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBLineageRow.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBRecordSetHelper.h" #include GoDBLineageRow::GoDBLineageRow() { this->InitializeMap(); } //------------------------------------------------------------------------- GoDBLineageRow::~GoDBLineageRow () { } //------------------------------------------------------------------------- /*GoDBLineageRow::GoDBLineageRow(vtkMySQLDatabase *DatabaseConnector, GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID, vtkPolyData *TraceVisu) { //GoDBTraceRow::GoDBTraceRow(DatabaseConnector, TraceVisu, Min, Max, // ImgSessionID); if ( this->DoesThisBoundingBoxLineageExist(DatabaseConnector) ) { std::cout << "The bounding box alreaady exists for this lineage" << std::endl; } }*/ //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBLineageRow::InitializeMap() { this->m_TableName = "lineage"; this->m_TableIDName = "lineageID"; this->m_CollectionName = "None"; this->m_CollectionIDName = "NoneID"; this->m_MapRow[this->m_TableIDName] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["TrackIDRoot"] = std::string( "0" );//ConvertToString< int >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBLineageRow::DoesThisBoundingBoxLineageExist(vtkMySQLDatabase *DatabaseConnector) { std::vector< FieldWithValue > Conditions; this->AddConditions("ImagingSessionID", Conditions); this->AddConditions("CoordIDMax", Conditions); this->AddConditions("CoordIDMin", Conditions); return FindOneID(DatabaseConnector, "lineage", "lineageID", Conditions); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBLineageRow::SaveInDB(vtkMySQLDatabase *DatabaseConnector) { return this->SaveInDBTemplate< GoDBLineageRow >(DatabaseConnector, this); } GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBTrackFamilyRow.h0000644000175000017500000000523711667757442021572 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBTrackFamilyRow_h #define __GoDBTrackFamilyRow_h #include #include #include #include #include "GoDBRow.h" #include "ConvertToStringHelper.h" /** \class GoDBTrackFamilyRow \brief manages a map with keys matching fields of the gofiguredatabase TrackFamily table and values of the map matching a row of the TrackFamily table \ingroup DB */ class QGOIO_EXPORT GoDBTrackFamilyRow:public GoDBRow { public: GoDBTrackFamilyRow(); GoDBTrackFamilyRow(unsigned int iExistingID, vtkMySQLDatabase *DatabaseConnector); ~GoDBTrackFamilyRow() {} int SaveInDB(vtkMySQLDatabase *DatabaseConnector); /**\brief check if the track family already exists in the database, if yes, return the corresponding ID, if not, return -1*/ int DoesThisTrackFamilyAlreadyExists(vtkMySQLDatabase *DatabaseConnector); protected: virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBCellTypeRow.h0000644000175000017500000000473111667757442021103 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBCellTypeRow_h #define __GoDBCellTypeRow_h #include "GoDBNameDescRow.h" #include "vtkMySQLDatabase.h" /** \class GoDBCellTypeRow \brief this class manages the map with the keys matching the fields of the CellType gofiguredatabase table and values of the map matching a row of the Celltype table \ingroup DB */ class QGOIO_EXPORT GoDBCellTypeRow:public GoDBNameDescRow { public: GoDBCellTypeRow(); ~GoDBCellTypeRow() {} //mother class method virtual int SaveInDB(vtkMySQLDatabase *DatabaseConnector); //mother class method virtual int DoesThisEntityAlreadyExists( vtkMySQLDatabase *DatabaseConnector); protected: //mother class method virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBCoordinateRow.cxx0000644000175000017500000001061511667757442022022 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBCoordinateRow.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBRecordSetHelper.h" GoDBCoordinateRow::GoDBCoordinateRow() { this->InitializeMap(); this->m_TableName = "coordinate"; this->m_TableIDName = "CoordID"; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBCoordinateRow::InitializeMap() { this->m_MapRow["CoordID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["PCoord"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["RCoord"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["CCoord"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["XTileCoord"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["YTileCoord"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["ZTileCoord"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["XCoord"] = std::string( "0" );//ConvertToString< float >(0); this->m_MapRow["YCoord"] = std::string( "0" );//ConvertToString< float >(0); this->m_MapRow["ZCoord"] = std::string( "0" );//ConvertToString< float >(0); this->m_MapRow["TCoord"] = std::string( "0" );//ConvertToString< float >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBCoordinateRow::DoesThisCoordinateExist(vtkMySQLDatabase *DatabaseConnector) { std::vector< FieldWithValue > Conditions; this->AddConditions("PCoord", Conditions); this->AddConditions("RCoord", Conditions); this->AddConditions("CCoord", Conditions); this->AddConditions("XTileCoord", Conditions); this->AddConditions("YTileCoord", Conditions); this->AddConditions("ZTileCoord", Conditions); this->AddConditions("XCoord", Conditions); this->AddConditions("YCoord", Conditions); this->AddConditions("ZCoord", Conditions); this->AddConditions("TCoord", Conditions); return FindOneID(DatabaseConnector, "coordinate", "CoordID", Conditions); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBCoordinateRow::SaveInDB(vtkMySQLDatabase *DatabaseConnector) { int ID = this->DoesThisCoordinateExist(DatabaseConnector); if ( ID == -1 ) { return AddOnlyOneNewObjectInTable< GoDBCoordinateRow >(DatabaseConnector, "coordinate", *this, "CoordID"); } else { return ID; } } GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBMeshRow.h0000644000175000017500000001347311667757442020261 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBMeshRow_h #define __GoDBMeshRow_h #include #include "boost/unordered_map.hpp" #include #include #include "GoDBTraceRow.h" #include "GoDBCoordinateRow.h" #include "ConvertToStringHelper.h" #include "vtkMySQLDatabase.h" #include "vtkPolyData.h" #include "GoFigureMeshAttributes.h" /** \class GoDBMeshRow \brief this class manages the map with the keys matching the fields of the Mesh gofiguredatabase table and values of the map matching a row of the Mesh table \ingroup DB */ class QGOIO_EXPORT GoDBMeshRow:public GoDBTraceRow { public: GoDBMeshRow(); /** \brief fill the mesh map with the values gotten from the visualization \param[in] DatabaseConnector connection to the database \param[in] TraceVisu vtkPolyData the points will be extracted from to create a string for "Points" \param[in] Min coordinate row for the minimum of the bounding box \param[in] Max coordinate row for the maximum of the bounding box \param[in] ImgSessionID ID of the current imagingsession \param[in] iMeshAttributes container for intensity values */ explicit GoDBMeshRow(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID, GoFigureMeshAttributes *iMeshAttributes = 0); GoDBMeshRow(const GoDBMeshRow & iRow); /** \brief \param[in] ImagingSessionID ID of the current imagingsession */ GoDBMeshRow(unsigned int ImagingSessionID); //constructor GoDBTraceRow GoDBMeshRow(unsigned int iExistingID,vtkMySQLDatabase *iDatabaseConnector); ~GoDBMeshRow(); //int DoesThisBoundingBoxMeshExist(vtkMySQLDatabase* DatabaseConnector); /** \brief put the value of map["Celltype"] to CellTypeName \param[in] DatabaseConnector connection to the database \param[in] CellTypeName */ void SetCellType(vtkMySQLDatabase *DatabaseConnector, std::string CellTypeName); /** \brief put the value of map["SubCelltype"] to SubCellTypeName \param[in] DatabaseConnector connection to the database \param[in] SubCellTypeName */ void SetSubCellType(vtkMySQLDatabase *DatabaseConnector, std::string SubCellTypeName); //mother class method virtual int SaveInDB(vtkMySQLDatabase *DatabaseConnector); //void ReInitializeMapAfterCast(); /** \brief create the intensities per channel based on the channel names and values contained in iNameChannelWithValues \param[in] DatabaseConnector connection to the database \param[in] iNameChannelWithValues map with keys as channel names and values as intensities */ void SaveInDBTotalIntensityPerChannel(vtkMySQLDatabase *DatabaseConnector, boost::unordered_map< std::string, int > iNameChannelWithValues); /** \brief convert a GoDBTraceRow in GoDBMeshRow \param[in] iRow */ void SafeDownCast(GoDBTraceRow & iRow); /** \overload */ void SetTheDataFromTheVisu(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow iCoordMin, GoDBCoordinateRow iCoordMax, GoFigureMeshAttributes *iMeshAttributes); /** \brief static method.get the CellTypeID base on the name of the celltype \param[in] iDatabaseConnector connection to the database \param[in] iCellTypeName name of the celltype \return the ID of the celltype */ static int GetCellTypeID(vtkMySQLDatabase *iDatabaseConnector, std::string iCellTypeName); /** \brief static method.get the SubCellTypeID base on the name of the subcelltype \param[in] iDatabaseConnector connection to the database \param[in] iSubCellTypeName name of the subcelltype \return the ID of the subcelltype */ static int GetSubCellTypeID(vtkMySQLDatabase *iDatabaseConnector, std::string iSubCellTypeName); protected: //mother class method virtual void InitializeMap(); boost::unordered_map< std::string, int > m_NameChannelWithValues; }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBProjectRow.cxx0000644000175000017500000000442111667757442021337 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBProjectRow.h" GoDBProjectRow::GoDBProjectRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBProjectRow::InitializeMap() { this->m_MapRow["Name"] = ""; this->m_MapRow["Description"] = ""; this->m_MapRow["AuthorID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["CreationDate"] = ""; this->m_MapRow["DatabaseVersion"] = ""; } GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBImageRow.h0000644000175000017500000000443311667757442020403 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBImageRow_h #define __GoDBImageRow_h #include "ConvertToStringHelper.h" #include "GoDBRow.h" #include #include /** \class GoDBImageRow \brief manages a map with keys matching fields of the gofiguredatabase Image table and values of the map matching a row of the Image table \ingroup DB */ class QGOIO_EXPORT GoDBImageRow:public GoDBRow { public: GoDBImageRow(); ~GoDBImageRow() {} int SaveInDB(vtkMySQLDatabase *DatabaseConnector); protected: virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBLineageRow.h0000644000175000017500000000561011667757442020723 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBLineageRow_h #define __GoDBLineageRow_h #include #include #include #include #include "GoDBTraceRow.h" #include "ConvertToStringHelper.h" #include "vtkMySQLDatabase.h" /** \class GoDBLineageRow \brief this class manages the map with the keys matching the fields of the Lineage gofiguredatabase table and values of the map matching a row of the Lineage table \ingroup DB */ class QGOIO_EXPORT GoDBLineageRow:public GoDBTraceRow { public: GoDBLineageRow(); ~GoDBLineageRow(); //GoDBLineageRow(vtkMySQLDatabase *DatabaseConnector, GoDBCoordinateRow Min, // GoDBCoordinateRow Max, unsigned int ImgSessionID, vtkPolyData *TraceVisu); /** \brief \param[in] DatabaseConnector connection to the database \return the TrackID of the Track with the same bounding box already registered in the DB or -1 if not yet created */ int DoesThisBoundingBoxLineageExist(vtkMySQLDatabase *DatabaseConnector); //mother class method virtual int SaveInDB(vtkMySQLDatabase *DatabaseConnector); protected: //mother class method virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBBookmarkRow.h0000644000175000017500000000534411667757442021130 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBBookmarkRow_h #define __GoDBBookmarkRow_h #include #include #include #include #include "GoDBNameDescRow.h" #include "ConvertToStringHelper.h" #include "vtkMySQLDatabase.h" /** \class GoDBBookmarkRow \brief manages a map with keys matching fields of the gofiguredatabase Bookmark table and values of the map matching a row of the Bookmark table \ingroup DB */ class QGOIO_EXPORT GoDBBookmarkRow:public GoDBNameDescRow { public: GoDBBookmarkRow(); ~GoDBBookmarkRow() {} //mother class method virtual int SaveInDB(vtkMySQLDatabase *DatabaseConnector); //mother class method: here based on the name and the imagingsessionid virtual int DoesThisEntityAlreadyExists( vtkMySQLDatabase *DatabaseConnector); //mother class method:here based on the name and the imagingsessionid virtual int DoesThisNameAlreadyExists( vtkMySQLDatabase *DatabaseConnector); protected: virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBNameDescRow.h0000644000175000017500000001134111667757442021034 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBNameDescRow_h #define __GoDBNameDescRow_h #include "GoDBRow.h" #include "GoDBRecordSetHelper.h" #include "vtkMySQLDatabase.h" /** \class GoDBNameDescRow \brief Abstract. manages the map with the keys matching the fields for the DBtable containing a name and description fields. \ingroup DB */ class QGOIO_EXPORT GoDBNameDescRow:public GoDBRow { public: GoDBNameDescRow(); ~GoDBNameDescRow() {} /** \brief Pure Virtual :check if the entity already exists in the DB, if yes, return the existing ID, if not, save it in the DB and return the ID for the new created entity \param[in] iDatabaseConnector connection to the database \return int existing or new created ID for the entity */ virtual int SaveInDB(vtkMySQLDatabase *iDatabaseConnector) = 0; /** \brief Pure Virtual :check if the entity already exists in the database based on its own uniqueness definition, return the ID of the entity already existing or -1 if not yet created. \param[in] iDatabaseConnector connection to the database \return int existing ID or -1 if the entity doesn't exists */ virtual int DoesThisEntityAlreadyExists( vtkMySQLDatabase *iDatabaseConnector) = 0; /** \brief check if the entity already exists in the database based on its own uniqueness definition, return the ID of the entity already exiting or -1 if not yet created and change the ioName with the name of the existing entity \param[in] iDatabaseConnector connection to the database \param[in,out] ioName modified if the entity already exists with the name of the existing entity \return int existing ID or -1 if the entity doesn't exists */ virtual int DoesThisEntityAlreadyExistsAndReturnName( vtkMySQLDatabase *iDatabaseConnector, std::string & ioName); /** \brief check if the name already exists in the database, if yes, return the corresponding ID, if not -1 \param[in] iDatabaseConnector connection to the database \return int return the ID of the existing entity with the same name or -1 if no entity has the same name */ virtual int DoesThisNameAlreadyExists(vtkMySQLDatabase *iDatabaseConnector); protected: //mother class method virtual void InitializeMap(); /** \brief check if the GoDBNameDescRow already exists, if yes, return the ID of the existing one, if not, save it in the database and return the new ID \param[in] iDatabaseConnector connection to the database \param[in] iNewEntity new entity to be saved \tparam iNewEntity children of NameDescRow */ template< typename T > int SaveInDBTemplate(vtkMySQLDatabase *iDatabaseConnector, T iNewEntity) { int NewEntityID = iNewEntity.DoesThisEntityAlreadyExists(iDatabaseConnector); if ( NewEntityID == -1 ) { NewEntityID = AddOnlyOneNewObjectInTable< T >(iDatabaseConnector, iNewEntity.m_TableName, iNewEntity, iNewEntity.m_TableIDName); } return NewEntityID; } }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBBookmarkRow.cxx0000644000175000017500000000752011667757442021501 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBBookmarkRow.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBRecordSetHelper.h" GoDBBookmarkRow::GoDBBookmarkRow() { this->m_TableName = "bookmark"; this->m_TableIDName = "BookmarkID"; this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBBookmarkRow::InitializeMap() { this->m_MapRow["BookmarkID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["Name"] = ""; this->m_MapRow["ImagingSessionID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["CoordID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["CreationDate"] = ""; this->m_MapRow["Description"] = ""; std::string NoDescription = "None"; this->SetField("Description", NoDescription); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBBookmarkRow::DoesThisNameAlreadyExists( vtkMySQLDatabase *DatabaseConnector) { std::vector< FieldWithValue > Conditions; this->AddConditions("ImagingSessionID", Conditions); this->AddConditions("Name", Conditions); return FindOneID(DatabaseConnector, "bookmark", "BookmarkID", Conditions); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBBookmarkRow::DoesThisEntityAlreadyExists( vtkMySQLDatabase *iDatabaseConnector) { std::vector< FieldWithValue > Conditions; this->AddConditions("ImagingSessionID", Conditions); this->AddConditions("CoordID", Conditions); return FindOneID(iDatabaseConnector, "bookmark", "BookmarkID", Conditions); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBBookmarkRow::SaveInDB(vtkMySQLDatabase *iDatabaseConnector) { return this->SaveInDBTemplate< GoDBBookmarkRow >(iDatabaseConnector, *this); } GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBSubCellTypeRow.cxx0000644000175000017500000000735111667757442022131 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBSubCellTypeRow.h" #include "GoDBRecordSetHelper.h" GoDBSubCellTypeRow::GoDBSubCellTypeRow() : GoDBNameDescRow() { this->m_TableName = "subcellulartype"; this->m_TableIDName = "SubCellularID"; this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBSubCellTypeRow::InitializeMap() { this->m_MapRow[this->m_TableIDName] = ConvertToString< int >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBSubCellTypeRow::DoesThisEntityAlreadyExists( vtkMySQLDatabase *DatabaseConnector) { return DoesThisNameAlreadyExists(DatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*int GoDBSubCellTypeRow::DoesThisEntityAlreadyExists( vtkMySQLDatabase* DatabaseConnector, std::string& ioName) { int ID = DoesThisNameAlreadyExists(DatabaseConnector); if (ID == -1) { return ID; } ioName = ReturnOnlyOneValue(DatabaseConnector, this->m_TableName, "Name", this->m_TableIDName, ConvertToString(ID)); return ID; }*/ //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBSubCellTypeRow::SaveInDB(vtkMySQLDatabase *iDatabaseConnector) { /* int SubCellTypeID = this->DoesThisEntityAlreadyExists(DatabaseConnector); if (SubCellTypeID == -1) { SubCellTypeID = AddOnlyOneNewObjectInTable(DatabaseConnector, this->m_TableName, *this, this->m_TableIDName); } return SubCellTypeID;*/ return this->SaveInDBTemplate< GoDBSubCellTypeRow >(iDatabaseConnector, *this); }GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBImgSessionRow.h0000644000175000017500000000527711667757442021450 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBImgSessionRow_h #define __GoDBImgSessionRow_h #include "ConvertToStringHelper.h" #include "GoDBRow.h" #include "vtkMySQLDatabase.h" #include #include /** \class GoDBImgSessionRow \brief manages a map with keys matching fields of the gofiguredatabase ImgSession table and values of the map matching a row of the ImgSession table \ingroup DB */ class QGOIO_EXPORT GoDBImgSessionRow:public GoDBRow { public: GoDBImgSessionRow(); // : GoDBRow() ~GoDBImgSessionRow() {} /** \brief return the ImgSessionID of the imaging session with the same date+time of creation and microscope already registered in the DB or -1 if not yet created \param[in] DatabaseConnector connection to the database \return the ID of the existing ImgSession, -1 if the ImgSession does'nt exist yet */ int DoesThisImagingSessionExist(vtkMySQLDatabase *DatabaseConnector); protected: virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBChannelRow.cxx0000644000175000017500000000746711667757442021316 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBChannelRow.h" #include "GoDBRecordSetHelper.h" GoDBChannelRow::GoDBChannelRow() : GoDBRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBChannelRow::InitializeMap() { this->m_TableName = "channel"; this->m_TableIDName = "ChannelID"; this->m_MapRow["ChannelID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["Name"] = ""; this->m_MapRow["ImagingSessionID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["ColorID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["ChannelNumber"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["NumberOfBits"] = std::string( "0" );//ConvertToString< int >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBChannelRow::SaveInDB(vtkMySQLDatabase *DatabaseConnector) { int ChannelID = this->DoesThisChannelAlreadyExists(DatabaseConnector); if ( ChannelID == -1 ) { ChannelID = AddOnlyOneNewObjectInTable< GoDBChannelRow >( DatabaseConnector, "channel", *this, "ChannelID"); } return ChannelID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBChannelRow::DoesThisChannelAlreadyExists( vtkMySQLDatabase *DatabaseConnector) { std::vector< FieldWithValue > Conditions; this->AddConditions("ImagingSessionID", Conditions); this->AddConditions("ChannelNumber", Conditions); return FindOneID(DatabaseConnector, "channel", "ChannelID", Conditions); /** \todo Lydie: Once we get the channel names from the megacapture file, the uniqueness of the channel can be ImagingSessionID + Name*/ } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBColorRow.cxx0000644000175000017500000001047211667757442021012 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBColorRow.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBRecordSetHelper.h" GoDBColorRow::GoDBColorRow() : GoDBNameDescRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBColorRow::InitializeMap() { this->m_TableName = "color"; this->m_TableIDName = "ColorID"; this->m_MapRow[this->m_TableIDName] = std::string( "0" );//ConvertToString< int >(0); //this->m_MapRow["Name"] = ""; this->m_MapRow["Red"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["Green"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["Blue"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["Alpha"] = std::string( "0" );//ConvertToString< int >(0); //this->m_MapRow["Description"] = ""; //std::string NoDescription = "None"; //this->SetField("Description", NoDescription); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBColorRow::DoesThisEntityAlreadyExists( vtkMySQLDatabase *iDatabaseConnector) { return this->DoesThisNameAlreadyExists(iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBColorRow::SaveInDB(vtkMySQLDatabase *iDatabaseConnector) { /*int ColorID = this->DoesThisEntityAlreadyExists(DatabaseConnector); if (ColorID == -1) { ColorID = AddOnlyOneNewObjectInTable(DatabaseConnector, "color", *this, "ColorID"); } return ColorID;*/ return this->SaveInDBTemplate< GoDBColorRow >(iDatabaseConnector, *this); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*int GoDBColorRow::DoesThisEntityAlreadyExists(vtkMySQLDatabase* DatabaseConnector) { std::string Red = this->GetMapValue("Red"); std::string Blue = this->GetMapValue("Blue"); std::string Green = this->GetMapValue("Green"); std::string Alpha = this->GetMapValue("Alpha"); std::string Name = this->GetMapValue("Name"); //return FindOneID(DatabaseConnector,"color", "ColorID","Red",Red,"Green",Green, //"Blue",Blue,"Alpha",Alpha,"Name",Name); return FindOneID(DatabaseConnector, "color", "ColorID", "Name", this->GetMapValue("Name")); }*/ GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBRow.cxx0000644000175000017500000002106611667757442020014 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBRow.h" #include GoDBRow::GoDBRow() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBRow::~GoDBRow() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBRow::SetField(const std::string& key, const std::string& value) { StringMapIterator it = m_MapRow.find(key); if ( it != m_MapRow.end() ) { std::stringstream valueToQuery; valueToQuery << "\"" << value << "\""; it->second = valueToQuery.str(); } else { std::cerr << "This field does not exist!!!" << std::endl; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GoDBRow::PrintValues() { std::stringstream ListValues; for ( StringMapIterator iter = m_MapRow.begin(); iter != m_MapRow.end(); ++iter ) { ListValues << iter->second << ", "; } size_t n = ListValues.str().length() - 2; return ListValues.str().substr(0, n); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GoDBRow::PrintColumnNames() { std::stringstream ListColumnNames; for ( StringMapIterator iter = m_MapRow.begin(); iter != m_MapRow.end(); ++iter ) { ListColumnNames << iter->first << ", "; } size_t n = ListColumnNames.str().length() - 2; return ListColumnNames.str().substr(0, n); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GoDBRow::PrintColumnNamesWithValues() { std::stringstream StringQuery; for ( StringMapIterator iter = m_MapRow.begin(); iter != m_MapRow.end(); ++iter ) { StringQuery << iter->first; StringQuery << " = "; StringQuery << iter->second; StringQuery << ", "; } size_t n = StringQuery.str().length() - 2; return StringQuery.str().substr(0, n); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector< std::string > GoDBRow::GetVectorColumnNames() { std::vector< std::string > VectorColumnNames; for ( StringMapIterator iter = m_MapRow.begin(); iter != m_MapRow.end(); ++iter ) { VectorColumnNames.push_back(iter->first); } return VectorColumnNames; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBRow::StringMapIterator GoDBRow::MapBegin() { return m_MapRow.begin(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBRow::StringMapIterator GoDBRow::MapEnd() { return m_MapRow.end(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBRow::StringMapConstIterator GoDBRow::ConstMapBegin() { return m_MapRow.begin(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBRow::StringMapConstIterator GoDBRow::ConstMapEnd() { return m_MapRow.end(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GoDBRow::GetMapValue(const std::string& key) { std::string oMapValue = "noValue"; StringMapIterator iter = m_MapRow.find(key); if ( iter == m_MapRow.end() ) { return oMapValue; } else { oMapValue = iter->second; // Need to test if the value is not a string previously put in the map by // SetField // if so, the value will be ""value"" and need to be transformed to "value". // First, // find the 1rst character and save it as CharacterToCompare: std::string CharacterToCompare = oMapValue.substr(0, 1); //test if it is equal to " : if ( CharacterToCompare == "\"" ) { //if yes, remove the " at the beginning of the string and at the end: oMapValue = oMapValue.substr(1, oMapValue.size() - 2); } return oMapValue; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool GoDBRow::SetValuesForSpecificID(int ID, vtkMySQLDatabase *iDatabaseConnector) { std::vector< std::string > ResultQuery = ListSpecificValuesForOneColumn( iDatabaseConnector, this->m_TableName, this->PrintColumnNames(), this->m_TableIDName, ConvertToString< int >(ID) ); if ( ResultQuery.empty() ) { return false; } if ( this->m_MapRow.size() != ResultQuery.size() ) { std::cout << "pb the map and the query results are not the same size"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return false; } std::vector< std::string >::iterator iterResultQuery = ResultQuery.begin(); StringMapIterator iterMap = this->MapBegin(); while ( iterMap != this->MapEnd() ) { iterMap->second = *iterResultQuery; ++iterMap; ++iterResultQuery; } return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GoDBRow::GetTableName() { return this->m_TableName; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GoDBRow::GetTableIDName() { return this->m_TableIDName; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBRow::AddConditions( const std::string& iNameOfField, std::vector< FieldWithValue > & ioFieldWithValue) { FieldWithValue temp = { iNameOfField, this->GetMapValue(iNameOfField), "=" }; ioFieldWithValue.push_back(temp); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBRow::DeleteFromDB( vtkMySQLDatabase *iDatabaseConnector) { if (this->GetMapValue(this->m_TableIDName) != "0") { DeleteRow(iDatabaseConnector, this->m_TableName, this->m_TableIDName, this->GetMapValue(this->m_TableIDName) ); } } GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBTraceRow.h0000644000175000017500000001727611667757442020430 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBTraceRow_h #define __GoDBTraceRow_h #include "GoDBCoordinateRow.h" #include "GoDBRecordSetHelper.h" #include "GoDBRecordSet.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkMySQLDatabase.h" /** \class GoDBTraceRow \brief abstract class to be inherited by Contour,Mesh,Track and GoDBLineageRow \ingroup DB */ class QGOIO_EXPORT GoDBTraceRow:public GoDBRow { public: GoDBTraceRow(); /** \brief fill the trace map with the values gotten from the visualization \param[in] DatabaseConnector connection to the database \param[in] TraceVisu vtkPolyData the points will be extracted from to create a string for "Points" \param[in] Min coordinate row for the minimum of the bounding box \param[in] Max coordinate row for the maximum of the bounding box \param[in] ImgSessionID ID of the current imagingsession */ GoDBTraceRow(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID); //GoDBTraceRow(vtkMySQLDatabase *DatabaseConnector, std::string TraceVisu, // GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID); //GoDBTraceRow(unsigned int ImgSessionID); //GoDBTraceRow(unsigned int iExistingID,vtkMySQLDatabase *iDatabaseConnector); ~GoDBTraceRow() {} /** \brief check if a trace already has the same bounding box \param[in] DatabaseConnector connection to the database \return the TraceID of the Trace with the same bounding box already registered in the DB or -1 if not yet created */ int DoesThisBoundingBoxExist(vtkMySQLDatabase *DatabaseConnector); /** \brief get the colorID corresponding to the rgba values and set the colorID field of the trace with it \param[in] Red \param[in] Green \param[in] Blue \param[in] Alpha \param[in] ColorName \param[in] DatabaseConnector connection to the database */ void SetColor(unsigned int Red, unsigned int Green, unsigned int Blue, unsigned int Alpha, std::string ColorName, vtkMySQLDatabase *DatabaseConnector); /** \brief \return the collectionID name */ std::string GetCollectionIDName(); /** \brief \return the collection name */ std::string GetCollectionName(); /** \brief check in the database if the Coordinate Min and Max already exists, if yes fill the map["CoordIDMin"] and ["CoordIDmax"] with the existing CoordinateID if not, create the coordinates in the database and fill the map with the new created ID, if the bounding box already exists, a cout is generated \param[in] iDatabaseConnector connection to the database \param[in] Min coordinate row for the minimum of the bounding box \param[in] Max coordinate row for the maximum of the bounding box */ void SetTheBoundingBox(vtkMySQLDatabase *iDatabaseConnector, GoDBCoordinateRow Min, GoDBCoordinateRow Max); /** \brief set the collectionID field to iCollectionID \param[in] iCollectionID collectionID to be set to */ void SetCollectionID(unsigned int iCollectionID); /** \overload */ bool SetValuesForSpecificID(int ID, vtkMySQLDatabase *iDatabaseConnector); /** \brief save the row in the database if the TraceID is set to "0", update the existing traceRow if the TraceID is <> 0 \param[in] DatabaseConnector connection to the database \return the ID of the updated or saved trace */ virtual int SaveInDB(vtkMySQLDatabase *DatabaseConnector) = 0; protected: virtual void InitializeMap(); /**\brief check in the database if the Coordinate Min adn Max already exists, if yes fill the map["CoordIDMin"] and ["CoordIDmax"] with the existing CoordinateID if not, create the coordinates in the database and fill the map with the new created ID, if the bounding box already exists, a cout is generated*/ // void CreateBoundingBox(vtkMySQLDatabase* DatabaseConnector, // GoDBCoordinateRow Min, // GoDBCoordinateRow Max); std::string m_CollectionIDName; std::string m_CollectionName; /** \brief set the ImagingSessionID field to iImgSessionID \param[in] iImgSessionID collectionID to be set to */ void SetImgSessionID(unsigned int iImgSessionID); /** \brief save the row in the database if the TraceID is set to "0", update the existing traceRow if the TraceID is <> 0 \param[in] iDatabaseConnector connection to the database \param[in] iTrace trace to be saved \tparam T children of GoDBTraceRow \return the ID of the updated or saved trace */ template< typename T > int SaveInDBTemplate(vtkMySQLDatabase *iDatabaseConnector, T* iTrace) { int SavedTraceID; //in case the ID is different from 0, this means the values have been //updated for this trace, so we update it in the database: if ( this->m_MapRow[this->m_TableIDName] != "0" ) { SavedTraceID = UpdateOneNewObjectInTable< T >(iDatabaseConnector, iTrace); } else { SavedTraceID = AddOnlyOneNewObjectInTable< T >(iDatabaseConnector, this->m_TableName, iTrace, this->m_TableIDName); this->SetField(this->m_TableIDName, SavedTraceID); } return SavedTraceID; } template< typename T > void SetTheDataFromTheVisuTemplate(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow iCoordMin, GoDBCoordinateRow iCoordMax) { this->SetTheBoundingBox(DatabaseConnector, iCoordMin, iCoordMax); vtkSmartPointer< T > convert = vtkSmartPointer< T >::New(); std::string PointsString = convert->GetMySQLText(TraceVisu); this->SetField("Points", PointsString); if ( this->DoesThisBoundingBoxExist(DatabaseConnector) != -1) { std::cout << "The bounding box already exists for this mesh" << std::endl; } } }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBTrackRow.cxx0000644000175000017500000001475011667757442021003 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBTrackRow.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBRecordSetHelper.h" #include "vtkPolyDataMySQLTrackWriter.h" #include #include "vtkSmartPointer.h" GoDBTrackRow::GoDBTrackRow() : GoDBTraceRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBTrackRow::GoDBTrackRow(vtkMySQLDatabase *DatabaseConnector, GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID, std::string TraceVisu) : GoDBTraceRow() { this->InitializeMap(); this->SetImgSessionID(ImgSessionID); this->SetTheBoundingBox(DatabaseConnector, Min, Max); this->SetField("Points", TraceVisu); cout << "Track ID found: " << this->DoesThisBoundingBoxTrackExist(DatabaseConnector) << endl; if ( this->DoesThisBoundingBoxTrackExist(DatabaseConnector) ) { std::cout << "The bounding box already exists for this track" << std::endl; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBTrackRow::GoDBTrackRow(unsigned int ImagingSessionID) : GoDBTraceRow() { this->InitializeMap(); this->SetImgSessionID(ImagingSessionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBTrackRow::GoDBTrackRow(unsigned int iExistingID, vtkMySQLDatabase *iDatabaseConnector) : GoDBTraceRow() { this->InitializeMap(); this->SetValuesForSpecificID(iExistingID, iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBTrackRow::GoDBTrackRow(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID) : GoDBTraceRow() { this->InitializeMap(); this->SetImgSessionID(ImgSessionID); this->SetTheDataFromTheVisu(DatabaseConnector, TraceVisu, Min, Max); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBTrackRow::InitializeMap() { this->m_TableName = "track"; this->m_TableIDName = "trackID"; this->m_CollectionName = "lineage"; this->m_CollectionIDName = "lineageID"; this->m_MapRow[this->m_TableIDName] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["lineageID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["TrackFamilyID"] = std::string( "0" );//ConvertToString< int >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBTrackRow::DoesThisBoundingBoxTrackExist( vtkMySQLDatabase *DatabaseConnector) { std::vector< FieldWithValue > Conditions; this->AddConditions("ImagingSessionID", Conditions); this->AddConditions("CoordIDMax", Conditions); this->AddConditions("CoordIDMin", Conditions); return FindOneID(DatabaseConnector, "track", "trackID", Conditions); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBTrackRow::SaveInDB(vtkMySQLDatabase *DatabaseConnector) { return this->SaveInDBTemplate< GoDBTrackRow >(DatabaseConnector, this); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBTrackRow::SetTheDataFromTheVisu(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TrackVisu, GoDBCoordinateRow iCoordMin, GoDBCoordinateRow iCoordMax) { this->SetTheDataFromTheVisuTemplate< vtkPolyDataMySQLTrackWriter >( DatabaseConnector, TrackVisu, iCoordMin, iCoordMax); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBTrackRow::SetThePointsFromPolydata(vtkPolyData *iTrackVisu) { std::string PointsString = "0"; //in case the track has no more meshes if ( iTrackVisu ) { vtkSmartPointer< vtkPolyDataMySQLTrackWriter > convert = vtkSmartPointer< vtkPolyDataMySQLTrackWriter >::New(); PointsString = convert->GetMySQLText(iTrackVisu); } this->SetField("Points", PointsString); } GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBAuthorRow.cxx0000644000175000017500000000675511667757442021207 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBAuthorRow.h" #include "GoDBRecordSetHelper.h" GoDBAuthorRow::GoDBAuthorRow() : GoDBRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBAuthorRow::InitializeMap() { this->m_TableName = "author"; this->m_TableIDName = "authorID"; this->m_MapRow["authorID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["LastName"] = ""; this->m_MapRow["FirstName"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["MiddleName"] = ""; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBAuthorRow::SaveInDB(vtkMySQLDatabase *DatabaseConnector) { int AuthorID = this->DoesThisAuthorAlreadyExists(DatabaseConnector); if ( AuthorID == -1 ) { AuthorID = AddOnlyOneNewObjectInTable< GoDBAuthorRow >( DatabaseConnector, "author", *this, "authorID"); } return AuthorID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBAuthorRow::DoesThisAuthorAlreadyExists( vtkMySQLDatabase *DatabaseConnector) { std::vector< FieldWithValue > Conditions; this->AddConditions("FirstName", Conditions); this->AddConditions("LastName", Conditions); this->AddConditions("MiddleName", Conditions); return FindOneID(DatabaseConnector, "author", "authorID", Conditions); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBCoordinateRow.h0000644000175000017500000000525511667757442021453 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBCoordinateRow_h #define __GoDBCoordinateRow_h #include "ConvertToStringHelper.h" #include "GoDBRow.h" #include "vtkMySQLDatabase.h" #include #include /** \class GoDBCoordinateRow \brief manages a map with keys matching fields of the gofiguredatabase Coordinate table and values of the map matching a row of the Coordinate table \ingroup DB */ class QGOIO_EXPORT GoDBCoordinateRow:public GoDBRow { public: GoDBCoordinateRow(); ~GoDBCoordinateRow() {} /** \brief return the CoordID of the coordinate with the same attributes already registered in the DB or -1 if not yet created*/ int DoesThisCoordinateExist(vtkMySQLDatabase *DatabaseConnector); /** \brief save the coordinate in the database and return the ID of the new created coordinate or the ID of the existing one*/ int SaveInDB(vtkMySQLDatabase *DatabaseConnector); protected: virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBImageRow.cxx0000644000175000017500000000603311667757442020754 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBImageRow.h" #include "GoDBRecordSetHelper.h" GoDBImageRow::GoDBImageRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBImageRow::InitializeMap() { this->m_MapRow["ImageID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["ImagingSessionID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["CoordIDMin"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["Filename"] = ""; this->m_MapRow["ChannelID"] = std::string( "1" );//ConvertToString< int >(1); //\todo :change back // to 0 or -1 } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBImageRow::SaveInDB(vtkMySQLDatabase *DatabaseConnector) { return AddOnlyOneNewObjectInTable< GoDBImageRow >(DatabaseConnector, "image", *this, "ImageID"); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBMeshRow.cxx0000644000175000017500000002355611667757442020637 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBMeshRow.h" #include "GoDBColorRow.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBRecordSetHelper.h" #include "GoDBIntensityRow.h" #include "vtkPolyDataMySQLMeshWriter.h" #include "vtkSmartPointer.h" #include //------------------------------------------------------------------------- GoDBMeshRow::GoDBMeshRow() : GoDBTraceRow() { this->InitializeMap(); m_NameChannelWithValues.clear(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBMeshRow::~GoDBMeshRow() { } //------------------------------------------------------------------------- GoDBMeshRow::GoDBMeshRow(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID, GoFigureMeshAttributes *iMeshAttributes) : GoDBTraceRow() { this->InitializeMap(); this->SetImgSessionID(ImgSessionID); this->SetTheDataFromTheVisu(DatabaseConnector, TraceVisu, Min, Max, iMeshAttributes); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBMeshRow::GoDBMeshRow(unsigned int ImagingSessionID) : GoDBTraceRow() { this->InitializeMap(); this->SetImgSessionID(ImagingSessionID); this->m_MapRow["ImagingSessionID"] = ConvertToString< int >(ImagingSessionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBMeshRow::GoDBMeshRow(unsigned int iExistingID, vtkMySQLDatabase *iDatabaseConnector) : GoDBTraceRow() { this->InitializeMap(); this->SetValuesForSpecificID(iExistingID, iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBMeshRow::GoDBMeshRow(const GoDBMeshRow & iRow) : GoDBTraceRow() { this->m_TableName = iRow.m_TableName; this->m_TableIDName = iRow.m_TableIDName; this->m_CollectionIDName = iRow.m_CollectionIDName; this->m_CollectionName = iRow.m_CollectionName; this->InitializeMap(); this->m_MapRow = iRow.m_MapRow; if ( !iRow.m_NameChannelWithValues.empty() ) { m_NameChannelWithValues = iRow.m_NameChannelWithValues; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBMeshRow::SetTheDataFromTheVisu(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow iCoordMin, GoDBCoordinateRow iCoordMax, GoFigureMeshAttributes *iMeshAttributes) { this->SetTheDataFromTheVisuTemplate< vtkPolyDataMySQLMeshWriter >( DatabaseConnector, TraceVisu, iCoordMin, iCoordMax); m_NameChannelWithValues.clear(); if ( iMeshAttributes ) { this->m_NameChannelWithValues = iMeshAttributes->m_TotalIntensityMap; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBMeshRow::SafeDownCast(GoDBTraceRow & iRow) { GoDBTraceRow::StringMapConstIterator iRowIt = iRow.ConstMapBegin(); while ( iRowIt != iRow.ConstMapEnd() ) { this->SetField(iRowIt->first, iRowIt->second); ++iRowIt; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBMeshRow::InitializeMap() { GoDBTraceRow::InitializeMap(); this->m_TableName = "mesh"; this->m_TableIDName = "meshID"; this->m_CollectionName = "track"; this->m_CollectionIDName = "trackID"; this->m_MapRow[this->m_TableIDName] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["CellTypeID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["SubCellularID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["trackID"] = std::string( "0" );//ConvertToString< int >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBMeshRow::SaveInDB(vtkMySQLDatabase *DatabaseConnector) { int SavedMeshID = GoDBTraceRow::SaveInDBTemplate< GoDBMeshRow >(DatabaseConnector, this); if ( !this->m_NameChannelWithValues.empty() ) { this->SaveInDBTotalIntensityPerChannel(DatabaseConnector, this->m_NameChannelWithValues); } return SavedMeshID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBMeshRow::GetCellTypeID(vtkMySQLDatabase *iDatabaseConnector, std::string iCellTypeName) { return FindOneID(iDatabaseConnector, "celltype", "CellTypeID", "Name", iCellTypeName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBMeshRow::SetCellType(vtkMySQLDatabase *iDatabaseConnector, std::string iCellTypeName) { if ( iCellTypeName != "Add a new celltype..." && iCellTypeName != "Delete a celltype" ) { this->SetField< int >( "CellTypeID", GoDBMeshRow::GetCellTypeID(iDatabaseConnector, iCellTypeName) ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBMeshRow::GetSubCellTypeID(vtkMySQLDatabase *iDatabaseConnector, std::string iSubCellTypeName) { return FindOneID(iDatabaseConnector, "subcellulartype", "SubCellularID", "Name", iSubCellTypeName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBMeshRow::SetSubCellType(vtkMySQLDatabase *iDatabaseConnector, std::string iSubCellTypeName) { if ( iSubCellTypeName != "Add a new subcelltype..." && iSubCellTypeName != "Delete a subcelltype" ) { this->SetField< int >( "SubCellularID", GoDBMeshRow::GetSubCellTypeID(iDatabaseConnector, iSubCellTypeName) ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBMeshRow::SaveInDBTotalIntensityPerChannel( vtkMySQLDatabase *DatabaseConnector, boost::unordered_map< std::string, int > iNameChannelWithValues) { if ( this->GetMapValue("meshID") == "0" ) { std::cout << "The mesh needs to be saved before" << std::endl; return; } if ( this->GetMapValue("ImagingSessionID") == "0" ) { std::cout << "The imagingSession hasn't been entered for the mesh" << std::endl; } boost::unordered_map< std::string, int >::iterator iter = iNameChannelWithValues.begin(); while ( iter != iNameChannelWithValues.end() ) { std::vector< FieldWithValue > Conditions; this->AddConditions("ImagingSessionID", Conditions); FieldWithValue Name = { "Name", iter->first, "=" }; Conditions.push_back(Name); int ChannelID = FindOneID(DatabaseConnector, "channel", "ChannelID", Conditions); GoDBIntensityRow NewIntensity; NewIntensity.SetField("ChannelID", ChannelID); NewIntensity.SetField("Value", iter->second); std::string strMeshID = this->GetMapValue("meshID"); NewIntensity.SetField( "meshID", this->GetMapValue("meshID") ); NewIntensity.SaveInDB(DatabaseConnector); ++iter; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBNameDescRow.cxx0000644000175000017500000000645211667757442021416 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBRow.h" #include "GoDBNameDescRow.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBRecordSetHelper.h" GoDBNameDescRow::GoDBNameDescRow() : GoDBRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBNameDescRow::InitializeMap() { this->m_MapRow["Name"] = ""; this->m_MapRow["Description"] = ""; std::string NoDescription = "None"; std::string NoName = "None"; this->SetField("Description", NoDescription); this->SetField ("Name", NoName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBNameDescRow::DoesThisNameAlreadyExists( vtkMySQLDatabase *DatabaseConnector) { return FindOneID( DatabaseConnector, this->m_TableName, this->m_TableIDName, "Name", this->GetMapValue("Name") ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBNameDescRow::DoesThisEntityAlreadyExistsAndReturnName( vtkMySQLDatabase *iDatabaseConnector, std::string & ioName) { int ID = this->DoesThisEntityAlreadyExists(iDatabaseConnector); if ( ID == -1 ) { return ID; } ioName = ReturnOnlyOneValue( iDatabaseConnector, this->m_TableName, "Name", this->m_TableIDName, ConvertToString< int >(ID) ); return ID; }GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBIntensityRow.h0000755000175000017500000000526111667757442021352 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBIntensityRow_h #define __GoDBIntensityRow_h #include #include #include #include #include "GoDBRow.h" #include "ConvertToStringHelper.h" /** \class GoDBIntensityRow \brief manages a map with keys matching fields of the gofiguredatabase Intensity table and values of the map matching a row of the Intensity table \ingroup DB */ class QGOIO_EXPORT GoDBIntensityRow:public GoDBRow { public: GoDBIntensityRow(); ~GoDBIntensityRow(); /** \brief check if the intensity already exists in the database, if yes, return the corresponding ID, if not, return -1 \param[in] DatabaseConnector connection to the database \return the ID of the existing intensity and -1 if it doesn't exist */ int DoesThisIntensityAlreadyExists(vtkMySQLDatabase *DatabaseConnector); int SaveInDB(vtkMySQLDatabase *DatabaseConnector); protected: virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBSubCellTypeRow.h0000644000175000017500000000502611667757442021553 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBSubCellTypeRow_h #define __GoDBSubCellTypeRow_h #include "GoDBNameDescRow.h" #include "vtkMySQLDatabase.h" #include "QGoIOConfigure.h" /** \class GoDBSubCellTypeRow \brief this class manages the map with the keys matching the fields of the SubCellularType gofiguredatabase table and values of the map matching a row of the SubCellulartype table \ingroup DB */ class QGOIO_EXPORT GoDBSubCellTypeRow:public GoDBNameDescRow { public: GoDBSubCellTypeRow(); ~GoDBSubCellTypeRow() {} //mother class method virtual int SaveInDB(vtkMySQLDatabase *DatabaseConnector); //mother class method virtual int DoesThisEntityAlreadyExists( vtkMySQLDatabase *DatabaseConnector); protected: //mother class method virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBTraceRow.cxx0000644000175000017500000001644411667757442020777 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBTraceRow.h" #include "GoDBColorRow.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBRecordSetHelper.h" #include "vtkPolyDataMySQLContourWriter.h" #include "vtkSmartPointer.h" GoDBTraceRow::GoDBTraceRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBTraceRow::GoDBTraceRow(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID) { (void)Min; (void)Max; (void)TraceVisu; (void)DatabaseConnector; this->InitializeMap(); this->m_MapRow["ImagingSessionID"] = ConvertToString< unsigned int >(ImgSessionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*GoDBTraceRow::GoDBTraceRow(vtkMySQLDatabase *DatabaseConnector, std::string TraceVisu, GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID) { this->InitializeMap(); this->SetTheBoundingBox(DatabaseConnector, Min, Max); this->m_MapRow["ImagingSessionID"] = ConvertToString< unsigned int >(ImgSessionID); this->SetField("Points", TraceVisu); }*/ //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBTraceRow::InitializeMap() { this->m_MapRow["ImagingSessionID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["ColorID"] = std::string( "1" );//ConvertToString< int >(1); this->m_MapRow["CoordIDMax"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["CoordIDMin"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["Points"] = std::string( "0" );//ConvertToString< int >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBTraceRow::SetTheBoundingBox(vtkMySQLDatabase *DatabaseConnector, GoDBCoordinateRow Min, GoDBCoordinateRow Max) { int CoordMin = Min.DoesThisCoordinateExist(DatabaseConnector); if ( CoordMin == -1 ) { CoordMin = Min.SaveInDB(DatabaseConnector); } this->m_MapRow["CoordIDMin"] = ConvertToString< int >(CoordMin); int CoordMax = Max.DoesThisCoordinateExist(DatabaseConnector); if ( CoordMax == -1 ) { CoordMax = Max.SaveInDB(DatabaseConnector); } this->m_MapRow["CoordIDMax"] = ConvertToString< int >(CoordMax); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBTraceRow::DoesThisBoundingBoxExist( vtkMySQLDatabase *DatabaseConnector) { std::vector< FieldWithValue > Conditions; this->AddConditions("CoordIDMax", Conditions); this->AddConditions("CoordIDMin", Conditions); this->AddConditions("ImagingSessionID", Conditions); return FindOneID(DatabaseConnector, this->m_TableName, this->m_TableIDName, Conditions); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBTraceRow::SetColor(unsigned int Red, unsigned int Green, unsigned int Blue, unsigned int Alpha, std::string ColorName, vtkMySQLDatabase *DatabaseConnector) { GoDBColorRow ColorRow; ColorRow.SetField< int >("Red", Red); ColorRow.SetField< int >("Green", Green); ColorRow.SetField< int >("Blue", Blue); ColorRow.SetField< int >("Alpha", Alpha); ColorRow.SetField("Name", ColorName); int ColorID = ColorRow.DoesThisEntityAlreadyExists(DatabaseConnector); if ( ColorID == -1 ) { this->m_MapRow["ColorID"] = ConvertToString< int >( ColorRow.SaveInDB(DatabaseConnector) ); } else { this->SetField< int >("ColorID", ColorID); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GoDBTraceRow::GetCollectionIDName() { return this->m_CollectionIDName; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GoDBTraceRow::GetCollectionName() { return this->m_CollectionName; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBTraceRow::SetCollectionID(unsigned int iCollectionID) { this->SetField< int >(this->m_CollectionIDName, iCollectionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBTraceRow::SetImgSessionID(unsigned int iImgSessionID) { this->SetField< int >("ImagingSessionID", iImgSessionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool GoDBTraceRow::SetValuesForSpecificID(int ID, vtkMySQLDatabase *iDatabaseConnector) { if ( GoDBRow::SetValuesForSpecificID(ID, iDatabaseConnector) ) { //add the "" for the string this->SetField("Points", this->m_MapRow["Points"]); return true; } return false; } GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBIntensityRow.cxx0000644000175000017500000000713711667757442021726 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBIntensityRow.h" #include "GoDBRecordSetHelper.h" GoDBIntensityRow::GoDBIntensityRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBIntensityRow::~GoDBIntensityRow() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBIntensityRow::InitializeMap() { this->m_TableName = "intensity"; this->m_TableIDName = "IntensityID"; this->m_MapRow["IntensityID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["Value"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["meshID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["ChannelID"] = std::string( "0" );//ConvertToString< int >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBIntensityRow::SaveInDB(vtkMySQLDatabase *DatabaseConnector) { int IntensityID = this->DoesThisIntensityAlreadyExists(DatabaseConnector); if ( IntensityID == -1 ) { IntensityID = AddOnlyOneNewObjectInTable< GoDBIntensityRow >( DatabaseConnector, "intensity", this, "IntensityID"); } return IntensityID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBIntensityRow::DoesThisIntensityAlreadyExists( vtkMySQLDatabase *DatabaseConnector) { std::vector< FieldWithValue > Conditions; this->AddConditions("ChannelID", Conditions); this->AddConditions("meshID", Conditions); return FindOneID(DatabaseConnector, "intensity", "IntensityID", Conditions); } GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBTrackFamilyRow.cxx0000644000175000017500000000770511667757442022147 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBTrackFamilyRow.h" #include "GoDBRecordSetHelper.h" GoDBTrackFamilyRow::GoDBTrackFamilyRow() : GoDBRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBTrackFamilyRow::GoDBTrackFamilyRow(unsigned int iExistingID, vtkMySQLDatabase* iDatabaseConnector) { this->InitializeMap(); this->SetValuesForSpecificID(iExistingID, iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBTrackFamilyRow::InitializeMap() { this->m_TableName = "trackfamily"; this->m_TableIDName = "TrackFamilyID"; this->m_MapRow["TrackFamilyID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["TrackIDMother"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["TrackIDDaughter1"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["TrackIDDaughter2"] = std::string( "0" );//ConvertToString< int >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBTrackFamilyRow::SaveInDB(vtkMySQLDatabase *DatabaseConnector) { int TrackFamilyID = this->DoesThisTrackFamilyAlreadyExists(DatabaseConnector); if ( TrackFamilyID == -1 ) { TrackFamilyID = AddOnlyOneNewObjectInTable< GoDBTrackFamilyRow >( DatabaseConnector, "trackfamily", *this, "TrackFamilyID"); } return TrackFamilyID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBTrackFamilyRow::DoesThisTrackFamilyAlreadyExists( vtkMySQLDatabase *DatabaseConnector) { std::vector< FieldWithValue > Conditions; this->AddConditions("TrackIDMother", Conditions); return FindOneID(DatabaseConnector, this->m_TableName, this->m_TableIDName, Conditions); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBAuthorRow.h0000644000175000017500000000502111667757442020615 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBAuthorRow_h #define __GoDBAuthorRow_h #include #include #include #include #include "GoDBRow.h" #include "ConvertToStringHelper.h" /** \class GoDBAuthorRow \brief manages a map with keys matching fields of the gofiguredatabase Author table and values of the map matching a row of the Author table \ingroup DB */ class QGOIO_EXPORT GoDBAuthorRow:public GoDBRow { public: GoDBAuthorRow(); ~GoDBAuthorRow() {} int SaveInDB(vtkMySQLDatabase *DatabaseConnector); /**\brief check if the author already exists in the database, if yes, return the corresponding ID, if not, return -1*/ int DoesThisAuthorAlreadyExists(vtkMySQLDatabase *DatabaseConnector); protected: virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBContourRow.h0000644000175000017500000000777211667757442021023 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBContourRow_h #define __GoDBContourRow_h #include "ConvertToStringHelper.h" #include "GoDBTraceRow.h" #include "GoFigureMeshAttributes.h" #include #include /** \class GoDBContourRow \brief this class manages the map with the keys matching the fields of the Contour gofiguredatabase table and values of the map matching a row of the Contour table \ingroup DB */ class QGOIO_EXPORT GoDBContourRow:public GoDBTraceRow { public: GoDBContourRow(); ~GoDBContourRow() {} /** \brief fill the contour map with the values gotten from the visualization \param[in] DatabaseConnector connection to the database \param[in] TraceVisu vtkPolyData the points will be extracted from to create a string for "Points" \param[in] Min coordinate row for the minimum of the bounding box \param[in] Max coordinate row for the maximum of the bounding box \param[in] ImgSessionID ID of the current imagingsession */ GoDBContourRow(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID); //constructor in GoDBTraceRow GoDBContourRow(unsigned int ImagingSessionID); //constructor in GoDBTraceRow GoDBContourRow(unsigned int iExistingID,vtkMySQLDatabase *iDatabaseConnector); /**\brief fill the contour map with the values gotten from the visualization*/ /* GoDBContourRow(vtkMySQLDatabase* DatabaseConnector,GoDBCoordinateRow Min, GoDBCoordinateRow Max,unsigned int ImgSessionID,vtkPolyData* TraceVisu);*/ /**\brief return the ContourID of the Contour with the same bounding box already registered in the DB or -1 if not yet created*/ //int DoesThisBoundingBoxContourExist(vtkMySQLDatabase* DatabaseConnector); //mother class method virtual int SaveInDB(vtkMySQLDatabase *DatabaseConnector); //void SetCollectionID(int iCollectionID); //void ReInitializeMapAfterCast(); void SetTheDataFromTheVisu(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow Min, GoDBCoordinateRow Max); //GoDBCoordinateRow Min, GoDBCoordinateRow Max, GoFigureMeshAttributes* // iMeshAttributes = 0); protected: //mother class method virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBImgSessionRow.cxx0000644000175000017500000000762711667757442022024 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBImgSessionRow.h" #include "SelectQueryDatabaseHelper.h" GoDBImgSessionRow::GoDBImgSessionRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBImgSessionRow::InitializeMap() { this->m_MapRow["ImagingSessionID"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["CoordIDMax"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["CoordIDMin"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["Name"] = ""; this->m_MapRow["Description"] = ""; this->m_MapRow["ImagesTimeInterval"] = std::string( "0" );//ConvertToString< float >(0); this->m_MapRow["RealPixelDepth"] = std::string( "0" );//ConvertToString< float >(0); this->m_MapRow["RealPixelHeight"] = std::string( "0" );//ConvertToString< float >(0); this->m_MapRow["RealPixelWidth"] = std::string( "0" );//ConvertToString< float >(0); this->m_MapRow["ProjectName"] = ""; this->m_MapRow["MicroscopeName"] = ""; this->m_MapRow["CreationDate"] = ""; this->m_MapRow["XImageSize"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["YImageSize"] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["XTileOverlap"] = std::string( "0" );//ConvertToString< float >(0); this->m_MapRow["YTileOverlap"] = std::string( "0" );//ConvertToString< float >(0); this->m_MapRow["ZTileOverlap"] = std::string( "0" );//ConvertToString< float >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBImgSessionRow::DoesThisImagingSessionExist( vtkMySQLDatabase *DatabaseConnector) { //std::string MicroscopeName = this->GetMapValue("MicroscopeName"); //std::string CreationDate = this->GetMapValue("CreationDate"); std::vector< FieldWithValue > Conditions; this->AddConditions("MicroscopeName", Conditions); this->AddConditions("CreationDate", Conditions); return FindOneID(DatabaseConnector, "imagingsession", "ImagingSessionID", Conditions); } GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBContourRow.cxx0000644000175000017500000001532311667757442021365 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBContourRow.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBRecordSetHelper.h" #include "vtkPolyDataMySQLContourWriter.h" #include "vtkSmartPointer.h" #include GoDBContourRow::GoDBContourRow() : GoDBTraceRow() { this->InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBContourRow::GoDBContourRow(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID) : //GoDBTraceRow(DatabaseConnector, TraceVisu, Min, Max, ImgSessionID) GoDBTraceRow() { this->InitializeMap(); this->SetImgSessionID(ImgSessionID); this->SetTheDataFromTheVisu(DatabaseConnector, TraceVisu, Min, Max); if ( this->DoesThisBoundingBoxExist(DatabaseConnector) ) { std::cout << "The bounding box already exists for this contour" << std::endl; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBContourRow::GoDBContourRow(unsigned int ImagingSessionID) : GoDBTraceRow() { this->InitializeMap(); this->SetImgSessionID(ImagingSessionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBContourRow::GoDBContourRow(unsigned int iExistingID, vtkMySQLDatabase *iDatabaseConnector) : GoDBTraceRow() { this->InitializeMap(); this->SetValuesForSpecificID(iExistingID, iDatabaseConnector); } /*GoDBContourRow::GoDBContourRow(vtkMySQLDatabase* DatabaseConnector, GoDBCoordinateRow Min, GoDBCoordinateRow Max,unsigned int ImgSessionID, vtkPolyData* TraceVisu): GoDBTraceRow(DatabaseConnector,TraceVisu,Min,Max, ImgSessionID) { this->InitializeMap(); if (this->DoesThisBoundingBoxExist(DatabaseConnector)) { std::cout<<"The bounding box already exists for this contour"<m_TableName = "contour"; this->m_TableIDName = "contourID"; this->m_CollectionName = "mesh"; this->m_CollectionIDName = "meshID"; this->m_MapRow[this->m_TableIDName] = std::string( "0" );//ConvertToString< int >(0); this->m_MapRow["meshID"] = std::string( "0" );//ConvertToString< int >(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBContourRow::SaveInDB(vtkMySQLDatabase *DatabaseConnector) { return this->SaveInDBTemplate< GoDBContourRow >(DatabaseConnector, this); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*void GoDBContourRow::SetCollectionID(int iCollectionID) { this->SetField< int >("meshID", iCollectionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBContourRow::ReInitializeMapAfterCast() { GoDBContourRow::InitializeMap(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoDBContourRow::SetTheDataFromTheVisu( vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow Min, GoDBCoordinateRow Max) { GoDBTraceRow::SetTheDataFromTheVisu(DatabaseConnector, TraceVisu, Min, Max); if ( this->DoesThisBoundingBoxExist(DatabaseConnector) ) { std::cout << "The bounding box already exists for this mesh" << std::endl; } }*/ //------------------------------------------------------------------------- void GoDBContourRow::SetTheDataFromTheVisu(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow iCoordMin, GoDBCoordinateRow iCoordMax) { /*this->SetTheBoundingBox(DatabaseConnector, iCoordMin, iCoordMax); vtkSmartPointer< vtkPolyDataMySQLContourWriter > convert = vtkSmartPointer< vtkPolyDataMySQLContourWriter >::New(); std::string PointsString = convert->GetMySQLText(TraceVisu); std::cout << "output string: " << PointsString << std::endl; this->SetField("Points", PointsString); if ( this->DoesThisBoundingBoxExist(DatabaseConnector) ) { std::cout << "The bounding box already exists for this mesh" << std::endl; }*/ this->SetTheDataFromTheVisuTemplate< vtkPolyDataMySQLContourWriter >( DatabaseConnector, TraceVisu, iCoordMin, iCoordMax); } GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBChannelRow.h0000644000175000017500000000505111667757442020726 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBChannelRow_h #define __GoDBChannelRow_h #include #include #include #include #include "GoDBRow.h" #include "ConvertToStringHelper.h" /** \class GoDBChannelRow \brief manages a map with keys matching fields of the gofiguredatabase Channel table and values of the map matching a row of the Channel table \ingroup DB */ class QGOIO_EXPORT GoDBChannelRow:public GoDBRow { public: GoDBChannelRow(); // : GoDBRow() ~GoDBChannelRow() {} int SaveInDB(vtkMySQLDatabase *DatabaseConnector); /**\brief check if the channel already exists in the database, if yes, return the corresponding ID, if not, return -1*/ int DoesThisChannelAlreadyExists(vtkMySQLDatabase *DatabaseConnector); protected: virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBColorRow.h0000644000175000017500000000505111667757442020434 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBColorRow_h #define __GoDBColorRow_h #include #include #include #include #include "GoDBNameDescRow.h" #include "ConvertToStringHelper.h" #include "vtkMySQLDatabase.h" /** \class GoDBColorRow \brief this class manages the map with the keys matching the fields of the Color gofiguredatabase table and values of the map matching a row of the Color table \ingroup DB */ class QGOIO_EXPORT GoDBColorRow:public GoDBNameDescRow { public: GoDBColorRow(); ~GoDBColorRow() {} //mother class method virtual int SaveInDB(vtkMySQLDatabase *iDatabaseConnector); //mother class method virtual int DoesThisEntityAlreadyExists(vtkMySQLDatabase *iDatabaseConnector); protected: //mother class method virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBTrackRow.h0000644000175000017500000001016311667757442020422 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBTrackRow_h #define __GoDBTrackRow_h #include "ConvertToStringHelper.h" #include "GoDBTraceRow.h" #include "vtkMySQLDatabase.h" #include #include /** \class GoDBTrackRow \brief this class manages the map with the keys matching the fields of the Track gofiguredatabase table and values of the map matching a row of the Track table \ingroup DB */ class QGOIO_EXPORT GoDBTrackRow:public GoDBTraceRow { public: GoDBTrackRow(); ~GoDBTrackRow() {} /** \brief fill the track map with the values gotten from the visualization \param[in] DatabaseConnector connection to the database \param[in] TraceVisu vtkPolyData the points will be extracted from to create a string for "Points" \param[in] Min coordinate row for the minimum of the bounding box \param[in] Max coordinate row for the maximum of the bounding box \param[in] ImgSessionID ID of the current imagingsession */ GoDBTrackRow(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TraceVisu, GoDBCoordinateRow Min,GoDBCoordinateRow Max, unsigned int ImgSessionID); GoDBTrackRow(vtkMySQLDatabase *DatabaseConnector,GoDBCoordinateRow Min, GoDBCoordinateRow Max, unsigned int ImgSessionID,std::string iPoints); /** \param[in] ImagingSessionID current imagingsession the track belongs to */ GoDBTrackRow(unsigned int ImagingSessionID); //constructor GoDBTraceRow GoDBTrackRow(unsigned int iExistingID,vtkMySQLDatabase *iDatabaseConnector); //mother class method void SetTheDataFromTheVisu(vtkMySQLDatabase *DatabaseConnector, vtkPolyData *TrackVisu, GoDBCoordinateRow iCoordMin, GoDBCoordinateRow iCoordMax); /** \brief convert the iTrackVisu into a string and set the field 'points' of the map \param[in] iTrackVisu vtkPolyData the points will be extracted from to create a string for "Points" */ void SetThePointsFromPolydata(vtkPolyData * iTrackVisu); /** \brief \return the TrackID of the Track with the same bounding box already registered in the DB or -1 if not yet created */ int DoesThisBoundingBoxTrackExist(vtkMySQLDatabase *DatabaseConnector); //mother class method virtual int SaveInDB(vtkMySQLDatabase *DatabaseConnector); protected: //mother class method virtual void InitializeMap(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRow/GoDBRow.h0000644000175000017500000001553411667757442017444 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBRow_h #define __GoDBRow_h #include "ConvertToStringHelper.h" #include "vtkMySQLDatabase.h" #include #include #include #include #include "QGoIOConfigure.h" #include "SelectQueryDatabaseHelper.h" #include "QueryDataBaseHelper.h" /** \class GoDBRow \brief abstract class manages a map with keys matching fields of a gofiguredatabase table and values of the map matching a row of a gofiguredatabase table \ingroup DB */ class QGOIO_EXPORT GoDBRow { public: typedef std::map< std::string, std::string > StringMapType; typedef StringMapType::iterator StringMapIterator; typedef StringMapType::const_iterator StringMapConstIterator; GoDBRow(); virtual ~GoDBRow(); /** \brief convert the value into a string and assign it to the key in the map \param[in] key key of the map \param[in] value value to be assigned to key \tparam T type of the value, anything but string */ template< typename T > void SetField(const std::string& key, const T& value) { StringMapIterator it = m_MapRow.find(key); if ( it != m_MapRow.end() ) { it->second = ConvertToString< T >(value); } else { std::cerr << "This field does not exist!!!" << std::endl; } } /** \brief set value as the value of map[key] after having put " at the beginning and at the end of the string, as value is a string and it will be needed for the database queries. map[key] = " "value" " \param[in] key key of the map \param[in] value value to be assigned to key which is a string */ void SetField(const std::string& key, const std::string& value); /** \brief \return the table name */ std::string GetTableName(); /** \brief \return the tableID name */ std::string GetTableIDName(); /** \brief put all the values of the map in a string separated by ',' \return all the map values separated by ',' but without a ',' at the end of the string */ std::string PrintValues(); /** \brief put all the keys of the map in a string separated by ',' \return all the map keys separated by ',' but without a ',' at the end of the string */ std::string PrintColumnNames(); std::vector< std::string > PrintColumnsAndValues(); /** \brief put all the keys of the map in a vector \return all the map keys in a vector */ std::vector< std::string > GetVectorColumnNames(); /** \brief put all the keys and values of the map in a string as map[key] = value separated by ',' \return all the map [key] = value separated by ',' but without a ',' at the end of the string */ std::string PrintColumnNamesWithValues(); /** \brief \return the iterator at the beginning of the class map as a const */ StringMapConstIterator ConstMapBegin(); /** \brief \return the iterator at the end of the class map as a const */ StringMapConstIterator ConstMapEnd(); /** \brief \return the iterator at the beginning of the class map */ StringMapIterator MapBegin(); /** \brief \return the iterator at the end of the class map */ StringMapIterator MapEnd(); /** \brief return the value for the field map[key] after having removed the " at the beginning and at the end of the value if it is a string in order to get the original value. \param[in] key key of the map for which the value is needed \return the corresponding value without "" if the value was a string */ std::string GetMapValue(const std::string& key); template T GetMapValue(const std::string& key) { std::string Value = this->GetMapValue(key); return ss_atoi(Value); } /** \brief print the keys and values of the map in a cout \param[in,out] os \param[in,out] c the row to print */ friend std::ostream & operator<<(std::ostream & os, const GoDBRow & c) { for ( StringMapConstIterator it = c.m_MapRow.begin(); it != c.m_MapRow.end(); ++it ) { os << it->first << " = " << it->second << std::endl; } return os; } /** \brief get the data from the database corresponding to the specific ID and put them in the map \param[in] ID ID for which the data are needed \param[in] iDatabaseConnector connection to the database \return false if the ID hasn't been found in the database */ virtual bool SetValuesForSpecificID(int ID, vtkMySQLDatabase *iDatabaseConnector); /** \brief delete from the database the row which has the same TableID \param[in] iDatabaseConnector connection to the database */ void DeleteFromDB(vtkMySQLDatabase *iDatabaseConnector); protected: /** \brief virtual pure. initialize all the values of the map */ virtual void InitializeMap() = 0; /** \brief add as an element of ioFieldWithValue the name and value of the map with the key iNameOfField \param[in] iNameOfField key of the map \param[in,out] ioFieldWithValue vector of FieldWithValue */ void AddConditions(const std::string& iNameOfField, std::vector& ioFieldWithValue); StringMapType m_MapRow; std::string m_TableName; std::string m_TableIDName; }; #endif GoFigure2-v0.9.0/Code/IO/GoDBRecordSetHelper.h0000644000175000017500000000751011667757442020457 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBRecordSetHelper_h #define __GoDBRecordSetHelper_h #include "GoDBRecordSet.h" #include "QueryDataBaseHelper.h" #include "SelectQueryDatabaseHelper.h" /** \brief help add a new object of type T in the table "TableName" in the database: add a new ImagingSession, new Image, new Mesh... \param[in] DatabaseConnector \param[in] TableName \param[in] myNewObject */ template< class T > void AddOnlyOneNewObjectInTable(vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, T & myNewObject) { typedef GoDBRecordSet< T > SetType; SetType mySet; mySet.SetConnector(DatabaseConnector); mySet.SetTableName(TableName); mySet.AddObject(myNewObject); mySet.SaveInDB(); } template< class T > int AddOnlyOneNewObjectInTable(vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, T & myNewObject, const std::string IDColumnName) { typedef GoDBRecordSet< T > SetType; SetType mySet; mySet.SetConnector(DatabaseConnector); mySet.SetTableName(TableName); mySet.AddObject(myNewObject); mySet.SaveInDB(); return MaxValueForOneColumnInTable(DatabaseConnector, IDColumnName, TableName); } template< class T > int AddOnlyOneNewObjectInTable(vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, T *myNewObject, const std::string IDColumnName) { typedef GoDBRecordSet< T > SetType; SetType mySet; mySet.SetConnector(DatabaseConnector); mySet.SetTableName(TableName); mySet.AddObject(*myNewObject); mySet.SaveInDB(); return MaxValueForOneColumnInTable(DatabaseConnector, IDColumnName, TableName); } template< class T > int UpdateOneNewObjectInTable(vtkMySQLDatabase *DatabaseConnector, T *myNewObject) { typedef GoDBRecordSet< T > SetType; SetType mySet; mySet.SetConnector(DatabaseConnector); mySet.SetTableName( myNewObject->GetTableName() ); mySet.AddObject(*myNewObject); mySet.SaveInDB(true); return atoi( myNewObject->GetMapValue( myNewObject->GetTableIDName() ).c_str() ); } #endif GoFigure2-v0.9.0/Code/IO/vtkPolyDataMySQLContourWriter.h0000644000175000017500000000562611667757442022636 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkPolyDataMySQLContourWriter_h #define __vtkPolyDataMySQLContourWriter_h #include #include #include "vtkPolyData.h" #include "vtkMath.h" #include "vtkIdList.h" #include "QGoIOConfigure.h" /** \defgroup MySQLWriter MySQLWriter \defgroup Contour Contour \defgroup Trace Trace */ /** \class vtkPolyDataMySQLContourWriter \brief Reads a string and convert it into a contour polydata \ingroup MySQLWriter Contour Trace */ class QGOIO_EXPORT vtkPolyDataMySQLContourWriter:public vtkObject { public: /* * \brief Public constructor */ static vtkPolyDataMySQLContourWriter * New(); vtkTypeRevisionMacro(vtkPolyDataMySQLContourWriter, vtkObject); /* * \brief Generate a string from a contour polydata * \param[in] iPolyData Polydata to generate the string * \return string containing the contour polydata information */ std::string GetMySQLText(vtkPolyData *iPolyData); protected: vtkPolyDataMySQLContourWriter(); ~vtkPolyDataMySQLContourWriter(); private: vtkPolyDataMySQLContourWriter(const vtkPolyDataMySQLContourWriter &); void operator=(const vtkPolyDataMySQLContourWriter &); }; #endif GoFigure2-v0.9.0/Code/IO/GoFigureFileInfoMultiIndexContainerHelper.h0000644000175000017500000001760411667757442025067 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoFigureFileInfoMultiIndexContainerHelper_h #define __GoFigureFileInfoMultiIndexContainerHelper_h #include "boost/multi_index_container.hpp" #include "boost/multi_index/member.hpp" #include "boost/multi_index/ordered_index.hpp" #include #include #include #include #include #include #include #include #include "QGoIOConfigure.h" struct QGOIO_EXPORT GoFigureFileInfoHelper { unsigned int m_PCoord; unsigned int m_RCoord; unsigned int m_CCoord; unsigned int m_XTileCoord; unsigned int m_YTileCoord; unsigned int m_ZTileCoord; unsigned int m_XCoord; unsigned int m_YCoord; unsigned int m_ZCoord; unsigned int m_TCoord; unsigned int m_Channel; std::string m_Filename; GoFigureFileInfoHelper(const unsigned int & p, const unsigned int & r, const unsigned int & c, const unsigned int & xt, const unsigned int & yt, const unsigned int & zt, const unsigned int & xs, const unsigned int & ys, const unsigned int & zs, const unsigned int & t, const unsigned int & ch, const std::string & iFile): m_PCoord(p), m_RCoord(r), m_CCoord(c), m_XTileCoord(xt), m_YTileCoord(yt), m_ZTileCoord(zt), m_XCoord(xs), m_YCoord(ys), m_ZCoord(zs), m_TCoord(t), m_Channel(ch), m_Filename(iFile) {} GoFigureFileInfoHelper():m_PCoord(0), m_RCoord(0), m_CCoord(0), m_XTileCoord(0), m_YTileCoord(0), m_ZTileCoord(0), m_XCoord(0), m_YCoord(0), m_ZCoord(0), m_TCoord(0), m_Channel(0), m_Filename("") {} ~GoFigureFileInfoHelper() {} }; #ifndef DOXYGEN_SHOULD_SKIP_THIS struct m_PCoord {}; struct m_RCoord {}; struct m_CCoord {}; struct m_XTileCoord {}; struct m_YTileCoord {}; struct m_ZTileCoord {}; struct m_XCoord {}; struct m_YCoord {}; struct m_ZCoord {}; struct m_TCoord {}; struct m_Channel {}; #endif /** \todo (Arnaud) Since we are not yet using all information * the unused one are commented for performance issues * (PCoord, RCoord, CCoord, XTileCoord, YTileCoord, ZTileCoord) */ typedef boost::multi_index::multi_index_container< GoFigureFileInfoHelper, boost::multi_index::indexed_by< boost::multi_index::ordered_non_unique< boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper,unsigned int,m_PCoord) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper,unsigned int,m_RCoord) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper,unsigned int,m_CCoord) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper,unsigned int,m_XTileCoord) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper,unsigned int,m_YTileCoord) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper,unsigned int,m_ZTileCoord) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< m_ZCoord >, BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper, unsigned int, m_ZCoord) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< m_Channel >, BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper, unsigned int, m_Channel) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< m_TCoord >, BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper, unsigned int, m_TCoord) > > > GoFigureFileInfoHelperMultiIndexContainer; typedef boost::multi_index::multi_index_container< const GoFigureFileInfoHelper *, boost::multi_index::indexed_by< boost::multi_index::ordered_non_unique< BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper, const unsigned int, m_ZCoord) > > > GoFigureFileInfoHelperZCoordViewContainer; typedef boost::multi_index::multi_index_container< const GoFigureFileInfoHelper *, boost::multi_index::indexed_by< boost::multi_index::ordered_non_unique< BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper, const unsigned int, m_TCoord) > > > GoFigureFileInfoHelperTCoordViewContainer; typedef boost::multi_index::multi_index_container< const GoFigureFileInfoHelper *, boost::multi_index::indexed_by< boost::multi_index::ordered_non_unique< BOOST_MULTI_INDEX_MEMBER(GoFigureFileInfoHelper, const unsigned int, m_Channel) > > > GoFigureFileInfoHelperChannelViewContainer; QGOIO_EXPORT std::map< unsigned int, std::list< std::string > > GetAllFileNamesForGivenTCoord( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const unsigned int & iT, const unsigned int & iMinCh, const unsigned int & iMaxCh ); QGOIO_EXPORT std::map< unsigned int, std::list< std::string > > GetAllFileNamesForGivenZCoord( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const unsigned int & iZ, const unsigned int & iMinCh, const unsigned int & iMaxCh ); QGOIO_EXPORT std::list< std::string > GetAllFileNamesForGivenTCoordAndChannel( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const unsigned int & iT, const unsigned int & iCh ); QGOIO_EXPORT std::list< std::string > GetAllFileNamesForGivenZCoordPointAndChannel( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const unsigned int & iZ, const unsigned int & iCh ); QGOIO_EXPORT std::map< unsigned int, std::list< std::string > > GetAllFileNamesForGivenChannelAndTCoords( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const unsigned int & iCh, const std::set< unsigned int > & iT ); #endif GoFigure2-v0.9.0/Code/IO/ContourMeshStructure.h0000644000175000017500000001274011667757442021121 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __ContourMeshStructure_h #define __ContourMeshStructure_h class vtkActor; class vtkPolyData; class vtkProperty; #include #include #include "QGoIOConfigure.h" #include "TraceStructure.h" #ifndef DOXYGEN_SHOULD_SKIP_THIS #include "StructureHelper.h" #endif /** \defgroup Contour Contour \defgroup Mesh Mesh */ /** * \struct ContourMeshStructure * \brief Structure which represent a contour or a mesh, and used for * interaction between Visualization and TableWidget * \ingroup Contour Mesh Trace * * \sa ContourMeshContainer */ class QGOIO_EXPORT ContourMeshStructure : public TraceStructure { public: //unsigned int CollectionID; /** Time point of the contour / mesh */ unsigned int TCoord; /** \brief Return the direction of a given contour iContour \return 0 if z coordinates are constant \return 1 if y coordinates are constant \return 2 if x coordinates are constant \return -1 else */ int GetDirection(); /** \brief Is it a contour or a mesh ? \return true if it is a contour \return false else */ bool IsAContour(); /** Default Constructor */ ContourMeshStructure(); /** Constructor */ ContourMeshStructure(const unsigned int & iTraceID, const unsigned int & iCollectionID, std::vector< vtkActor * > iActors, vtkPolyData *iNodes, const unsigned int & iT, const bool & iHighlighted, const bool & iVisible, const double & r, const double & g, const double & b, const double & alpha); /** Constructor */ ContourMeshStructure(const unsigned int & iTraceID, const unsigned int & iCollectionID, std::vector< vtkActor * > iActors, vtkPolyData *iNodes, const unsigned int & iT, const bool & iHighlighted, const bool & iVisible, double iRgba[4]); /** Constructor */ ContourMeshStructure(const unsigned int & iTraceID, const unsigned int & iCollectionID, vtkActor *iActorXY, vtkActor *iActorYZ, vtkActor *iActorXZ, vtkActor *iActorXYZ, vtkPolyData *iNodes, const unsigned int & iT, const bool & iHighlighted, const bool & iVisible, const double & r, const double & g, const double & b, const double & alpha); /** Constructor by copy */ ContourMeshStructure(const ContourMeshStructure & iE); /** Destructor */ ~ContourMeshStructure(); void ModifyCollectionID(unsigned int iCollectionID); /** Printing one element. std::cout << element << std::endl; */ friend std::ostream & operator<< (std::ostream & os, const ContourMeshStructure & c) { os << "TraceID " << c.TraceID << std::endl; os << "ActorXY " << c.ActorXY << std::endl; os << "ActorXZ " << c.ActorXZ << std::endl; os << "ActorYZ " << c.ActorYZ << std::endl; os << "ActorXYZ " << c.ActorXYZ << std::endl; os << "Nodes " << c.Nodes << std::endl; //os << "CollectionID " << c.CollectionID << std::endl; os << "TCoord " << c.TCoord << std::endl; os << "Highlighted " << c.Highlighted << std::endl; os << "Visible " << c.Visible << std::endl; os << "RGBA [" << c.rgba[0] << ", " << c.rgba[1] << ", " << c.rgba[2] << ", " << c.rgba[3] << "]" << std::endl; return os; } }; #endif GoFigure2-v0.9.0/Code/IO/itkMegaCaptureReader.h0000644000175000017500000001076111667757442020763 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkMegaCaptureReader_h #define __itkMegaCaptureReader_h #include "GoFigureGlobalDefinition.h" #include "itkLightProcessObject.h" #include "GoFigureFileInfoMultiIndexContainerHelper.h" #include "MegaCaptureHeaderReader.h" #include "QGoIOConfigure.h" #include "vtkSmartPointer.h" class vtkImageData; class vtkImageAppend; namespace itk { class QGOIO_EXPORT MegaCaptureReader:public LightProcessObject { public: /** Standard class typedefs. */ typedef MegaCaptureReader Self; typedef LightProcessObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkNewMacro(Self); itkTypeMacro(MegaCaptureReader, LightProcessObject); /** \brief set the input as a GoFigure format file list */ void SetInput(const GoFigureFileInfoHelperMultiIndexContainer & UserFileList); void SetMegaCaptureHeader(const std::string & iHeader); /** \brief */ itkSetMacro(FileType, GoFigure::FileType); itkSetMacro(TimeBased, bool); void SetTimePoint(const unsigned int & iTm); itkGetConstMacro(UpdateTimePoint, unsigned int); itkGetConstMacro(MinTimePoint, unsigned int); itkGetConstMacro(MaxTimePoint, unsigned int); itkGetConstMacro(TimeInterval, unsigned int); void SetZSlice(const unsigned int & iZs); itkGetConstMacro(UpdateZSlice, unsigned int); itkGetConstMacro(MinZSlice, unsigned int); itkGetConstMacro(MaxZSlice, unsigned int); itkGetConstMacro(MinChannel, unsigned int); itkGetConstMacro(MaxChannel, unsigned int); void Update(); vtkSmartPointer GetOutput(const unsigned int & iChannel); vtkSmartPointer GetImage( const unsigned int & iChannel, const unsigned int & iT ); std::map< unsigned int, vtkImageData * > GetOutputs(); std::vector< std::vector< int > > GetChannelColor(); protected: MegaCaptureReader(); ~MegaCaptureReader(); void ComputeBounds(); void AddToVTKVolumeBuilder( const int& iCounter, const std::string& iFileName, vtkImageAppend * iBuilder ); std::map< unsigned int, vtkImageData * > m_OutputImageMap; GoFigureFileInfoHelperMultiIndexContainer m_FileList; GoFigure::FileType m_FileType; MegaCaptureHeaderReader *m_HeaderReader; std::vector< std::vector< int > > m_ChannelColor; unsigned int m_MinTimePoint; unsigned int m_MaxTimePoint; unsigned int m_UpdateTimePoint; unsigned int m_TimeInterval; unsigned int m_MinZSlice; unsigned int m_MaxZSlice; unsigned int m_UpdateZSlice; unsigned int m_MinChannel; unsigned int m_MaxChannel; bool m_TimeBased; bool m_Modified; private: MegaCaptureReader(const Self &); void operator=(const Self &); }; } #endif GoFigure2-v0.9.0/Code/IO/vtkPolyDataMySQLContourReader.cxx0000644000175000017500000000737711667757442023144 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkPolyDataMySQLContourReader.h" #include "vtkObjectFactory.h" #include "vtkCellArray.h" #include "vtkPolyData.h" #include vtkCxxRevisionMacro(vtkPolyDataMySQLContourReader, "$Revision$"); vtkStandardNewMacro(vtkPolyDataMySQLContourReader); //-------------------------------------------------------------------------- vtkPolyDataMySQLContourReader::vtkPolyDataMySQLContourReader() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyDataMySQLContourReader:: ~vtkPolyDataMySQLContourReader() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer< vtkPolyData > vtkPolyDataMySQLContourReader::GetPolyData(const std::string & iString) { vtkSmartPointer< vtkPolyData > oContour = vtkSmartPointer< vtkPolyData >::New(); vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New(); std::stringstream str(iString); vtkIdType N; // NOTE ALEX: // As expected the problem is here in the Reader .... // the following line takes the first char of the string off // str >> quote >> N; // in the case I m dealing with, there is no characters to skip // Thus resulting dropping the frist 1 of 111 to make it eleven. // great ... str >> N; points->SetNumberOfPoints(N); double pt[3]; for ( vtkIdType i = 0; i < N; i++ ) { str >> pt[0] >> pt[1] >> pt[2]; points->SetPoint(i, pt); } oContour->SetPoints(points); vtkSmartPointer< vtkCellArray > cells = vtkSmartPointer< vtkCellArray >::New(); vtkIdType * ids = new vtkIdType[N + 1]; for ( vtkIdType i = 0; i < N; i++ ) { ids[i] = i; } ids[N] = 0; cells->InsertNextCell(N + 1, ids); oContour->SetLines(cells); delete[] ids; return oContour; } //--------------------------------------------------------------------------GoFigure2-v0.9.0/Code/IO/SelectQueryDatabaseHelper.h0000644000175000017500000007143111667757442021766 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __SelectQueryDatabaseHelper_h #define __SelectQueryDatabaseHelper_h #include #include #include "boost/unordered_map.hpp" #include #include "itkMacro.h" #include "vtkMySQLDatabase.h" #include "vtkSQLQuery.h" #include "GoDBTraceInfoForVisu.h" #include "ContourMeshStructure.h" #include "TrackStructure.h" #include "LineageStructure.h" #include "QueryBuilderHelper.h" #include "ConvertToStringHelper.h" #include "QGoIOConfigure.h" /** \brief SELECT ColumnName from TableName ORDER BY OrderbyColumnName \param[in] DatabaseConnector connection to the database \param[in] ColumnName name of the field in the database \param[in] TableName name of the database table \param{in] OrderByColumnName sorting \return all the values for the column sorted or not */ QGOIO_EXPORT std::vector< std::string > ListAllValuesForOneColumn( vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnName, const std::string & TableName, std::string OrderByColumnName = ""); /** \brief SELECT ColumnNameOne,ColumnNameTwo FROM TableName ORDER BY ColumnName ASC \param[in] DatabaseConnector connection to the database \param[in] ColumnNameOne first value of the pair \param[in] ColumnNameTwo second value of the pair \param[in] TableName name of the database table \param{in] OrderByColumnName sorting \return all the values sorted by OrderByColumnName in a vector of pair */ QGOIO_EXPORT std::vector< std::pair< std::string, std::string > > VectorTwoColumnsFromTable(vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnNameOne, const std::string & ColumnNameTwo, const std::string & TableName, const std::string & OrderByColumnName); /** \brief query: "SELECT ColumnName1, ColumnName2 FROM TableName" \param[in] DatabaseConnector connection to the database \param[in] iColumnNames vector[0] = ColumnName1, vector[1] = ColumnName2 \param[in] iTableName name of the database table \param[in] iField field for the condition if there is one \param[in] iValue value of the condition if there is one \return map[Value from ColumnName1] = Value from ColumnName2 */ QGOIO_EXPORT boost::unordered_map< std::string, std::string > MapTwoColumnsFromTable( vtkMySQLDatabase *DatabaseConnector, const std::vector & iColumnNames, const std::string & iTableName, std::string iField = "", std::string iValue = ""); /** \brief SELECT * FROM TableName WHERE field = value */ //if field is a primary key, will return only the values for //one row //not used QGOIO_EXPORT std::vector< std::string > ListSpecificValuesForRow( vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, const std::string & field, const std::string & value); /** \brief SELECT ColumnName FROM TableName WHERE field = value \param[in] DatabaseConnector connection to the database \param[in] TableName name of the database table \param[in] ColumnName name of the field in the database \param[in] field field for the condition \param[in] value value of the condition \return only one ID */ QGOIO_EXPORT int FindOneID(vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::string & value); /** \overload \param[in] iConditions vector of fields = values */ QGOIO_EXPORT int FindOneID(vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::vector & iConditions); /** \brief "SELECT ColumnName FROM TableName WHERE (field1 = value1 AND field2 = value2...); \param[in] DatabaseConnector connection to the database \param[in] TableName name of the database table \param[in] ColumnName name of the field in the database \param[in] iConditions vector of fields = values \return all the values in ColumnName that fit the conditions */ QGOIO_EXPORT std::vector< std::string > FindSeveralIDs( vtkMySQLDatabase * iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::vector & iConditions); /** \brief SELECT ColumnName FROM TableName WHERE field = value and ColumnName <> 0 (if excludezero) \param[in] iDatabaseConnector connection to the database \param[in] TableName name of the database table \param[in] ColumnName name of the field in the database \param[in] field field for the condition \param[in] value value of the condition \param[in] distinct set to true if doublon are not allowed \param[in] ExcludeZero set to true if ColumnName has to be different than 0 \return all the values in ColumnName that fit the conditions */ QGOIO_EXPORT std::vector< std::string > ListSpecificValuesForOneColumn( vtkMySQLDatabase *iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::string & value, //bool Distinct = false, bool ExcludeZero = false); /** \brief SELECT ColumnName FROM TableName WHERE field = value ORDER BY ColumnNameOrder ASC \overload \param[in] ColumnNameOrder name of the column for sorting */ QGOIO_EXPORT std::vector< std::string > ListSpecificValuesForOneColumn( vtkMySQLDatabase *iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::string & value, const std::string & ColumnNameOrder); /** \brief SELECT ColumnName FROM TableName WHERE (field = value1 or field = value2 AND ColumnName <> 0 (if excludezero)) \overload */ QGOIO_EXPORT std::vector< std::string > ListSpecificValuesForOneColumn( vtkMySQLDatabase *iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::vector< std::string > & VectorValues, bool Distinct = false, bool ExcludeZero = false); /** \brief SELECT ColumnName FROM TableName WHERE (field = value1 or field = value2 AND ColumnName <> 0 (if excludezero)) \overload */ QGOIO_EXPORT std::list< unsigned int > ListSpecificValuesForOneColumn( vtkMySQLDatabase *iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::list< unsigned int > & ListValues, bool Distinct = false, bool ExcludeZero = false); /** \brief SELECT ColumnName FROM TableName WHERE (field1 = value1 or field = value2 AND fieldTwo = ValueFieldTwo ) \overload */ QGOIO_EXPORT std::list< unsigned int > ListSpecificValuesForOneColumn( vtkMySQLDatabase *iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & fieldOne, const std::list< unsigned int > & ListValuesOne, const std::string & fieldTwo, const std::string & ValueFieldTwo); /** \brief SELECT ColumnNameOne,ColumnName2 FROM TableName WHERE field = value ORDER BY ColumnNameOrder ASC" \param[in] iDatabaseConnector connection to the database \param[in] TableName name of the database table \param[in] ColumnNameOne name of the first field in the database \param[in] ColumnNameTwo name of the second field in the database \param[in] field field for the condition \param[in] value value of the condition \param{in] OrderByColumnName sorting \return a vector of pair with the values of each Column */ QGOIO_EXPORT std::vector< std::pair< std::string, std::string > > ListSpecificValuesForTwoColumns( vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, const std::string & ColumnNameOne, const std::string & ColumnNameTwo, const std::string & field, const std::string & value, const std::string & ColumnNameOrder); /** \brief SELECT MAX(ColumnName) FROM TableName WHERE (field = value1 or field = value2...." \param[in] DatabaseConnector connection to the database \param[in] TableName name of the database table \param[in] ColumnName name of the field in the database \param[in] field field for the condition \param[in] VectorValues values of the condition \return the max value */ QGOIO_EXPORT int MaxValueForOneColumnInTable( vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnName, const std::string & TableName, const std::string & field, const std::vector< std::string > & VectorValues); /** \brief SELECT MAX(ColumnName) FROM TableName \overload */ QGOIO_EXPORT int MaxValueForOneColumnInTable( vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnName, const std::string & TableName); /** \brief SELECT MAX(ColumnName) FROM TableName WHERE field = value \overload */ QGOIO_EXPORT int MaxValueForOneColumnInTable( vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnName, const std::string & TableName, const std::string & field, const std::string & value); /** \brief SELECT MIN(ColumnName) FROM TableName WHERE (field = value1 or field = value2...." \param[in] DatabaseConnector connection to the database \param[in] TableName name of the database table \param[in] ColumnName name of the field in the database \param[in] field field for the condition \param[in] VectorValues values of the condition \return the minimum value */ QGOIO_EXPORT int MinValueForOneColumnInTable( vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnName, const std::string & TableName, const std::string & field, const std::vector< std::string > & VectorValues); /** \brief SELECT ColunmName FROM TableName WHERE field=value limit 1 \param[in] iDatabaseConnector connection to the database \param[in] TableName name of the database table \param[in] ColumnName name of the field in the database \param[in] field field for the condition \param[in] value value of the condition \return only one value if several are selected */ QGOIO_EXPORT std::string ReturnOnlyOneValue( vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::string & value); QGOIO_EXPORT std::vector< std::pair< int, std::string > > ListSpecificValuesForTwoColumnsAndTwoTables( vtkMySQLDatabase *DatabaseConnector, const std::string & TableOne, const std::string & ColumnOne, const std::string & TableTwo, const std::string & ColumnTwo, const std::string & ForeignKey, const std::string & PrimaryKey, const std::string & field, const std::string & value); /** \brief fill the TCoord and the attributes of the structure obtained from Points \param[in] ioStructure structure to be modified with TCoord and co. \param[in] iTCoord one to be filled with \param[in] iPoints points from which some attributes will be calculated \param[in] iTraceName name of the trace */ QGOIO_EXPORT void ModifyStructureWithSpecificities( ContourMeshStructure & ioStructure, unsigned int iTCoord, const std::string & iPoints, const std::string & iTraceName); /** \overload */ QGOIO_EXPORT void ModifyStructureWithSpecificities( TrackStructure & ioStructure, unsigned int iTCoord, const std::string & iPoints, const std::string & iTraceName); /** \overload */ QGOIO_EXPORT void ModifyStructureWithSpecificities( LineageStructure & ioStructure, unsigned int iTrackRootID, const std::string & iPoints, const std::string & iTraceName); /** \brief execute iQueryString and put the results in a list of T structure \param[in] iDatabaseConnector \param[in] iQueryString query to execute \param[in,out] ioListStructure list to be filled with the results of the query \param[in] iTableOne name of the main table (usually a trace name) \tparam ContourMeshStructure or TrackStructure */ template void ExecuteQueryAndModifyListStructure( vtkMySQLDatabase* iDatabaseConnector, const std::string & iQueryString, std::list & ioListStructure, const std::string & iTableOne) { vtkSQLQuery *query = iDatabaseConnector->GetQueryInstance(); query->SetQuery( iQueryString.c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "get info traces query failed" << query->GetLastErrorText() ); iDatabaseConnector->Close(); iDatabaseConnector->Delete(); query->Delete(); return; } while ( query->NextRow() ) { { T temp; temp.TraceID = query->DataValue(0).ToUnsignedInt(); unsigned int SpecifiedValue; if (iTableOne == "lineage") { SpecifiedValue = query->DataValue(1).ToUnsignedInt(); } else { temp.CollectionID = query->DataValue(1).ToUnsignedInt(); SpecifiedValue = query->DataValue(7).ToUnsignedInt(); } ModifyStructureWithSpecificities(temp, SpecifiedValue, query->DataValue(6).ToString(), iTableOne); /// \note For the visualization rgba values are supposed to be double in /// between 0 and 1; whereas in the database these values are in between /// 0 and 255. temp.rgba[0] = ( query->DataValue(2).ToDouble() ) / 255.; temp.rgba[1] = ( query->DataValue(3).ToDouble() ) / 255.; temp.rgba[2] = ( query->DataValue(4).ToDouble() ) / 255.; temp.rgba[3] = ( query->DataValue(5).ToDouble() ) / 255.; //ModifyStructureWithTCoordAndPoints(temp, query->DataValue(7).ToUnsignedInt(), // query->DataValue(6).ToString(), iTableOne); ioListStructure.push_back(temp); } } query->Delete(); } /** \brief select iselectedattributes from (tableone left join tabletwo ijoinconditionone) left join tablethree ijoinconditiontwo where (ifieldone = ivaluefieldone and (iIDfieldname = ivectids1 or ivectids2...) ); \param[in] iDatabaseConnector connection to the database \param[in,out] ioListStructure list of Structure to be filled \param[in] iSelectedAttributes vector of all the attributes to be fetched from the db \param[in] iTableOne main table involved (usually the table for the trace) \param[in] iTableTwo table attached to the main table \param[in] iTableThree table attached to the main table \param[in] iJoinConditionOne describes how the tabletwo is attached to the main table \param[in] iJoinConditionTwo describes how the tablethree is attached to the main table \param[in] iFieldOne first condition \param[in] iValueFieldOne value for the first condition \param[in] iIDFieldName field for the IDName where there is a condition \param[in] iListIDs values for the iIDFieldname */ template void GetInfoFromDBAndModifyListStructure( std::list< T > & ioListStructure, vtkMySQLDatabase *iDatabaseConnector, const std::vector & iSelectedAttributes, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iTableThree, const FieldWithValue & iJoinConditionOne, const FieldWithValue & iJoinConditionTwo, const std::string & iFieldOne, unsigned int iValueFieldOne, const std::string & iIDFieldName, const std::list< unsigned int > & iListIDs) { std::string QueryString = SelectForTracesInfo(iSelectedAttributes, iTableOne, iTableTwo, iTableThree, iJoinConditionOne, iJoinConditionTwo, iFieldOne, iValueFieldOne, iIDFieldName, iListIDs); ExecuteQueryAndModifyListStructure( iDatabaseConnector, QueryString, ioListStructure, iTableOne); } //return a pair with the number of fields in the query and a vector of the // results: QGOIO_EXPORT std::vector< std::vector< std::string > > GetValuesFromSeveralTables( vtkMySQLDatabase *DatabaseConnector, const std::string & MainTable, const std::vector< std::string > & SelectFields, const std::string & field, const std::string & value, const std::vector< std::string > & JoinTablesOnTraceTable, bool Distinct); //return a pair with the number of fields in the query and a vector of the // results, //the query includes the where conditions from the vector as AND conditions: QGOIO_EXPORT std::vector< std::vector< std::string > > GetValuesFromSeveralTables( vtkMySQLDatabase *DatabaseConnector, const std::string & MainTable, const std::vector< std::string > & SelectFields, const std::vector< std::string > & WhereAndConditions, const std::vector< std::string > & JoinTablesOnTraceTable, bool Distinct); std::vector< std::vector< std::string > > GetValuesFromSeveralTables( vtkMySQLDatabase *DatabaseConnector, const std::string & MainTable, const std::vector< std::string > & SelectFields, const std::string & field, const std::string & value, const std::vector< std::string > & JoinTablesOnTraceTable, bool Distinct, const std::vector & iWhereOrConditions); //query: SELECT where condition1 UNION SELECT where condition1 and condition2 QGOIO_EXPORT std::vector< std::string > GetSamefieldFromTwoTables( vtkMySQLDatabase *DatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const std::string & iField, const std::string & iValue, const std::string & iFieldTwo, const std::vector< std::string > & iListConditionsTwo); //query: SELECT iColumnOne FROM TableOne WHERE...UNION SELECT iColumnTwo FROM // TableOne... //UNION SELECT iColumnOne FROM TableTwo WHERE....UNION SELECT iColumnTwo FROM // TableTwo WHERE. QGOIO_EXPORT std::vector< std::string > GetSamefieldsFromTwoTables(vtkMySQLDatabase *DatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumnOne, const std::string & iColumnTwo, const std::string & iField, const std::string & iValue); //query: select distinct iColumnOne FROM TableOne where ifield = listconditions union select //distinct icolumntwo from tableOne left join tabletwo on iOnCondition where ifield = listconditions QGOIO_EXPORT std::list< unsigned int > GetTwoFieldsFromTwoTables( vtkMySQLDatabase *DatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const FieldWithValue & iOnCondition, const std::string & iColumnOne, const std::string & iColumnTwo, const std::string & iField, const std::vector< std::string > & iListValues, bool Distinct); //query: SELECT iColumnOne FROM TableOne WHERE...UNION SELECT iColumnTwo FROM // TableOne... //UNION SELECT iColumnOne FROM TableTwo WHERE listconditions2.... //UNION SELECT iColumnTwo FROM TableTwo WHERE listconditions2. QGOIO_EXPORT std::vector< std::string > GetSamefieldsFromTwoTables(vtkMySQLDatabase *DatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumnOne, const std::string & iColumnTwo, const std::string & iField, const std::string & iValue, const std::string & iFieldTwo, const std::vector< std::string > & iListConditionsTwo); QGOIO_EXPORT std::vector< std::string > GetSameFieldsFromSeveralTables(vtkMySQLDatabase *DatabaseConnector, const std::vector< std::string > & iColumnNames, const std::vector< std::string > & iVectorTablesNames, const std::vector< std::string > & iVectorConditionFieldNames, const std::vector< std::vector< std::string > > & iVectorConditionsValues); //query: SELECT iColumnName FROM TableName WHERE ( (iFieldOne = // iVectorConditionFieldOne(i) // OR iFieldOne = iVectorConditionFieldOne(i+1...) AND (iFieldTwo = // iVectorConditionFieldTwo(j) OR //iVectorConditionFieldTwo(j+1)... ) ); QGOIO_EXPORT std::vector< std::string > GetSpecificValueFromOneTableWithConditionsOnTwoColumns( vtkMySQLDatabase *DatabaseConnector, const std::string & iColumnName, const std::string & iTableName, const std::string & iFieldOne, const std::vector< std::string > & iVectorConditionFieldOne, const std::string & iFieldTwo, const std::vector< std::string > &iVectorConditionFieldTwo); //Select t1 from (select mesh.meshid,coordinate.zcoord from mesh left join // coordinate //on mesh.coordidmax = coordinate.coordid where( imagingsessionid = 2 and //coordinate.zcoord > 20) ) AS t1 INNER JOIN //(select mesh.meshid,coordinate.zcoord from mesh left join //coordinate on mesh.coordidmin = coordinate.coordid //where ( imagingsessionid = 2 and coordinate.zcoord < 20) ) //AS t2 on t1.meshid = t2.meshid; QGOIO_EXPORT std::list< unsigned int > GetColumnForBoundedValue(const std::string & iColumnName, const std::string & TableName, const std::string & iImgSessionID, const std::string & iCoordType, const std::string & iValue, vtkMySQLDatabase *DatabaseConnector); QGOIO_EXPORT std::list< unsigned int > GetSpecificValuesEqualToZero( vtkMySQLDatabase *iDatabaseConnection, const std::string & iColumnName, const std::string & iTableName, const std::vector< std::string > & iVectorConditionFieldOne, const std::string & iFieldTwo); template inline TResultsQuery ExecuteSelectQuery(vtkMySQLDatabase *iDatabaseConnector, const std::string & iQuery) { // std::cout << "execute query:" << iQuery << std::endl; vtkSQLQuery *query = iDatabaseConnector->GetQueryInstance(); TResultsQuery oResults; typedef typename TResultsQuery::value_type ValueType; query->SetQuery( iQuery.c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "Execute select query failed" << query->GetLastErrorText() ); iDatabaseConnector->Close(); iDatabaseConnector->Delete(); query->Delete(); return oResults; } int NumberOfFields = query->GetNumberOfFields(); while ( query->NextRow() ) { for ( int k = 0; k < NumberOfFields; k++ ) { ValueType temp = ss_atoi(query->DataValue(k).ToString()); oResults.push_back( temp ); } } query->Delete(); return oResults; } template T ExecuteSelectQueryOneValue(vtkMySQLDatabase *iDatabaseConnector, const std::string & iQuery) { vtkSQLQuery *query = iDatabaseConnector->GetQueryInstance(); T oResults = ss_atoi("-1"); query->SetQuery( iQuery.c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "Execute select query failed" << query->GetLastErrorText() ); iDatabaseConnector->Close(); iDatabaseConnector->Delete(); query->Delete(); return oResults; } if ( query->NextRow() ) { oResults = ss_atoi(query->DataValue(0).ToString() ); } query->Delete(); return oResults; } // WHERE (iWhereAndConditions[i] = iWhereAndConditions[i+1] and/or ....) //if only 1 condition: WHERE iWhereAndConditions[i] = iWhereAndConditions[i+1] QGOIO_EXPORT std::string WhereAndOrConditions( const std::vector & iWhereAndConditions, bool iAnd = true); QGOIO_EXPORT std::list GetAllSelectedValuesFromTwoTables( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::vector & iFieldsWithValues, bool Distinct = false); QGOIO_EXPORT std::vector GetAllSelectedValuesFromTwoTables( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::vector & iListAttributes, const FieldWithValue & iJoinCondition, const std::vector & iFieldsWithValues, std::string iConditionConnector = "AND", std::string ColumnNameOrder = ""); QGOIO_EXPORT std::list< unsigned int > GetAllSelectedValuesFromTwoTables( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::string & iField, const std::vector & iVectorValues, bool Distinct = false , bool NonNULLRows = false); QGOIO_EXPORT std::list< unsigned int > GetAllSelectedValuesFromTwoTables( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::string & iField, const std::vector & iVectorValues, const FieldWithValue & iAndCondition); QGOIO_EXPORT std::list GetAllSelectedValuesFromTwoTables( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::vector & iSelectedFields, const FieldWithValue & iJoinCondition, const std::string & iField, const std::string & iValue, bool NonNULLRows); QGOIO_EXPORT std::list< unsigned int > GetDoublonValuesFromTwoTables( vtkMySQLDatabase* iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::string & iField, const std::vector & iVectValues);//, std::string GroupByColumn = ""); QGOIO_EXPORT int GetMaxValueFromTwoTables( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::string & iField, const std::vector & iVectorValues, const FieldWithValue & iAndCondition); //add the selected fields separated by ',' to the ioQueryStream //void GetAllSelectedFields(std::stringstream & ioQueryStream, // std::vector< std::string > iSelectedFields); //select columnname FROM tablename WHERE field = value order by ASC/DESC limit // iNumberLimit QGOIO_EXPORT std::vector< std::string > GetOrderByWithLimit( vtkMySQLDatabase *iDatabaseConnector, const std::string & iColumnName, const std::string & iTableName, const std::string & iField, const std::string & iValue, bool ASC, const std::string & iNumberLimit); QGOIO_EXPORT std::string GetCoordinateValuesQueryString( const std::string & iTableName, const std::string & iField, const std::string & iValue, bool iMin); //get the center of the bounding boxes for tableName with restriction of iField = iValue QGOIO_EXPORT std::list< double* > GetCenterBoundingBoxes( vtkMySQLDatabase *DatabaseConnector, const std::string & iTableName, const std::string & iField, const std::string & iValue); QGOIO_EXPORT std::list GetListValuesFromTwoTablesAndCondition( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::string & iField, const std::vector & iVectorValues, const FieldWithValue & iAndCondition); QGOIO_EXPORT int NumberOfElementForGivenImagingSessionAndTrace( vtkMySQLDatabase *DatabaseConnector, unsigned int iImagingSession, const std::string & iTrace); QGOIO_EXPORT int NumberOfElementForGivenImagingSessionAndTraceForGivenTimePoint( vtkMySQLDatabase *DatabaseConnector, unsigned int iImagingSession, const std::string & iTrace, int iTimePoint); /* QGOIO_EXPORT int NumberOfTimePointsForGivenImagingSession( vtkMySQLDatabase *DatabaseConnector, unsigned int iImagingSession); */ #endif GoFigure2-v0.9.0/Code/IO/LSMToMegaCapture.cxx0000644000175000017500000002237511667757442020366 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "LSMToMegaCapture.h" #include #include #include #include #include #include #include "vtkImageWriterHelper.h" #include "vtkExtractVOI.h" #include "vtkImageData.h" #include "vtkLSMReader.h" #include "vtkPNGWriter.h" #include "vtkTIFFWriter.h" /** * \brief Constructor */ LSMToMegaCapture::LSMToMegaCapture() : m_Plaque(0), m_Row(0), m_Column(0), m_XTile(0), m_YTile(0), m_ZTile(0) { } /** * \brief Destructor */ LSMToMegaCapture:: ~LSMToMegaCapture() { if ( !m_LSMReaders.empty() ) { for ( unsigned int i = 0; i < m_LSMReaders.size(); i++ ) { m_LSMReaders[i]->Delete(); } } } void LSMToMegaCapture::SetPlaque(const unsigned int & iPlaque) { m_Plaque = iPlaque; } void LSMToMegaCapture::SetRow(const unsigned int & iRow) { m_Row = iRow; } void LSMToMegaCapture::SetColumn(const unsigned int & iCol) { m_Column = iCol; } void LSMToMegaCapture::SetXTile(const unsigned int & iXt) { m_XTile = iXt; } void LSMToMegaCapture::SetYTile(const unsigned int & iYt) { m_YTile = iYt; } void LSMToMegaCapture::SetZTile(const unsigned int & iZt) { m_ZTile = iZt; } void LSMToMegaCapture::SetOutputFileType(const GoFigure::FileType & iFileType) { m_FileType = iFileType; } /** * \brief * \param iFileName */ void LSMToMegaCapture::SetFileName(const std::string & iFileName) { m_FileName = iFileName; size_t point_idx = iFileName.rfind(".lsm"); if ( point_idx != std::string::npos ) { size_t slash_idx = iFileName.rfind('/'); if ( point_idx != std::string::npos ) { m_BaseName = iFileName.substr(slash_idx, point_idx - slash_idx); } else { slash_idx = iFileName.rfind("\\"); if ( point_idx != std::string::npos ) { m_BaseName = iFileName.substr(slash_idx, point_idx - slash_idx); } else { m_BaseName = iFileName.substr(0, point_idx); } } if ( !m_LSMReaders.empty() ) { for ( unsigned int i = 0; i < m_LSMReaders.size(); i++ ) { m_LSMReaders[i]->Delete(); } } m_LSMReaders.push_back( vtkLSMReader::New() ); m_LSMReaders.front()->SetFileName( iFileName.c_str() ); m_LSMReaders.front()->Update(); } } std::vector< vtkLSMReader * > LSMToMegaCapture::GetLSMReaders() { return m_LSMReaders; } /** * \brief Export as MegaCapture * \param[in] iDirectoryPath */ void LSMToMegaCapture::Export(const std::string & iDirectoryPath) { m_NumberOfChannels = m_LSMReaders[0]->GetNumberOfChannels(); m_NumberOfTimePoints = m_LSMReaders[0]->GetNumberOfTimePoints(); std::cout << m_LSMReaders[0]->GetDescription() << std::endl; double spacing[3]; m_LSMReaders[0]->GetVoxelSizes(spacing); int dim[5]; m_LSMReaders[0]->GetDimensions(dim); std::string headerfilename = iDirectoryPath; headerfilename += m_BaseName; headerfilename += ".meg"; std::ofstream file( headerfilename.c_str() ); file << "MegaCapture" << std::endl; file << "" << std::endl; file << "Version 3.0" << std::endl; file << "ExperimentTitle " << std::endl; file << "ExperimentDescription "; if ( m_LSMReaders[0]->GetDescription() ) { file << m_LSMReaders[0]->GetDescription(); } file << std::endl; file << "TimeInterval " << m_LSMReaders[0]->GetTimeInterval() << std::endl; file << "Objective " << m_LSMReaders[0]->GetObjective() << std::endl; file << "VoxelSizeX " << spacing[0] * 1000000 << std::endl; file << "VoxelSizeY " << spacing[1] * 1000000 << std::endl; file << "VoxelSizeZ " << spacing[2] * 1000000 << std::endl; file << "DimensionX " << dim[0] << std::endl; file << "DimensionY " << dim[1] << std::endl; file << "DimensionPL " << m_Plaque << std::endl; file << "DimensionCO " << m_Column << std::endl; file << "DimensionRO " << m_Row << std::endl; file << "DimensionZT " << m_ZTile << std::endl; file << "DimensionYT " << m_YTile << std::endl; file << "DimensionXT " << m_XTile << std::endl; file << "DimensionTM " << m_NumberOfTimePoints << std::endl; file << "DimensionZS " << dim[2] << std::endl; file << "DimensionCH " << m_NumberOfChannels << std::endl; unsigned int i, j, k; for ( i = 0; i < m_NumberOfChannels; i++ ) { int r = m_LSMReaders[0]->GetChannelColorComponent(i, 0); int g = m_LSMReaders[0]->GetChannelColorComponent(i, 1); int b = m_LSMReaders[0]->GetChannelColorComponent(i, 2); file << "ChannelColor" << i << " " << r * 256 * 256 + g * 256 + b << std::endl; } file << "ChannelDepth 8" << std::endl; file << "FileType PNG" << std::endl; file << "" << std::endl; if ( m_NumberOfChannels > 1 ) { for ( i = 1; i < m_NumberOfChannels; i++ ) { m_LSMReaders.push_back( vtkLSMReader::New() ); m_LSMReaders[i]->SetFileName( m_FileName.c_str() ); m_LSMReaders[i]->SetUpdateChannel(i); } } int extent[6]; char timeStr[100] = ""; struct stat buf; if ( !stat(m_FileName.c_str(), &buf) ) { strftime( timeStr, 100, "%Y-%m-%d %H:%M:%S", localtime(&buf.st_mtime) ); } for ( i = 0; i < m_NumberOfTimePoints; i++ ) { for ( k = 0; k < m_NumberOfChannels; k++ ) { m_LSMReaders[k]->SetUpdateTimePoint(i); } for ( j = 0; j < m_NumberOfChannels; j++ ) { m_LSMReaders[j]->Update(); vtkImageData *image3d = m_LSMReaders[j]->GetOutput(); image3d->GetExtent(extent); for ( k = 0; k < static_cast< unsigned int >( dim[2] ); k++ ) { std::stringstream filename; filename << m_BaseName << "-PL" << setfill('0') << setw(2) << m_Plaque; filename << "-CO" << setfill('0') << setw(2) << m_Column; filename << "-RO" << setfill('0') << setw(2) << m_Row; filename << "-ZT" << setfill('0') << setw(2) << m_ZTile; filename << "-YT" << setfill('0') << setw(2) << m_YTile; filename << "-XT" << setfill('0') << setw(2) << m_XTile; filename << "-TM" << setfill('0') << setw(4) << i; filename << "-ch" << setfill('0') << setw(2) << j; filename << "-zs" << setfill('0') << setw(4) << k; switch ( m_FileType ) { default: case GoFigure::PNG: { filename << ".png"; break; } case GoFigure::TIFF: { filename << ".tiff"; break; } } file << "" << std::endl; file << "Filename " << filename.str() << std::endl; file << "DateTime " << timeStr << std::endl; file << "StageX 1000" << std::endl; file << "StageY -1000" << std::endl; file << "Pinhole 44.216" << std::endl; file << "" << std::endl; vtkExtractVOI *extract = vtkExtractVOI::New(); extract->SetSampleRate(1, 1, 1); extract->SetInput(image3d); extract->SetVOI(extent[0], extent[1], extent[2], extent[3], k, k); extract->Update(); vtkImageData *image2d = extract->GetOutput(); std::string final_filename = iDirectoryPath; final_filename += filename.str(); switch ( m_FileType ) { default: case GoFigure::PNG: { vtkWriteImage< vtkPNGWriter >(image2d, final_filename); break; } case GoFigure::TIFF: { vtkWriteImage< vtkTIFFWriter >(image2d, final_filename); break; } } extract->Delete(); } } } file.close(); }GoFigure2-v0.9.0/Code/IO/TraceStructure.cxx0000644000175000017500000002630111667757442020262 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "TraceStructure.h" #include #include "vtkPolyData.h" #include "vtkCellArray.h" #include "vtkActor.h" #include "vtkMapper.h" #include "vtkDoubleArray.h" #include "vtkPointData.h" #include "vtkLookupTable.h" //-------------------------------------------------------------------------- TraceStructure::TraceStructure() : TraceID(0), CollectionID(0), ActorXY(NULL), ActorXZ(NULL), ActorYZ(NULL), ActorXYZ(NULL), Nodes(NULL), Highlighted(false), Visible(false) { this->rgba[0] = 1.; this->rgba[1] = 1.; this->rgba[2] = 1.; this->rgba[3] = 1.; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- TraceStructure::TraceStructure( const unsigned int & iTraceID, const unsigned int & iCollectionID, std::vector< vtkActor * > iActors, vtkPolyData *iNodes, const bool & iHighlighted, const bool & iVisible, const double & r, const double & g, const double & b, const double & alpha) : TraceID(iTraceID), CollectionID(iCollectionID), Nodes(iNodes), Highlighted(iHighlighted), Visible(iVisible) { if ( iActors.size() == 4 ) { ActorXY = iActors[0]; ActorXZ = iActors[1]; ActorYZ = iActors[2]; ActorXYZ = iActors[3]; } else { std::cerr << "iActors.size() != 4" << std::endl; return; } this->rgba[0] = r; this->rgba[1] = g; this->rgba[2] = b; this->rgba[3] = alpha; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- TraceStructure::TraceStructure(const unsigned int & iTraceID, const unsigned int & iCollectionID, std::vector< vtkActor * > iActors, vtkPolyData *iNodes, const bool & iHighlighted, const bool & iVisible, double iRgba[4]) : TraceID(iTraceID), CollectionID(iCollectionID), Nodes(iNodes), Highlighted(iHighlighted), Visible(iVisible) { if ( iActors.size() == 4 ) { ActorXY = iActors[0]; ActorXZ = iActors[1]; ActorYZ = iActors[2]; ActorXYZ = iActors[3]; } else { std::cout << "iActors.size() != 4" << std::endl; return; } this->rgba[0] = iRgba[0]; this->rgba[1] = iRgba[1]; this->rgba[2] = iRgba[2]; this->rgba[3] = iRgba[3]; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- TraceStructure::TraceStructure(const unsigned int & iTraceID, const unsigned int & iCollectionID, vtkActor *iActorXY, vtkActor *iActorYZ, vtkActor *iActorXZ, vtkActor *iActorXYZ, vtkPolyData *iNodes, const bool & iHighlighted, const bool & iVisible, const double & r, const double & g, const double & b, const double & alpha) : TraceID(iTraceID), CollectionID(iCollectionID), ActorXY(iActorXY), ActorXZ(iActorXZ), ActorYZ(iActorYZ), ActorXYZ(iActorXYZ), Nodes(iNodes), Highlighted(iHighlighted), Visible(iVisible) { this->rgba[0] = r; this->rgba[1] = g; this->rgba[2] = b; this->rgba[3] = alpha; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- TraceStructure::TraceStructure(const TraceStructure & iE) : TraceID(iE.TraceID), CollectionID(iE.CollectionID), ActorXY(iE.ActorXY), ActorXZ(iE.ActorXZ), ActorYZ(iE.ActorYZ), ActorXYZ(iE.ActorXYZ), Nodes(iE.Nodes), Highlighted(iE.Highlighted), Visible(iE.Visible) { for ( int i = 0; i < 4; i++ ) { this->rgba[i] = iE.rgba[i]; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- TraceStructure:: ~TraceStructure() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TraceStructure::SetActorProperties(vtkProperty *iProperty) const { if ( iProperty ) { if ( this->ActorXY ) { this->ActorXY->SetProperty(iProperty); } if ( this->ActorXZ ) { this->ActorXZ->SetProperty(iProperty); } if ( this->ActorYZ ) { this->ActorYZ->SetProperty(iProperty); } if ( this->ActorXYZ ) { this->ActorXYZ->SetProperty(iProperty); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TraceStructure::SetActorVisibility(const bool & iVisible) const { if ( this->ActorXY ) { this->ActorXY->SetVisibility(iVisible); } if ( this->ActorXZ ) { this->ActorXZ->SetVisibility(iVisible); } if ( this->ActorYZ ) { this->ActorYZ->SetVisibility(iVisible); } if ( this->ActorXYZ ) { this->ActorXYZ->SetVisibility(iVisible); } } //-------------------------------------------------------------------------- void TraceStructure::SetScalarData(const std::string & iName, const double & iValue) const { if ( this->Nodes ) { vtkIdType NbOfPoints = this->Nodes->GetNumberOfPoints(); vtkSmartPointer data = vtkSmartPointer::New(); data->SetNumberOfComponents(1); data->SetName( iName.c_str() ); for ( vtkIdType i = 0; i < NbOfPoints; ++i ) { data->InsertNextValue(iValue); } this->Nodes->GetPointData()->SetScalars(data); this->Nodes->GetPointData()->SetActiveScalars( iName.c_str() ); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TraceStructure::SetScalarRange(const double & iMin, const double & iMax) const { if ( this->ActorXY ) { this->ActorXY->GetMapper()->SetScalarRange(iMin, iMax); this->ActorXY->GetMapper()->SetScalarVisibility(true); } if ( this->ActorXZ ) { this->ActorXZ->GetMapper()->SetScalarRange(iMin, iMax); this->ActorXZ->GetMapper()->SetScalarVisibility(true); } if ( this->ActorYZ ) { this->ActorYZ->GetMapper()->SetScalarRange(iMin, iMax); this->ActorYZ->GetMapper()->SetScalarVisibility(true); } if ( this->ActorXYZ ) { this->ActorXYZ->GetMapper()->SetScalarRange(iMin, iMax); this->ActorXYZ->GetMapper()->SetScalarVisibility(true); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TraceStructure::RenderWithOriginalColors() const { if ( this->Nodes ) { this->Nodes->GetPointData()->SetActiveScalars(NULL); } if ( this->ActorXY ) { this->ActorXY->GetMapper()->SetScalarVisibility(false); } if ( this->ActorXZ ) { this->ActorXZ->GetMapper()->SetScalarVisibility(false); } if ( this->ActorYZ ) { this->ActorYZ->GetMapper()->SetScalarVisibility(false); } if ( this->ActorXYZ ) { this->ActorXYZ->GetMapper()->SetScalarVisibility(false); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TraceStructure::SetLookupTable(const vtkLookupTable *iLut) const { if ( iLut ) { if ( this->ActorXY ) { this->ActorXY->GetMapper()->SetLookupTable( const_cast(iLut)); } if ( this->ActorXZ ) { this->ActorXZ->GetMapper()->SetLookupTable( const_cast(iLut)); } if ( this->ActorYZ ) { this->ActorYZ->GetMapper()->SetLookupTable( const_cast(iLut)); } if ( this->ActorXYZ ) { this->ActorXYZ->GetMapper()->SetLookupTable( const_cast(iLut)); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TraceStructure::ReleaseData() const { if ( this->ActorXY ) { this->ActorXY->Delete(); } if ( this->ActorXZ ) { this->ActorXZ->Delete(); } if ( this->ActorYZ ) { this->ActorYZ->Delete(); } if ( this->ActorXYZ ) { this->ActorXYZ->Delete(); } if ( this->Nodes ) { this->Nodes->Delete(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TraceStructure::ResetNodes() const { if ( this->Nodes ) { if ( this->Nodes->GetPointData() ) { this->Nodes->GetPointData()->Reset(); } if ( this->Nodes->GetPoints() ) { this->Nodes->GetPoints()->Reset(); } if ( this->Nodes->GetLines() ) { this->Nodes->GetLines()->Reset(); } if ( this->Nodes ) { this->Nodes->Reset(); } } } GoFigure2-v0.9.0/Code/IO/ConvertToStringHelper.h0000644000175000017500000000477611667757442021216 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __ConvertToStringHelper_h #define __ConvertToStringHelper_h #include #include #include #include "boost/lexical_cast.hpp" template< typename T > std::string ConvertToString(const T & ToConvert) { std::stringstream st; st << ToConvert; return st.str(); } template< typename T > T ss_atoi(const std::string & the_string) { try { return boost::lexical_cast< T >( the_string ); } catch( boost::bad_lexical_cast& ) { std::cout <<"***" < #include #include "vtkPolyData.h" #include "vtkMath.h" #include "vtkIdList.h" #include "QGoIOConfigure.h" /** \defgroup MySQLWriter MySQLWriter \defgroup Track Track \defgroup Trace Trace */ /** \class vtkPolyDataMySQLTrackWriter \brief Reads a string and convert it into a track polydata \ingroup MySQLWriter Track Trace */ class QGOIO_EXPORT vtkPolyDataMySQLTrackWriter:public vtkObject { public: /* * \brief Public constructor */ static vtkPolyDataMySQLTrackWriter * New(); vtkTypeRevisionMacro(vtkPolyDataMySQLTrackWriter, vtkObject); /* * \brief Generate a string from a track polydata * \param[in] iPolyData Polydata to generate the string * \return string containing the track polydata information */ std::string GetMySQLText(vtkPolyData *iPolyData); protected: vtkPolyDataMySQLTrackWriter(); virtual ~vtkPolyDataMySQLTrackWriter(); private: vtkPolyDataMySQLTrackWriter(const vtkPolyDataMySQLTrackWriter &); void operator=(const vtkPolyDataMySQLTrackWriter &); }; #endif GoFigure2-v0.9.0/Code/IO/vtkPolyDataMySQLMeshReader.h0000644000175000017500000000556111667757442022025 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkPolyDataMySQLMeshReader_h #define __vtkPolyDataMySQLMeshReader_h #include "vtkObject.h" #include #include "vtkSmartPointer.h" class vtkPolyData; #include "QGoIOConfigure.h" /** \defgroup MySQLReader MySQLReader \defgroup Contour Contour \defgroup Mesh Mesh \defgroup Trace Trace */ /** \class vtkPolyDataMySQLMeshReader \brief Reads a string and convert it into a mesh polydata \ingroup MySQLReader Mesh Trace */ class QGOIO_EXPORT vtkPolyDataMySQLMeshReader:public vtkObject { public: /* * \brief Public constructor */ static vtkPolyDataMySQLMeshReader * New(); vtkTypeRevisionMacro(vtkPolyDataMySQLMeshReader, vtkObject); /* * \brief Generate a mesh from a string * \param[in] iString base string to generate the polydata * \return pointer to the generated contour/mesh */ vtkSmartPointer GetPolyData(const std::string & iString); protected: vtkPolyDataMySQLMeshReader(); ~vtkPolyDataMySQLMeshReader(); private: vtkPolyDataMySQLMeshReader(const vtkPolyDataMySQLMeshReader &); void operator=(const vtkPolyDataMySQLMeshReader &); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBImport.cxx0000644000175000017500000003406611667757442017260 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBImport.h" #include "SelectQueryDatabaseHelper.h" #include "QueryDataBaseHelper.h" #include "ConvertToStringHelper.h" #include "GoDBColorRow.h" #include "GoDBCellTypeRow.h" #include "GoDBSubCellTypeRow.h" #include "GoDBCoordinateRow.h" #include "GoDBContourRow.h" #include "GoDBMeshRow.h" #include "GoDBTrackRow.h" #include "GoDBLineageRow.h" #include "GoDBChannelRow.h" #include "GoDBIntensityRow.h" //-------------------------------------------------------------------------- GoDBImport::GoDBImport(std::string iServerName, std::string iLogin, std::string iPassword, int iImagingSessionID, std::string iFilename, int iCurrentTimePoint) { this->m_ServerName = iServerName; this->m_Login = iLogin; this->m_Password = iPassword; this->m_ImagingSessionID = iImagingSessionID; this->m_CurrentTimePoint = iCurrentTimePoint; this->m_InFile.open(iFilename.c_str(), std::ifstream::in); } //-------------------------------------------------------------------------- GoDBImport::~GoDBImport() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBImport::ImportContours() { this->OpenDBConnection(); IntMapType MapColorIDs; IntMapType MapCellTypeIDs; IntMapType MapSubCellTypeIDs; IntMapType MapCoordIDs; std::string LineContent; LineContent = this->SaveNoTracesEntities(MapColorIDs, MapCellTypeIDs, MapSubCellTypeIDs, MapCoordIDs); this->SaveTracesEntities(MapColorIDs, MapCoordIDs, LineContent, MapCellTypeIDs, MapSubCellTypeIDs); //this->FillContourInfoForVisu(this->m_NewContourIDs); this->CloseDBConnection(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBImport::ImportMeshes() { this->OpenDBConnection(); this->m_NewContourIDs.clear(); IntMapType MapColorIDs; IntMapType MapCellTypeIDs; IntMapType MapSubCellTypeIDs; IntMapType MapCoordIDs; std::string LineContent; LineContent = this->SaveNoTracesEntities(MapColorIDs, MapCellTypeIDs, MapSubCellTypeIDs, MapCoordIDs); this->SaveTracesEntities(MapColorIDs, MapCoordIDs, LineContent, MapCellTypeIDs, MapSubCellTypeIDs, true); //this->FillMeshInfoForVisu(this->m_NewMeshIDs); this->CloseDBConnection(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBImport::ImportTracks() { this->ImportMeshes(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string GoDBImport::SaveNoTracesEntities(IntMapType & ioMapColorIDs, IntMapType & ioMapCellTypeIDs, IntMapType & ioMapSubCellTypeIDs, IntMapType & ioMapCoordIDs) { std::string LineContent; getline(this->m_InFile, LineContent); while ( !this->IsLineForNumberOfEntities(LineContent) ) { getline (this->m_InFile, LineContent); } while ( this->FindFieldName(LineContent) != "NumberOflineage" ) { int EntitiesNumber = atoi( this->GetValueForTheLine(LineContent).c_str() ); getline(this->m_InFile, LineContent); //if there is nothing to be saved in the database for this group, just go //to the next line in the file: if ( EntitiesNumber != 0 ) { if ( this->GetValueForTheLine(LineContent) != "NoValueOnTheLine" ) { std::cout << "There was supposed to be only the name of the entity to save,the entity will not be saved"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return LineContent; } std::string NameEntity = this->FindFieldName(LineContent); if ( NameEntity == "color" ) { LineContent = this->SaveImportedEntitiesInDatabase< GoDBColorRow >( EntitiesNumber, ioMapColorIDs); } if ( NameEntity == "celltype" ) { LineContent = this->SaveImportedEntitiesInDatabase< GoDBCellTypeRow >( EntitiesNumber, ioMapCellTypeIDs); } if ( NameEntity == "subcellulartype" ) { LineContent = this->SaveImportedEntitiesInDatabase< GoDBSubCellTypeRow >( EntitiesNumber, ioMapSubCellTypeIDs); } if ( NameEntity == "coordinate" ) { LineContent = this->SaveImportedEntitiesInDatabase< GoDBCoordinateRow >( EntitiesNumber, ioMapCoordIDs); } if ( NameEntity != "color" && NameEntity != "celltype" && NameEntity != "subcellulartype" && NameEntity != "coordinate" ) { std::cout << "The name of the entity doesn't correspond to any of the no traces entity"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } } } return LineContent; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBImport::SaveTracesEntities(const IntMapType & iMapColorIDs, const IntMapType & iMapCoordIDs, const std::string & iLineContent, const IntMapType & iMapCellTypeIDs, const IntMapType & iMapSubCellTypeIDs, bool SaveIntensities) { IntMapType MapContourIDs; IntMapType MapMeshIDs; IntMapType MapTrackIDs; IntMapType MapLineageIDs; std::string LineContent = iLineContent; { IntMapType MapIDsSpecificOne; IntMapType MapIDsSpecificTwo; this->SaveTraces< GoDBLineageRow >(iMapColorIDs, iMapCoordIDs, MapLineageIDs, LineContent, this->m_NewLineageIDs, MapLineageIDs, MapIDsSpecificOne, MapIDsSpecificTwo ); } { IntMapType MapIDsSpecificOne; IntMapType MapIDsSpecificTwo; this->SaveTraces< GoDBTrackRow >(iMapColorIDs, iMapCoordIDs, MapLineageIDs, LineContent, this->m_NewTracksIDs, MapTrackIDs, MapIDsSpecificOne, MapIDsSpecificTwo ); } { this->SaveTraces< GoDBMeshRow >(iMapColorIDs, iMapCoordIDs, MapTrackIDs, LineContent, this->m_NewMeshIDs, MapMeshIDs, iMapCellTypeIDs, iMapSubCellTypeIDs); } if ( SaveIntensities ) { this->SaveIntensityForMesh(LineContent, MapMeshIDs, iMapColorIDs); } { IntMapType MapIDsSpecificOne; IntMapType MapIDsSpecificTwo; this->SaveTraces< GoDBContourRow >(iMapColorIDs, iMapCoordIDs, MapMeshIDs, LineContent, this->m_NewContourIDs, MapContourIDs, MapIDsSpecificOne, MapIDsSpecificTwo ); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string GoDBImport::FindFieldName(std::string iLine) { size_t BegName = iLine.find("<", 0) + 1; size_t EndName = iLine.find(">", 0); size_t NameLength = EndName - BegName; std::string oName = iLine.substr(BegName, NameLength); if ( oName.find("/", 0) == 0 ) { oName = oName.substr(1); } return oName; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string GoDBImport::GetValueForTheLine(std::string iLine) { size_t BegValue = iLine.find(">", 0) + 1; size_t EndValue = iLine.find("<", BegValue); if ( EndValue != iLine.npos ) { size_t ValueLength = EndValue - BegValue; return iLine.substr(BegValue, ValueLength); } return "NoValueOnTheLine"; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool GoDBImport::IsLineForNumberOfEntities(std::string iLine) { size_t BegValue = iLine.find("NumberOf", 0); if ( BegValue != iLine.npos ) { return true; } return false; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBImport::OpenDBConnection() { this->m_DatabaseConnector = OpenDatabaseConnection(m_ServerName, m_Login, m_Password, "gofiguredatabase"); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBImport::CloseDBConnection() { CloseDatabaseConnection(m_DatabaseConnector); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBImport::SaveIntensityForMesh(std::string & ioLineContent, const IntMapType & iMapMeshIDs, const IntMapType & iMapColorIDs) { IntMapType MapChannelIDs; while ( this->FindFieldName(ioLineContent) != "NumberOfchannel" ) { getline (this->m_InFile, ioLineContent); } int EntitiesNumber = atoi( this->GetValueForTheLine(ioLineContent).c_str() ); getline(this->m_InFile, ioLineContent); if ( EntitiesNumber != 0 ) { while ( this->FindFieldName(ioLineContent) != "NumberOfintensity" ) { if ( this->GetValueForTheLine(ioLineContent) != "NoValueOnTheLine" ) { std::cout << "There was supposed to be only the name of the entity to save,the entity will not be saved"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } std::string NameEntity = this->FindFieldName(ioLineContent); if ( NameEntity != "channel" ) { std::cout << "The name of the entity should be channel but is actually different"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } else { GoDBChannelRow NewChannel; ioLineContent = this->GetValuesFromInfile< GoDBChannelRow >(NewChannel); this->ReplaceTheFieldWithNewIDs< GoDBChannelRow >( iMapColorIDs, "ColorID", NewChannel); int OldID = NewChannel.GetMapValue("ChannelID"); NewChannel.SetField("ChannelID", "0"); NewChannel.SetField("ImagingSessionID", this->m_ImagingSessionID); MapChannelIDs[OldID] = NewChannel.SaveInDB(this->m_DatabaseConnector); } } } EntitiesNumber = atoi( this->GetValueForTheLine(ioLineContent).c_str() ); getline(this->m_InFile, ioLineContent); if ( EntitiesNumber != 0 ) { while ( this->FindFieldName(ioLineContent) != "ExportTraces" ) { if ( this->GetValueForTheLine(ioLineContent) != "NoValueOnTheLine" ) { std::cout << "There was supposed to be only the name of the entity to save,the entity will not be saved"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } std::string NameEntity = this->FindFieldName(ioLineContent); if ( NameEntity != "intensity" ) { std::cout << "The name of the entity should be channel but is actually different"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } else { GoDBIntensityRow NewIntensity; ioLineContent = this->GetValuesFromInfile< GoDBIntensityRow >(NewIntensity); this->ReplaceTheFieldWithNewIDs< GoDBIntensityRow >( iMapMeshIDs, "meshID", NewIntensity); this->ReplaceTheFieldWithNewIDs< GoDBIntensityRow >( MapChannelIDs, "ChannelID", NewIntensity); NewIntensity.SetField("IntensityID", "0"); NewIntensity.SaveInDB(this->m_DatabaseConnector); } } } } GoFigure2-v0.9.0/Code/IO/GoFigureLineageAttributes.h0000644000175000017500000000564011667757442021776 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoFigureLineageAttributes_h #define __GoFigureLineageAttributes_h #include #include #include "QGoIOConfigure.h" /* \struct GoFigureLineageAttributes \brief Lineage attributes to be displayed in the table widget */ struct QGOIO_EXPORT GoFigureLineageAttributes { unsigned int MaxDepth; unsigned int MinDepth; unsigned int NumberOfDivisions; unsigned int NumberOfLeaves; /** Constructors */ GoFigureLineageAttributes() : MaxDepth( 0 ), MinDepth( 0 ), NumberOfDivisions( 0 ), NumberOfLeaves( 0) {} GoFigureLineageAttributes(const GoFigureLineageAttributes & iE): MaxDepth(iE.MaxDepth), MinDepth(iE.MinDepth), NumberOfDivisions(iE.NumberOfDivisions), NumberOfLeaves(iE.NumberOfLeaves) {} GoFigureLineageAttributes& operator = ( const GoFigureLineageAttributes & iE ) { this->MaxDepth = iE.MaxDepth; this->MinDepth = iE.MinDepth; this->NumberOfDivisions = iE.NumberOfDivisions; this->NumberOfLeaves = iE.NumberOfLeaves; return *this; } void clear() { this->MaxDepth = 0; this->MinDepth = 0; this->NumberOfDivisions = 0; this->NumberOfLeaves = 0; } }; #endif GoFigure2-v0.9.0/Code/IO/GoFigureTrackAttributes.h0000644000175000017500000000675211667757442021503 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoFigureTrackAttributes_h #define __GoFigureTrackAttributes_h #include #include #include "QGoIOConfigure.h" /* \struct GoFigureTrackAttributes \brief Track attributes to be displayed in the table widget */ struct QGOIO_EXPORT GoFigureTrackAttributes { /**total distance (add each segment size) = deplacement */ double total_length; /** average speed */ double avg_speed; /** maximum speed */ double max_speed; /** euclidian distance between first and last points */ double distance; /** theta in spherical coordinate system */ double theta; /** phi in spherical coordinate system */ double phi; /** average mesh volume over the track */ double avg_volume; unsigned int number_meshes; unsigned int temporal_extent; /** Constructors */ GoFigureTrackAttributes() : total_length( 0. ), avg_speed( 0. ), max_speed( 0. ), distance( 0. ), theta( 0. ), phi( 0. ), avg_volume(0.), number_meshes( 0 ), temporal_extent( 0 ) {} GoFigureTrackAttributes(const GoFigureTrackAttributes & iE): total_length(iE.total_length), avg_speed(iE.avg_speed), max_speed(iE.max_speed), distance(iE.distance), theta(iE.theta), phi(iE.phi), avg_volume(iE.avg_volume), number_meshes( iE.number_meshes ), temporal_extent(iE.temporal_extent) {} GoFigureTrackAttributes& operator = ( GoFigureTrackAttributes & iE ) { this->total_length = iE.total_length; this->avg_speed = iE.avg_speed; this->max_speed = iE.max_speed; this->distance = iE.distance; this->theta = iE.theta; this->phi = iE.phi; this->avg_volume = iE.avg_volume; this->number_meshes = iE.number_meshes; this->temporal_extent = iE.temporal_extent; return *this; } }; #endif GoFigure2-v0.9.0/Code/IO/itkMegaCaptureReader.cxx0000644000175000017500000003150411667757442021334 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkMegaCaptureReader.h" #include "itkNumericTraits.h" #include "vtkImageData.h" #include "vtkImageAppend.h" #include "vtkJPEGReader.h" #include "vtkBMPReader.h" #include "vtkPNGReader.h" #include "vtkTIFFReader.h" #include "vtkMetaImageReader.h" #include "VolumeBuilderHelper.h" namespace itk { //-------------------------------------------------------------------------- MegaCaptureReader::MegaCaptureReader() : m_FileType(GoFigure::PNG), m_TimeBased(true), m_Modified(true) { m_HeaderReader = new MegaCaptureHeaderReader(""); unsigned int max_uint = itk::NumericTraits< unsigned int >::max(); m_MinTimePoint = max_uint; m_MaxTimePoint = max_uint; m_UpdateTimePoint = max_uint; m_TimeInterval = max_uint; m_MinZSlice = max_uint; m_MaxZSlice = max_uint; m_UpdateZSlice = max_uint; m_MinChannel = max_uint; m_MaxChannel = max_uint; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- MegaCaptureReader:: ~MegaCaptureReader() { delete m_HeaderReader; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void MegaCaptureReader::SetTimePoint(const unsigned int & iT) { if ( iT < m_MinTimePoint ) { m_Modified = ( m_UpdateTimePoint != m_MinTimePoint ); m_UpdateTimePoint = m_MinTimePoint; } else { if ( iT > m_MaxTimePoint ) { m_Modified = ( m_UpdateTimePoint != m_MaxTimePoint ); m_UpdateTimePoint = m_MaxTimePoint; } else { m_Modified = ( m_UpdateTimePoint != iT ); m_UpdateTimePoint = iT; } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void MegaCaptureReader::SetZSlice(const unsigned int & iZs) { if ( iZs < m_MinZSlice ) { m_Modified = ( m_UpdateZSlice != m_MinZSlice ); m_UpdateZSlice = m_MinZSlice; } else { if ( iZs > m_MaxZSlice ) { m_Modified = ( m_UpdateZSlice != m_MaxZSlice ); m_UpdateZSlice = m_MaxZSlice; } else { m_Modified = ( m_UpdateZSlice != iZs ); m_UpdateZSlice = iZs; } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void MegaCaptureReader::SetMegaCaptureHeader(const std::string & iHeader) { m_HeaderReader->SetFileName(iHeader); m_HeaderReader->Read(); m_ChannelColor = m_HeaderReader->m_ChannelColor; m_Modified = true; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void MegaCaptureReader::SetInput(const GoFigureFileInfoHelperMultiIndexContainer & iUserFileList) { if ( iUserFileList.size() == 0 ) { std::cerr << "iUserFileList.empty()" << std::endl; return; } m_FileList = iUserFileList; m_Modified = true; ComputeBounds(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void MegaCaptureReader::ComputeBounds() { // get min time point GoFigureFileInfoHelperMultiIndexContainer::index< m_TCoord >::type::iterator tm_it = m_FileList.get< m_TCoord >().begin(); m_MinTimePoint = ( *tm_it ).m_TCoord; // get max time point GoFigureFileInfoHelperMultiIndexContainer::index< m_TCoord >::type::reverse_iterator r_tm_it = m_FileList.get< m_TCoord >().rbegin(); m_MaxTimePoint = ( *r_tm_it ).m_TCoord; // get min Z slices GoFigureFileInfoHelperMultiIndexContainer::index< m_ZCoord >::type::iterator zs_it = m_FileList.get< m_ZCoord >().begin(); m_MinZSlice = ( *zs_it ).m_ZCoord; // get max Z slices GoFigureFileInfoHelperMultiIndexContainer::index< m_ZCoord >::type::reverse_iterator r_zs_it = m_FileList.get< m_ZCoord >().rbegin(); m_MaxZSlice = ( *r_zs_it ).m_ZCoord; // get min channel GoFigureFileInfoHelperMultiIndexContainer::index< m_Channel >::type::iterator ch_it = m_FileList.get< m_Channel >().begin(); m_MinChannel = ( *ch_it ).m_Channel; // (note that the real one could be different) GoFigureFileInfoHelperMultiIndexContainer::index< m_Channel >::type::reverse_iterator r_ch_it = m_FileList.get< m_Channel >().rbegin(); m_MaxChannel = ( *r_ch_it ).m_Channel; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void MegaCaptureReader::AddToVTKVolumeBuilder(const int & iCounter, const std::string & iFileName, vtkImageAppend *iBuilder) { switch ( this->m_FileType ) { case GoFigure::JPEG: { AddToVolumeBuilder< vtkJPEGReader >(iCounter, iFileName, iBuilder); break; } case GoFigure::BMP: { AddToVolumeBuilder< vtkBMPReader >(iCounter, iFileName, iBuilder); break; } case GoFigure::PNG: { AddToVolumeBuilder< vtkPNGReader >(iCounter, iFileName, iBuilder); break; } case GoFigure::TIFF: { AddToVolumeBuilder< vtkTIFFReader >(iCounter, iFileName, iBuilder); break; } case GoFigure::MHA: { AddToVolumeBuilder< vtkMetaImageReader >(iCounter, iFileName, iBuilder); break; } case GoFigure::LSM: { itkGenericExceptionMacro(<< "stacks of 2D LSM are not supported at this time."); break; } default: { itkGenericExceptionMacro(<< "unsupported type: " << m_FileType << "."); break; } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void MegaCaptureReader::Update() { if ( m_Modified ) { this->InvokeEvent( StartEvent() ); std::map< unsigned int, std::list< std::string > > filelistperchannel; if ( m_TimeBased ) { filelistperchannel = GetAllFileNamesForGivenTCoord(m_FileList, m_UpdateTimePoint, m_MinChannel, m_MaxChannel); } else { filelistperchannel = GetAllFileNamesForGivenZCoord(m_FileList, m_UpdateZSlice, m_MinChannel, m_MaxChannel); } // prepare the final output std::map< unsigned int, std::list< std::string > >::iterator fch_it = filelistperchannel.begin(); std::map< unsigned int, std::list< std::string > >::iterator fch_end = filelistperchannel.end(); size_t kk = 0; size_t size = filelistperchannel.size() * fch_it->second.size(); while ( fch_it != fch_end ) { int counter = 0; vtkSmartPointer< vtkImageAppend > volumeBuilder = vtkSmartPointer< vtkImageAppend >::New(); volumeBuilder->SetNumberOfThreads(VTK_MAX_THREADS); volumeBuilder->SetAppendAxis(2); std::list< std::string >::iterator f_it = fch_it->second.begin(); std::list< std::string >::iterator f_end = fch_it->second.end(); while ( f_it != f_end ) { AddToVTKVolumeBuilder(counter, *f_it, volumeBuilder); this->SetProgress( static_cast< float >( kk ) / static_cast< float >( size ) ); ++kk; ++f_it; ++counter; } volumeBuilder->Update(); vtkImageData *temp_output = volumeBuilder->GetOutput(); double zspacing = 1.; /// \note We are using m_VoxelSizeZ no matter if m_TimeBased is true or // false. /// Since m_TimeInterval >> m_VoxelSizeX, it makes sense to do like this. zspacing = m_HeaderReader->m_VoxelSizeZ; // if( m_TimeBased ) // { // zspacing = m_HeaderReader.m_VoxelSizeZ; // } // else // { // zspacing = m_HeaderReader.m_TimeInterval; // } temp_output->SetSpacing(m_HeaderReader->m_VoxelSizeX, m_HeaderReader->m_VoxelSizeY, zspacing); if ( m_OutputImageMap.find(fch_it->first) == m_OutputImageMap.end() ) { m_OutputImageMap[fch_it->first] = vtkImageData::New(); } m_OutputImageMap[fch_it->first]->ShallowCopy(temp_output); ++fch_it; } m_TimeInterval = m_HeaderReader->m_TimeInterval; this->InvokeEvent( EndEvent() ); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer< vtkImageData > MegaCaptureReader::GetOutput(const unsigned int & iChannel) { std::map< unsigned int, vtkImageData * >::iterator it = m_OutputImageMap.find(iChannel); if ( it != m_OutputImageMap.end() ) { //vtkSmartPointer< vtkImageData > output = // vtkSmartPointer::New(); //output->ShallowCopy(it->second); return it->second; } else { return NULL; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer< vtkImageData > MegaCaptureReader::GetImage(const unsigned int & iCh, const unsigned int & iT) { std::list< std::string > filenames = GetAllFileNamesForGivenTCoordAndChannel(this->m_FileList, iT, iCh); if ( filenames.empty() ) { return NULL; } else { vtkSmartPointer< vtkImageAppend > volumeBuilder = vtkSmartPointer< vtkImageAppend >::New(); volumeBuilder->SetNumberOfThreads(VTK_MAX_THREADS); volumeBuilder->SetAppendAxis(2); std::list< std::string >::iterator f_it = filenames.begin(); std::list< std::string >::iterator f_end = filenames.end(); int counter = 0; while ( f_it != f_end ) { this->AddToVTKVolumeBuilder(counter, *f_it, volumeBuilder); ++counter; ++f_it; } volumeBuilder->Update(); vtkSmartPointer< vtkImageData > temp_output = vtkSmartPointer< vtkImageData >::New(); temp_output->ShallowCopy( volumeBuilder->GetOutput() ); temp_output->SetSpacing(m_HeaderReader->m_VoxelSizeX, m_HeaderReader->m_VoxelSizeY, m_HeaderReader->m_VoxelSizeZ); return temp_output; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::map< unsigned int, vtkImageData * > MegaCaptureReader::GetOutputs() { return m_OutputImageMap; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< std::vector< int > > MegaCaptureReader:: GetChannelColor() { return m_ChannelColor; } //-------------------------------------------------------------------------- }//end of namespace GoFigure2-v0.9.0/Code/IO/GoDBTableWidgetContainer.h0000644000175000017500000002163611667757442021470 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBTableWidgetContainer_h #define __GoDBTableWidgetContainer_h #include "GoDBTraceInfoForTableWidget.h" #include "GoDBTraceRow.h" #include "vtkMySQLDatabase.h" #include "SelectQueryDatabaseHelper.h" #include #include #include #include "QGoIOConfigure.h" /** \brief this class describes the columns of the table widget with the corresponding info to find their values in the database if the columns refer to data stored in the database and provides methods to fill the rows of the table widget and to get the right queries to find the data in the database \ingroup DB */ class QGOIO_EXPORT GoDBTableWidgetContainer { public: /** \brief Default Constructor */ GoDBTableWidgetContainer(); /** \brief constructor \param[in] iCollectionName name of the collection \param[in] iTracesName name of the traces \param[in] iImgSessionID ID of the imagingsession */ explicit GoDBTableWidgetContainer(std::string iCollectionName, std::string iTracesName, int iImgSessionID); /** \brief desctructor */ virtual ~GoDBTableWidgetContainer(){} typedef std::vector< std::pair< GoDBTraceInfoForTableWidget, std::vector< std::string > > > TWContainerType; /** \brief Return a list with all the ColumnNames and tooltips to be displayed in the tableWidget \return a list with all the ColumnNames and tooltips to be displayed in the tableWidget */ std::list< std::pair > GetListColumnsNamesAndToolTipsForTableWidget(); /** \brief Return a list with all the ColumnNames for computed values displayed in the tableWidget \return a list with all the ColumnNames for computed values displayed in the tableWidget */ std::vector< std::string > GetNameComputedColumns(); /** \brief get the results of the queries and put them in the row container corresponding to all the data needed to fill the table widget for the traces and return the corresponding row container \param[in] iDatabaseConnector connection to the database \return all the values needed from the database and the description of the info to know how to display them in the table widget */ virtual TWContainerType GetContainerLoadedWithAllFromDB( vtkMySQLDatabase *iDatabaseConnector,std::list iListTPs = std::list()); /** \brief get the results of the queries and put them in the row container corresponding to all the data needed to fill the table widget for the updated trace and return the link to the corresponding row container which has only 1 row \param[in] iDatabaseConnector connection to the database \param[in] iTraceID traceID the data are needed for \return the row container with all the data for the specific trace */ virtual TWContainerType GetContainerForOneSpecificTrace(vtkMySQLDatabase *iDatabaseConnector, int iTraceID); /** \brief get the results of the queries and put them in the row container corresponding to all the data needed to fill the table widget for the new created trace and return the link to the corresponding row container which has only 1 row*/ //virtual TWContainerType GetContainerForLastCreatedTrace( //vtkMySQLDatabase* iDatabaseConnector); //void ClearRowContainer(); std::vector< int > GetIndexForGroupColor(std::string iGroupName); /** \brief return all the traces IDs present in the RowContainer */ std::vector< int > GetAllTraceIDsInContainer(); /** *\brief return a list of all the traces with a bounding box containing the given ZCoord*/ //std::list GetTracesIDForAGivenZCoord(int iZCoord); //std::vector > GetChannelsInfo(); /** \brief Set the info needed for mesh*/ //void SetSpecificColumnsInfoForMesh( //std::vector > iChannelsInfo); /** \brief Insert a new created trace with the datas contained in the NewTraceContainer into the m_RowContainer*/ //void InsertNewCreatedTrace(GoDBTableWidgetContainer // iLinkToNewTraceContainer); //void DeleteSelectedTraces(std::list iSelectedTraces); //void UpdateIDs(std::list iListTracesToUpdate,unsigned int // NewCollectionID); protected: std::string m_CollectionName; std::string m_CollectionIDName; std::string m_TracesName; std::string m_TracesIDName; int m_ImgSessionID; std::vector< GoDBTraceInfoForTableWidget > m_ColumnsInfos; TWContainerType m_RowContainer; /** \brief Fill a vector of GoDBTraceInfoForTableWidget with the info needed to fill the table widget for all the traces \return a vector with all the info to fill the table widget for all the traces */ virtual std::vector< GoDBTraceInfoForTableWidget > GetColumnsInfoForTraceTable(); /** \brief Virtual Pure method Fill the vector of GoDBTraceInfoForTableWidget with the info common to 2 traces only */ virtual void SetCommonInfoForTwoTracesTable() = 0; void SetInfoForColumnIsVisible(); virtual void FillRowContainerWithDBValues( vtkMySQLDatabase *iDatabaseConnector, std::string iRestrictionName, std::string iRestrictionValue, std::list iListTimepoints = std::list()); /** \todo Lydie: find a way to make it ok for all traces, now only for mesh*/ /** \brief fill the row container with the values calculated and stored in th meshAttributes*/ void FillRowContainerForComputedValues( std::vector< std::vector< std::string > > *iComputedValues); //int GetLastCreatedTraceID(vtkMySQLDatabase* iDatabaseConnector); /** \brief return a vector of the table.fields to be selected from the database for all the fields except the ones with the same name if SameFieldsQuery is set to false and only for them if SameFieldsQuery is set to true*/ std::vector< std::string > GetQueryStringForSelectFieldsTables(bool SameFieldsInQuery); /** \brief return a vector of string with the tables to be joined with the trace table in the database query for all the fields except the ones with the same name if SameFieldsQuery is set to false and only for them if SameFieldsQuery is set to true*/ std::vector< std::string > GetQueryStringForTraceJoinedTables(bool SameFieldsInQuery); /** \brief fill the columns of the row container following the vector of string containing the columns to be filled with the results contained in the vector results from query and look on the columnNameDatabase in the column Info by default or else*/ void FillRowContainer(std::vector< std::vector< std::string > > iResultsFromQuery, std::vector< std::string > iSelectFields, std::string BaseOn = ""); size_t GetNumberOfRows(); /** *\brief return the index in the row container for the column with the given InfoName*/ int GetIndexInsideRowContainer(std::string iInfoName); virtual void ClearRowContainerValues(); /** \brief Fill the vector of GoDBTraceInfoForTableWidget with the info specific to a trace*/ //virtual void GetSpecificInfoForTraceTable() = 0; }; #endif GoFigure2-v0.9.0/Code/IO/QueryBuilderHelper.cxx0000644000175000017500000003723511667757442021067 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QueryBuilderHelper.h" #include "ConvertToStringHelper.h" #include std::string SelectGeneralQueryConditions( const std::string & iWhat, const std::string & iWhere, const std::string & iConditions) { std::stringstream querystream; querystream << "SELECT "; querystream << iWhat; querystream << " FROM "; querystream << iWhere; querystream << " WHERE "; querystream << iConditions; return querystream.str(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string SelectGeneralQuery( const std::string & iWhat, const std::string & iWhere, std::string iOrderByQuery) { std::stringstream querystream; querystream << "SELECT "; querystream << iWhat; querystream << " FROM "; querystream << iWhere; if ( !iOrderByQuery.empty() ) { querystream << iOrderByQuery; } return querystream.str(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string SelectQueryStream( const std::string & iTable, const std::string & iColumn, std::string iOrderByColumnName, std::string iAscDesc) { std::string OrderBy; if ( !iOrderByColumnName.empty() ) { OrderBy = AddOrderBy(iOrderByColumnName, iAscDesc); } return SelectGeneralQuery(iColumn, iTable, OrderBy); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string SelectQueryStream( const std::string & iTable, const std::vector< std::string > & iListAttributes, std::string iOrderByColumnName, std::string iAscDesc) { std::string SelectedFields = GetSelectedAttributes(iListAttributes); return SelectQueryStream(iTable, SelectedFields, iOrderByColumnName, iAscDesc); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string SelectQueryStreamCondition( const std::string & iTable, const std::string & iColumn, const std::string & iConditions, bool Distinct, std::string iOrderByColumnName, std::string iAscDesc) { std::string What = iColumn; std::string Condition = iConditions; if ( Distinct ) { What = AddDistinctToWhat(What); } if ( !iOrderByColumnName.empty() ) { Condition += AddOrderBy(iOrderByColumnName, iAscDesc); } return SelectGeneralQueryConditions(What, iTable, Condition); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string SelectQueryStreamCondition( const std::string & iTable, const std::string & iColumn, const std::string & iField, const std::string & iValue, std::string iOrderByColumnName, std::string iAscDesc, bool Distinct) { std::stringstream Conditions; Conditions << iField; Conditions << " = '"; Conditions << iValue; Conditions << "'"; return SelectQueryStreamCondition(iTable, iColumn, Conditions.str(), Distinct, iOrderByColumnName, iAscDesc); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string SelectQueryStreamCondition( const std::string & iTable, const std::vector< std::string > & iListAttributes, const std::string & iField, const std::string & iValue, std::string iOrderByColumnName, std::string iAscDesc) { std::string What = GetSelectedAttributes(iListAttributes); return SelectQueryStreamCondition(iTable, What, iField, iValue, iOrderByColumnName, iAscDesc); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string SelectQueryStreamListConditions( const std::string & iTable, const std::string & iColumn, const std::string & iField, const std::vector< std::string > & iListValues, bool Distinct, std::string iConditionConnector) { std::string Conditions = GetConditions(iField, iListValues, iConditionConnector); return SelectQueryStreamCondition(iTable, iColumn, Conditions, Distinct); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string SelectQueryStreamListConditions( const std::string & iTable, const std::vector< std::string > & iListAttributes, const std::string & iField, const std::vector< std::string > & iListValues, std::string iConditionConnector, bool Distinct) { std::string What = GetSelectedAttributes(iListAttributes); return SelectQueryStreamListConditions(iTable, What, iField, iListValues, Distinct, iConditionConnector); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string SelectQueryStreamListConditions( const std::string & iTable, const std::string & iColumn, const std::vector< FieldWithValue > & iConditions, std::string iConditionConnector, bool Distinct) { std::string What = iColumn; if ( Distinct ) { What = AddDistinctToWhat (What); } std::string Conditions = GetConditions(iConditions, iConditionConnector); return SelectQueryStreamCondition(iTable, iColumn, Conditions, Distinct); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string SelectQueryStreamListConditions( const std::string & iTable, const std::vector< std::string > & iListAttributes, const std::vector< FieldWithValue > & iConditions, std::string iConditionConnector, bool Distinct, std::string iOrderByColumnName) { std::string What = GetSelectedAttributes(iListAttributes); std::string oQueryString = SelectQueryStreamListConditions(iTable, What, iConditions, iConditionConnector, Distinct); if (!iOrderByColumnName.empty()) { oQueryString += AddOrderBy(iOrderByColumnName); } return oQueryString; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string AddDistinctToWhat(const std::string & iWhat) { std::string oWhat = "DISTINCT "; oWhat += iWhat; return oWhat; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string AddOrderBy(const std::string & iAttribute, std::string iAscDesc) { std::string oOrderBy = " ORDER BY "; oOrderBy += iAttribute; oOrderBy += " "; oOrderBy += iAscDesc; oOrderBy += " "; return oOrderBy; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string GetConditions( const std::vector< FieldWithValue > & iConditions, std::string iConditionConnector) { std::stringstream oConditions; oConditions << "("; unsigned int i; // why -1?? for ( i = 0; i < iConditions.size() - 1; i++ ) { oConditions << iConditions[i].Field; oConditions << iConditions[i].Operator; oConditions << " '"; oConditions << iConditions[i].Value; oConditions << "' "; oConditions << iConditionConnector; oConditions << " "; } oConditions << iConditions[i].Field; oConditions << iConditions[i].Operator; oConditions << " '"; oConditions << iConditions[i].Value; oConditions << "')"; return oConditions.str(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string GetConditions( const std::string & iField, const std::string & iValue, std::string iConnector) { std::vector< FieldWithValue > Condition(1); FieldWithValue Field = { iField, iValue, iConnector }; Condition[0] = Field; return GetConditions(Condition); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GetSelectedAttributes(const std::vector< std::string > & iListAttributes) { std::stringstream oQueryStream; unsigned int i; for ( i = 0; i < iListAttributes.size() - 1; i++ ) { oQueryStream << iListAttributes[i]; oQueryStream << ", "; } oQueryStream << iListAttributes[i]; return oQueryStream.str(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > ListUnsgIntToVectorString( const std::list< unsigned int > & iList) { std::list< unsigned int >::const_iterator iter = iList.begin(); std::vector< std::string > oVector; while ( iter != iList.end() ) { unsigned int temp = *iter; oVector.push_back( ConvertToString< unsigned int >(temp) ); ++iter; } return oVector; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > VectorStringToUnsgInt( const std::vector< std::string > & iVector) { std::vector< std::string >::const_iterator iter = iVector.begin(); std::list< unsigned int > oList; while ( iter != iVector.end() ) { oList.push_back( ss_atoi< unsigned int >( *iter ) ); ++iter; } return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector< std::string > VectorUnsgIntToVectorString( const std::vector< unsigned int > & iVector) { std::vector< unsigned int >::const_iterator iter = iVector.begin(); std::vector< std::string > oVector; while ( iter != iVector.end() ) { oVector.push_back( ConvertToString< unsigned int >( *iter ) ); ++iter; } return oVector; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GetLeftJoinTwoTables( const std::string & iTableOne, const std::string & iTableTwo, const FieldWithValue & iOnCondition, bool NonNULLRows) { std::stringstream oQueryStream; oQueryStream << iTableOne; if (NonNULLRows) { oQueryStream << " JOIN "; } else { oQueryStream << " LEFT JOIN "; } oQueryStream << iTableTwo; oQueryStream << " ON "; oQueryStream << iTableOne; oQueryStream << "."; oQueryStream << iOnCondition.Field; oQueryStream << iOnCondition.Operator; oQueryStream << iTableTwo; oQueryStream << "."; oQueryStream << iOnCondition.Value; return oQueryStream.str(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GetLeftJoinThreeTables( const std::string & iTable, const std::string & iTableTwo, const std::string & iTableThree, const FieldWithValue & iOnConditionOne, const FieldWithValue & iOnConditionTwo) { std::stringstream oQueryStream; oQueryStream << "("; oQueryStream << GetLeftJoinTwoTables(iTable, iTableTwo, iOnConditionOne); oQueryStream << ")"; std::string LeftJoinTwo = GetLeftJoinTwoTables(iTable, iTableThree, iOnConditionTwo); oQueryStream << LeftJoinTwo.substr( iTable.size() + 1, LeftJoinTwo.size() ); return oQueryStream.str(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GetGroupBy(const std::string & iColumn, unsigned int iNumberDoublons) { std::stringstream oQueryStream; oQueryStream << " group by "; oQueryStream << iColumn; if ( iNumberDoublons != 0 ) { oQueryStream << " HAVING COUNT("; oQueryStream << iColumn; oQueryStream << ") > "; oQueryStream << iNumberDoublons; } return oQueryStream.str(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string SelectForTracesInfo( const std::vector< std::string > & iSelectedAttributes, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iTableThree, const FieldWithValue & iJoinConditionOne, const FieldWithValue & iJoinConditionTwo, const std::string & iFieldOne, unsigned int iValueFieldOne, const std::string & iIDFieldName, const std::list< unsigned int > & iListIDs) { std::vector< unsigned int > VectIDs( iListIDs.begin(), iListIDs.end() ); std::string What = GetSelectedAttributes(iSelectedAttributes); std::string Where = GetLeftJoinThreeTables(iTableOne, iTableTwo, iTableThree, iJoinConditionOne, iJoinConditionTwo); FieldWithValue FirstPartCondition = { iFieldOne, ConvertToString< unsigned int >(iValueFieldOne), "=" }; std::string Conditions = GetAndORConditions< unsigned int >(FirstPartCondition, iIDFieldName, VectIDs); std::string QueryString = SelectQueryStreamCondition(Where, What, Conditions); return QueryString; } GoFigure2-v0.9.0/Code/IO/vtkPolyDataMySQLMeshWriter.cxx0000644000175000017500000000673211667757442022453 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkPolyDataMySQLMeshWriter.h" #include #include "vtkObjectFactory.h" #include "vtkMath.h" #include "vtkIdList.h" #include "vtkSmartPointer.h" vtkCxxRevisionMacro(vtkPolyDataMySQLMeshWriter, "$Revision$"); vtkStandardNewMacro(vtkPolyDataMySQLMeshWriter); //-------------------------------------------------------------------------- vtkPolyDataMySQLMeshWriter::vtkPolyDataMySQLMeshWriter() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyDataMySQLMeshWriter:: ~vtkPolyDataMySQLMeshWriter() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string vtkPolyDataMySQLMeshWriter::GetMySQLText(vtkPolyData *iPolyData) { vtkIdType N = iPolyData->GetNumberOfPoints(); double pt[3]; std::stringstream oMyString; oMyString << N << " "; for ( vtkIdType i = 0; i < N; i++ ) { iPolyData->GetPoint(i, pt); oMyString << pt[0] << " " << pt[1] << " " << pt[2] << " "; } vtkSmartPointer< vtkIdList > cell_points = vtkSmartPointer< vtkIdList >::New(); vtkIdType NbOfPointsInCell; N = iPolyData->GetNumberOfCells(); oMyString << N << " "; for ( vtkIdType i = 0; i < N; i++ ) { iPolyData->GetCellPoints(i, cell_points); NbOfPointsInCell = cell_points->GetNumberOfIds(); oMyString << NbOfPointsInCell << " "; for ( vtkIdType k = 0; k < NbOfPointsInCell; k++ ) { oMyString << cell_points->GetId(k) << " "; } } return oMyString.str(); } //--------------------------------------------------------------------------GoFigure2-v0.9.0/Code/IO/LineageStructure.h0000644000175000017500000000614111667757442020215 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __LineageStructure_h #define __LineageStructure_h #include "TraceStructure.h" #include "QGoIOConfigure.h" #ifndef DOXYGEN_SHOULD_SKIP_THIS #include "StructureHelper.h" #endif /** \defgroup Lineage Lineage */ /** * \struct LineageStructure * \brief Structure which represent a lineage, and used for * interaction between Visualization and TableWidget * \ingroup Lineage Trace */ class QGOIO_EXPORT LineageStructure : public TraceStructure { public: /** * \brief Default Constructor * */ LineageStructure(); /** Destructor */ ~LineageStructure(); unsigned int TrackRootID; /** Printing one element. std::cout << element << std::endl; */ friend std::ostream & operator<< (std::ostream & os, const LineageStructure & c) { os << "TraceID " << c.TraceID << std::endl; os << "TrackRootID " << c.TrackRootID << std::endl; os << "ActorXY " << c.ActorXY << std::endl; os << "ActorXZ " << c.ActorXZ << std::endl; os << "ActorYZ " << c.ActorYZ << std::endl; os << "ActorXYZ " << c.ActorXYZ << std::endl; os << "Nodes " << c.Nodes << std::endl; os << "Highlighted " << c.Highlighted << std::endl; os << "Visible " << c.Visible << std::endl; os << "RGBA [" << c.rgba[0] << ", " << c.rgba[1] << ", " << c.rgba[2] << ", " << c.rgba[3] << "]" << std::endl; return os; } }; #endif GoFigure2-v0.9.0/Code/IO/GoDBTableWidgetContainer.cxx0000644000175000017500000007713611667757442022051 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBTableWidgetContainer.h" #include #include GoDBTableWidgetContainer::GoDBTableWidgetContainer(std::string iTracesName, std::string iCollectionName, int iImgSessionID) { m_CollectionName = iCollectionName; m_CollectionIDName = m_CollectionName; m_CollectionIDName += "ID"; m_TracesName = iTracesName; m_TracesIDName = m_TracesName; m_TracesIDName += "ID"; m_ImgSessionID = iImgSessionID; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< GoDBTraceInfoForTableWidget > GoDBTableWidgetContainer::GetColumnsInfoForTraceTable() { GoDBTraceInfoForTableWidget temp; //IsSelected column will correspond to the "IsHighLighted": temp.InfoName = "Selected"; temp.ColumnNameTableWidget = ""; temp.ToolTip = "Check/Uncheck "; temp.ToolTip += this->m_TracesName; m_ColumnsInfos.push_back(temp); std::pair< GoDBTraceInfoForTableWidget, std::vector< std::string > > PairTemp; PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the TraceID: temp.InfoName = this->m_TracesIDName; temp.ColumnNameDatabase = this->m_TracesIDName; temp.ColumnNameTableWidget = this->m_TracesIDName; temp.TableNameDatabase = this->m_TracesName; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the CollectionID: if (this->m_CollectionName != "None") { temp.InfoName = this->m_CollectionIDName; temp.ColumnNameDatabase = this->m_CollectionIDName; temp.ColumnNameTableWidget = this->m_CollectionIDName; temp.TableNameDatabase = this->m_TracesName; temp.TableForeignKeyDatabase = this->m_CollectionIDName; temp.TableKeyDatabase = this->m_CollectionIDName; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); } //Get the info for the ColorID of the trace: //check if it is needed in the query ?? std::string ColorTrace = this->m_TracesName; ColorTrace += "Color"; temp.ColumnNameDatabase = "ColorID"; temp.TableNameDatabase = this->m_TracesName; temp.InfoName = ColorTrace; temp.TableForeignKeyDatabase = "ColorID"; temp.TableKeyDatabase = "ColorID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Red value of the trace: temp.ColumnNameDatabase = "Red"; temp.TableNameDatabase = "color"; std::string OtherInfo = "RedFor"; OtherInfo += this->m_TracesName; temp.InfoName = OtherInfo; temp.TableForeignKeyDatabase = "ColorID"; temp.TableKeyDatabase = "ColorID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Green value of the trace: temp.ColumnNameDatabase = "Green"; temp.TableNameDatabase = "color"; OtherInfo = "GreenFor"; OtherInfo += this->m_TracesName; temp.InfoName = OtherInfo; temp.TableForeignKeyDatabase = "ColorID"; temp.TableKeyDatabase = "ColorID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Blue value of the trace: temp.ColumnNameDatabase = "Blue"; temp.TableNameDatabase = "color"; OtherInfo = "BlueFor"; OtherInfo += this->m_TracesName; temp.InfoName = OtherInfo; temp.TableForeignKeyDatabase = "ColorID"; temp.TableKeyDatabase = "ColorID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Alpha value of the trace: temp.ColumnNameDatabase = "Alpha"; temp.TableNameDatabase = "color"; OtherInfo = "AlphaFor"; OtherInfo += this->m_TracesName; temp.InfoName = OtherInfo; temp.TableForeignKeyDatabase = "ColorID"; temp.TableKeyDatabase = "ColorID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the ColorID of the collection: if (this->m_CollectionName != "None") { std::string ColorCollection = this->m_CollectionName; ColorCollection += "Color"; temp.ColumnNameDatabase = "ColorID"; temp.TableNameDatabase = this->m_CollectionName; temp.InfoName = ColorCollection; temp.TableForeignKeyDatabase = this->m_CollectionIDName; temp.TableKeyDatabase = this->m_CollectionIDName; temp.SameFieldForDifferentValues = false; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Red value of the collection: temp.ColumnNameDatabase = "Red"; temp.TableNameDatabase = "color"; OtherInfo = "RedFor"; OtherInfo += this->m_CollectionName; temp.AccessFromTraceTableThroughWhichTable = this->m_CollectionName; temp.InfoName = OtherInfo; temp.TableForeignKeyDatabase = "ColorID"; temp.TableKeyDatabase = "ColorID"; temp.SameFieldForDifferentValues = true; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Green value of the collection: temp.ColumnNameDatabase = "Green"; temp.TableNameDatabase = "color"; OtherInfo = "GreenFor"; OtherInfo += this->m_CollectionName; temp.AccessFromTraceTableThroughWhichTable = this->m_CollectionName; temp.InfoName = OtherInfo; temp.TableForeignKeyDatabase = "ColorID"; temp.TableKeyDatabase = "ColorID"; temp.SameFieldForDifferentValues = true; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Blue value of the collection: temp.ColumnNameDatabase = "Blue"; temp.TableNameDatabase = "color"; OtherInfo = "BlueFor"; OtherInfo += this->m_CollectionName; temp.AccessFromTraceTableThroughWhichTable = this->m_CollectionName; temp.InfoName = OtherInfo; temp.TableForeignKeyDatabase = "ColorID"; temp.TableKeyDatabase = "ColorID"; temp.SameFieldForDifferentValues = true; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Alpha value of the collection: temp.ColumnNameDatabase = "Alpha"; temp.TableNameDatabase = "color"; OtherInfo = "AlphaFor"; OtherInfo += this->m_CollectionName; temp.AccessFromTraceTableThroughWhichTable = this->m_CollectionName; temp.InfoName = OtherInfo; temp.TableForeignKeyDatabase = "ColorID"; temp.TableKeyDatabase = "ColorID"; temp.SameFieldForDifferentValues = true; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); } this->SetCommonInfoForTwoTracesTable(); //Get the info for the PCoord: temp.InfoName = "PCoord"; temp.ColumnNameDatabase = "PCoord"; temp.ColumnNameTableWidget = "Plate"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the RCoord: temp.InfoName = "RCoord"; temp.ColumnNameDatabase = "RCoord"; temp.ColumnNameTableWidget = "Row"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the CCoord: temp.InfoName = "CCoord"; temp.ColumnNameDatabase = "CCoord"; temp.ColumnNameTableWidget = "Column"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the XTile: temp.InfoName = "XTile"; temp.ColumnNameDatabase = "XTileCoord"; temp.ColumnNameTableWidget = "XTile"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the YTile: temp.InfoName = "YTile"; temp.ColumnNameDatabase = "YTileCoord"; temp.ColumnNameTableWidget = "YTile"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the ZTile: temp.InfoName = "ZTile"; temp.ColumnNameDatabase = "ZTileCoord"; temp.ColumnNameTableWidget = "ZTile"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the CoordIDMin of the bounding box: temp.InfoName = "BDCoordIDMin"; temp.ColumnNameDatabase = "CoordIDMin"; temp.TableNameDatabase = this->m_TracesName; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the XMin: temp.InfoName = "BDXMin"; temp.ColumnNameDatabase = "XCoord"; temp.ColumnNameTableWidget = "XMin"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the YMin: temp.InfoName = "BDYMin"; temp.ColumnNameDatabase = "YCoord"; temp.ColumnNameTableWidget = "YMin"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the ZMin: temp.InfoName = "BDZMin"; temp.ColumnNameDatabase = "ZCoord"; temp.ColumnNameTableWidget = "ZMin"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the CoordIDMax of the bounding box: temp.InfoName = "BDCoordIDMax"; temp.ColumnNameDatabase = "CoordIDMax"; temp.TableNameDatabase = this->m_TracesName; temp.TableForeignKeyDatabase = "CoordIDMax"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the XMax: temp.InfoName = "BDXMax"; temp.ColumnNameDatabase = "XCoord"; temp.ColumnNameTableWidget = "XMax"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMax"; temp.TableKeyDatabase = "CoordID"; temp.SameFieldForDifferentValues = true; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the YMax: temp.InfoName = "BDYMax"; temp.ColumnNameDatabase = "YCoord"; temp.ColumnNameTableWidget = "YMax"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMax"; temp.TableKeyDatabase = "CoordID"; temp.SameFieldForDifferentValues = true; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the ZMax: temp.InfoName = "BDZMax"; temp.ColumnNameDatabase = "ZCoord"; temp.ColumnNameTableWidget = "ZMax"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMax"; temp.TableKeyDatabase = "CoordID"; temp.SameFieldForDifferentValues = true; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //this->SetCommonInfoForTwoTracesTable(); return m_ColumnsInfos; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTableWidgetContainer::SetInfoForColumnIsVisible() { GoDBTraceInfoForTableWidget temp; std::pair< GoDBTraceInfoForTableWidget, std::vector< std::string > > PairTemp; //for the column "is visible or not": temp.InfoName = "Show"; temp.ColumnNameTableWidget = "Show"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::list< std::pair< std::string, std::string > > GoDBTableWidgetContainer::GetListColumnsNamesAndToolTipsForTableWidget() { std::list< std::pair< std::string, std::string > > oListColumnNamesAndToolTips; for ( unsigned int i = 0; i < m_ColumnsInfos.size(); i++ ) { if ( m_ColumnsInfos[i].ColumnNameTableWidget != "None" && m_ColumnsInfos[i].ColumnNameTableWidget != "NoneID" ) { std::pair< std::string, std::string > temp; temp.first = m_ColumnsInfos[i].ColumnNameTableWidget; temp.second = m_ColumnsInfos[i].ToolTip; oListColumnNamesAndToolTips.push_back(temp); } } return oListColumnNamesAndToolTips; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< std::string > GoDBTableWidgetContainer::GetNameComputedColumns() { std::vector< std::string > ListComputedColumnNames; for ( unsigned int i = 0; i < m_ColumnsInfos.size(); i++ ) { if ( m_ColumnsInfos[i].ColumnNameTableWidget != "None" && m_ColumnsInfos[i].ColumnNameTableWidget != "NoneID" && m_ColumnsInfos[i].ColumnNameDatabase == "None" && m_ColumnsInfos[i].InfoName != "Selected" ) { ListComputedColumnNames.push_back(m_ColumnsInfos[i].ColumnNameTableWidget); } } return ListComputedColumnNames; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< std::string > GoDBTableWidgetContainer::GetQueryStringForSelectFieldsTables(bool SameFieldsInQuery) { std::vector< std::string > SelectFields; unsigned int i = 0; while ( i < m_ColumnsInfos.size() ) { //if there is info to get from the database and to put directly in the //table widget, and that the column Name in the table widget is not "NoneID" // (that can be found in the lineage table): if ( m_ColumnsInfos[i].ColumnNameDatabase != "None" && //m_ColumnsInfos[i].ColumnNameTableWidget != "None" && m_ColumnsInfos[i].SameFieldForDifferentValues == SameFieldsInQuery && m_ColumnsInfos[i].ColumnNameTableWidget != "NoneID" && m_ColumnsInfos[i].TableNameDatabase != "None" && m_ColumnsInfos[i].TableNameDatabase != "intensity" ) { //record TableNameDatabase.ColumnNameDatabase if it is not already in the // vector: std::string temp = m_ColumnsInfos[i].TableNameDatabase; temp += "."; temp += m_ColumnsInfos[i].ColumnNameDatabase; bool IsSelectFieldsInTheVector = false; unsigned int j = 0; while ( IsSelectFieldsInTheVector == false && j < SelectFields.size() ) { if ( SelectFields[j] == temp ) { IsSelectFieldsInTheVector = true; } j++; } if ( IsSelectFieldsInTheVector == false ) { SelectFields.push_back(temp); } } i++; } return SelectFields; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTableWidgetContainer::FillRowContainer( std::vector< std::vector< std::string > > iResultsFromQuery, std::vector< std::string > iSelectFields, std::string BaseOn) { for ( size_t i = 0; i < iSelectFields.size(); i++ ) { bool HasBeenFound = false; for ( size_t j = 0; j < m_RowContainer.size() && HasBeenFound == false; j++ ) { std::string test = iSelectFields[i]; //for test // purpose std::string test2 = m_RowContainer[j].first.ColumnNameDatabase; //for test // purpose size_t PosColumnNameFound; if ( BaseOn.empty() ) { PosColumnNameFound = iSelectFields[i].find(m_RowContainer[j].first.ColumnNameDatabase); } else { if ( BaseOn == "ColumnNameTableWidget" ) { std::string NameColumn = m_RowContainer[j].first.ColumnNameTableWidget; if ( !NameColumn.empty() ) { PosColumnNameFound = iSelectFields[i].find(NameColumn); } else { PosColumnNameFound = std::string::npos; } } else { std::cout << "The BaseOn you choose doesn't exist" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return; } } if ( PosColumnNameFound != std::string::npos && m_RowContainer[j].second.empty() ) { HasBeenFound = true; for ( size_t RowNumberForQueryResults = 0; RowNumberForQueryResults < iResultsFromQuery.size(); ++RowNumberForQueryResults ) { std::vector< std::string > ResultsFromQueryForOneTrace = iResultsFromQuery[RowNumberForQueryResults]; //j found corresponds to the vector in the row_container to be filled //with the values from the results of the query corresponding to i // column: m_RowContainer[j].second.push_back(ResultsFromQueryForOneTrace[i]); } } } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< std::string > GoDBTableWidgetContainer::GetQueryStringForTraceJoinedTables(bool SameFieldsInQuery) { std::list< std::string > SelectNamesColumns; std::vector< std::string > SelectJoinTables; unsigned int i = 0; //for all the TableNameDatabase in the m_ColumnsInfos: while ( i < m_ColumnsInfos.size() ) { std::string name = m_ColumnsInfos[i].TableNameDatabase; //for test purpose std::string name2 = m_ColumnsInfos[i].ColumnNameDatabase; //for test purpose //check first that the ColumnsInfos has direct infosfrom the database: if ( m_ColumnsInfos[i].TableNameDatabase != "None" && m_ColumnsInfos[i].TableNameDatabase != "intensity" ) { //check that the table is not already in the list: std::vector< std::string >::iterator iter = SelectJoinTables.begin(); bool IsTableInTheList = false; while ( iter != SelectJoinTables.end() && IsTableInTheList == false ) { if ( *iter == m_ColumnsInfos[i].TableNameDatabase ) { IsTableInTheList = true; } ++iter; } //if the table is not in the list,is not the table of the trace and //is accessed during the first query, record the name of the table, //and the traceName.tableforeignkey = tableName.primarykey for the // "on" condition in the "Join" part of the query if ( IsTableInTheList == false && m_ColumnsInfos[i].TableNameDatabase != this->m_TracesName && m_ColumnsInfos[i].SameFieldForDifferentValues == SameFieldsInQuery ) { if ( m_ColumnsInfos[i].AccessFromTraceTableThroughWhichTable == "None" ) { SelectJoinTables.push_back(m_ColumnsInfos[i].TableNameDatabase); std::string OnQuery = this->m_TracesName; OnQuery += "."; OnQuery += m_ColumnsInfos[i].TableForeignKeyDatabase; OnQuery += "="; OnQuery += m_ColumnsInfos[i].TableNameDatabase; OnQuery += "."; OnQuery += m_ColumnsInfos[i].TableKeyDatabase; SelectJoinTables.push_back(OnQuery); } else { if ( m_ColumnsInfos[i].AccessFromTraceTableThroughWhichTable != this->m_CollectionName ) { std::cout << "Pb: access table is different than the Collection Table" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } else { //join the trace table and the collection table (=intermediary // table) SelectJoinTables.push_back(m_ColumnsInfos[i].AccessFromTraceTableThroughWhichTable); std::string OnQuery = this->m_TracesName; OnQuery += "."; OnQuery += this->m_CollectionIDName; OnQuery += "="; OnQuery += this->m_CollectionName; OnQuery += "."; OnQuery += this->m_CollectionIDName; SelectJoinTables.push_back(OnQuery); //join the collection table and the TableNameDatabase of the // ColumnsInfo: SelectJoinTables.push_back(m_ColumnsInfos[i].TableNameDatabase); std::string OnQuerybis = this->m_CollectionName; OnQuerybis += "."; OnQuerybis += m_ColumnsInfos[i].TableForeignKeyDatabase; OnQuerybis += "="; OnQuerybis += m_ColumnsInfos[i].TableNameDatabase; OnQuerybis += "."; OnQuerybis += m_ColumnsInfos[i].TableKeyDatabase; SelectJoinTables.push_back(OnQuerybis); } } //ENDELSE } //ENDIF } //ENDIF i++; } //ENDWHILE return SelectJoinTables; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int GoDBTableWidgetContainer::GetIndexInsideRowContainer(std::string iInfoName) { for ( unsigned int i = 0; i < m_RowContainer.size(); i++ ) { if ( m_RowContainer[i].first.InfoName == iInfoName ) { return i; } } return -1; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBTableWidgetContainer::TWContainerType GoDBTableWidgetContainer::GetContainerLoadedWithAllFromDB( vtkMySQLDatabase *iDatabaseConnector, std::list iListTPs) { this->ClearRowContainerValues(); this->FillRowContainerWithDBValues( iDatabaseConnector, "ImagingsessionID", ConvertToString< unsigned int >(this->m_ImgSessionID), iListTPs); return this->m_RowContainer; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBTableWidgetContainer::TWContainerType GoDBTableWidgetContainer::GetContainerForOneSpecificTrace( vtkMySQLDatabase *iDatabaseConnector, int iTraceID) { this->ClearRowContainerValues(); this->FillRowContainerWithDBValues( iDatabaseConnector, this->m_TracesIDName, ConvertToString< int >(iTraceID) ); return this->m_RowContainer; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTableWidgetContainer::FillRowContainerWithDBValues( vtkMySQLDatabase *iDatabaseConnector, std::string iRestrictionName, std::string iRestrictionValue, std::list iListTimePoints) { /*first, get the right parts of the first query: all the fields except the ones where table.field are already in the query:*/ std::vector< std::string > JoinFirstTablesOnTraceTable = this->GetQueryStringForTraceJoinedTables(false); std::vector< std::string > SelectFirstFields = this->GetQueryStringForSelectFieldsTables(false); //Get the right parts of the second query (with only the remaining fields): std::vector< std::string > JoinSecondTablesOnTraceTable = this->GetQueryStringForTraceJoinedTables(true); std::vector< std::string > SelectSecondFields = this->GetQueryStringForSelectFieldsTables(true); std::vector< std::vector< std::string > > ResultsFirstQuery; std::vector< std::vector< std::string > > ResultsSecondQuery; //then, get the results of the 2 queries: if (iListTimePoints.empty()) { ResultsFirstQuery = GetValuesFromSeveralTables( iDatabaseConnector, this->m_TracesName, SelectFirstFields, iRestrictionName, iRestrictionValue, JoinFirstTablesOnTraceTable, true); ResultsSecondQuery = GetValuesFromSeveralTables( iDatabaseConnector, this->m_TracesName, SelectSecondFields, iRestrictionName, iRestrictionValue, JoinSecondTablesOnTraceTable, false); } else { std::vector OrConditions; std::list::iterator iter = iListTimePoints.begin(); while (iter != iListTimePoints.end() ) { FieldWithValue temp; temp.Field = "coordinate.TCoord"; unsigned int Tp = *iter; temp.Value = ConvertToString(Tp); OrConditions.push_back(temp); ++iter; } ResultsFirstQuery = GetValuesFromSeveralTables( iDatabaseConnector, this->m_TracesName, SelectFirstFields, iRestrictionName, iRestrictionValue, JoinFirstTablesOnTraceTable, true, OrConditions); ResultsSecondQuery = GetValuesFromSeveralTables( iDatabaseConnector, this->m_TracesName, SelectSecondFields, iRestrictionName, iRestrictionValue, JoinSecondTablesOnTraceTable, false, OrConditions); } //fill the row container with the results of the first query: this->FillRowContainer(ResultsFirstQuery, SelectFirstFields); //fill the row container with the results of the second query: this->FillRowContainer(ResultsSecondQuery, SelectSecondFields); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTableWidgetContainer::FillRowContainerForComputedValues( std::vector< std::vector< std::string > > *iComputedValues) { std::vector< std::string > ListComputedNames = this->GetNameComputedColumns(); if ( !ListComputedNames.empty() ) { std::vector< std::vector< std::string > > ComputedValues; if ( iComputedValues == 0 && !ListComputedNames.empty() ) { for ( unsigned int j = 0; j < this->GetNumberOfRows(); j++ ) { std::vector< std::string > EmptyVector; // int Size = iLinkToRowContainer->GetNumberOfRows(); for ( unsigned int i = 0; i < ListComputedNames.size(); i++ ) { EmptyVector.push_back("NV"); } ComputedValues.push_back(EmptyVector); EmptyVector.clear(); } } else { ComputedValues = *iComputedValues; } this->FillRowContainer( ComputedValues, ListComputedNames, "ColumnNameTableWidget"); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< int > GoDBTableWidgetContainer::GetIndexForGroupColor( std::string iGroupName) { std::vector< int > oIndexColor; std::string RedInfoName = "RedFor"; RedInfoName += iGroupName; oIndexColor.push_back( this->GetIndexInsideRowContainer(RedInfoName) ); std::string GreenInfoName = "GreenFor"; GreenInfoName += iGroupName; oIndexColor.push_back( this->GetIndexInsideRowContainer(GreenInfoName) ); std::string BlueInfoName = "BlueFor"; BlueInfoName += iGroupName; oIndexColor.push_back( this->GetIndexInsideRowContainer(BlueInfoName) ); std::string AlphaInfoName = "AlphaFor"; AlphaInfoName += iGroupName; oIndexColor.push_back( this->GetIndexInsideRowContainer(AlphaInfoName) ); return oIndexColor; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTableWidgetContainer::ClearRowContainerValues() { TWContainerType::iterator iter = this->m_RowContainer.begin(); while ( iter != this->m_RowContainer.end() ) { iter->second.clear(); ++iter; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- size_t GoDBTableWidgetContainer::GetNumberOfRows() { if ( !this->m_RowContainer.empty() ) { //return the number of traceID in the container which correspond to the 2nd // column return this->m_RowContainer.at(1).second.size(); } return 0; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< int > GoDBTableWidgetContainer::GetAllTraceIDsInContainer() { int IndexColumn = this->GetIndexInsideRowContainer(this->m_TracesIDName); std::vector< std::string > VectorIDsstr = this->m_RowContainer[IndexColumn].second; std::vector< std::string >::iterator iter = VectorIDsstr.begin(); std::vector< int > vectorInt; while ( iter != VectorIDsstr.end() ) { std::string intstr = *iter; vectorInt.push_back( ss_atoi< int >(intstr) ); ++iter; } return vectorInt; } GoFigure2-v0.9.0/Code/IO/vtkPolyDataMySQLTrackWriter.cxx0000644000175000017500000000657711667757442022632 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkPolyDataMySQLTrackWriter.h" #include #include "vtkObjectFactory.h" #include "vtkMath.h" #include "vtkIdList.h" #include "vtkIntArray.h" #include "vtkPointData.h" #include "vtkSmartPointer.h" vtkCxxRevisionMacro(vtkPolyDataMySQLTrackWriter, "$Revision$"); vtkStandardNewMacro(vtkPolyDataMySQLTrackWriter); //-------------------------------------------------------------------------- vtkPolyDataMySQLTrackWriter::vtkPolyDataMySQLTrackWriter() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyDataMySQLTrackWriter:: ~vtkPolyDataMySQLTrackWriter() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string vtkPolyDataMySQLTrackWriter::GetMySQLText(vtkPolyData *iPolyData) { vtkIdType N = iPolyData->GetNumberOfPoints(); double * pt = NULL; int time = 0; std::stringstream oMyString; oMyString << N << " "; vtkSmartPointer< vtkPoints > points = iPolyData->GetPoints(); // Might create problems because of the safedowncast vtkSmartPointer< vtkIntArray > temporalArray = vtkIntArray::SafeDownCast( iPolyData->GetPointData()->GetArray("TemporalInformation") ); for ( vtkIdType i = 0; i < N; i++ ) { pt = points->GetPoint(i); time = temporalArray->GetValue(i); oMyString << pt[0] << " " << pt[1] << " " << pt[2] << " " << time << " "; } return oMyString.str(); } //--------------------------------------------------------------------------GoFigure2-v0.9.0/Code/IO/GoImage/0000755000175000017500000000000011667757442016065 5ustar mathieumathieuGoFigure2-v0.9.0/Code/IO/GoImage/GoMegaImageStructure.h0000644000175000017500000001607111667757442022266 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef GoMegaImageStructure_H #define GoMegaImageStructure_H // Required for dynamic libs on Windows (QGoIOExport) #include "QGoIOConfigure.h" // includes from external libs // VTK #include "vtkSmartPointer.h" #include "vtkLookupTable.h" #include "vtkImageData.h" #include "vtkPiecewiseFunction.h" #include "vtkImageAccumulate.h" // convert VTK to ITK #include "itkImage.h" #include "itkVTKImageImport.h" #include "vtkImageExport.h" #include "vtkitkAdaptor.h" /** * \struct GoMegaImageStructure * \brief Convenience structure to store visible image * \ingroup GoImage */ struct QGOIO_EXPORT GoMegaImageStructure { unsigned int Index; vtkSmartPointer LUT; vtkSmartPointer Image; std::vector< double > Color; bool Visibility; std::string Name; std::map Alpha; vtkSmartPointer OpacityTF; vtkSmartPointer Histogram; int Gamma; int Min; int Max; /** Constructor */ GoMegaImageStructure(unsigned int iIndex, vtkSmartPointer iLUT, vtkSmartPointer iImage, std::vector< double > iColor, bool iVisibility, std::string iName): Index(iIndex), LUT(iLUT), Color(iColor), Visibility(iVisibility), Name(iName) { Image = iImage; // alpha, modified by user on clicks Alpha[0] = 0; Alpha[255] = Color[3]; // gamma Gamma = 100; // min Min = 0; // max Max = LUT->GetRange()[1]; OpacityTF = vtkSmartPointer::New(); OpacityTF->AddPoint(0, 0); OpacityTF->AddPoint(LUT->GetRange()[1], Color[3]/255); //compute histogram double* range; range = Image->GetScalarRange(); Histogram = vtkSmartPointer::New(); Histogram->SetInput( Image ); Histogram->SetComponentExtent( 0, static_cast(range[1])-static_cast(range[0])-1,0,0,0,0 ); Histogram->SetComponentOrigin( range[0],0,0 ); Histogram->SetComponentSpacing( 1,0,0 ); Histogram->SetIgnoreZero( false ); Histogram->Update(); } // functions to modify the structure through the boost::multiindexcontainer void setGamma(int iGamma) { Gamma = iGamma; } void setMin(int iMin) { Min = iMin; } void setMax(int iMax) { Max = iMax; } void setLUTParameters(int iGamma, int iMin, int iMax) { Gamma = iGamma; Min = iMin; Max = iMax; } void setLUT(vtkSmartPointer iLUT) { LUT = iLUT; } void setVisibility(bool iVisibility) { Visibility = iVisibility; } void setColor(std::vector iColor) { Color = iColor; } void setName(std::string iName) { Name = iName; } void setImage(vtkImageData* iImage) { Image = iImage; // compute new histogram double* range; range = Image->GetScalarRange(); Histogram->RemoveAllInputs(); Histogram->SetInput( Image ); Histogram->SetComponentExtent( 0, static_cast(range[1])-static_cast(range[0])-1,0,0,0,0 ); Histogram->SetComponentOrigin( range[0],0,0 ); Histogram->SetComponentSpacing( 1,0,0 ); Histogram->SetIgnoreZero( false ); Histogram->Update(); } void set_PointsAlpha(std::map< unsigned int, unsigned int> iAlpha) { Alpha = iAlpha; } /* * \brief Convert a vtkImage to a itkImage. If we call after "ExtractROI", * the dimension should be 3 all the time. * (Even if we extract a2D region from a 3d image) * \tparam PixelType type of pixel (unsigned char, etc.) * \tparam VImageDimension dimension of the image (2 or 3) * \param[in] iInput Pointer to a vtkImageData * \return Pointer to an itkImage */ template< class PixelType, const unsigned int VImageDimension > typename itk::Image< PixelType, VImageDimension >::Pointer Convert2ITK() const { //Export VTK image to ITK vtkSmartPointer exporter = vtkSmartPointer::New(); exporter->SetInput(Image); exporter->Update(); // ImageType typedef itk::Image< PixelType, VImageDimension > ImageType; // Import VTK Image to ITK typedef itk::VTKImageImport< ImageType > ImageImportType; typedef typename ImageImportType::Pointer ImageImportPointer; ImageImportPointer importer = ImageImportType::New(); ConnectPipelines< vtkImageExport, ImageImportPointer >( exporter, importer); typename ImageType::Pointer itkImage = importer->GetOutput(); itkImage->DisconnectPipeline(); return itkImage; } friend std::ostream& operator<<(std::ostream& os,const GoMegaImageStructure& e) { os<< "index: "<GetNumberOfTimePoints(); m_BoundsTime[0] = 0; m_BoundsTime[1] = numberOfTimePoints -1; int numberOfChannels = m_LSMReader->GetNumberOfChannels(); m_BoundsChannel[0] = 0; m_BoundsChannel[1] = numberOfChannels -1; m_TimeInterval = m_LSMReader->GetTimeInterval(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoLSMImageProcessor:: initTimePoint(const unsigned int& iTime) { if( iTime != this->m_CurrentTimePoint ) { //check if time point exists if(iTime >= m_BoundsTime[0] && iTime <= m_BoundsTime[1]) { m_MegaImageContainer.clear(); } else { return; } this->m_CurrentTimePoint = iTime; // update the container // Get Number of channels from reader int numberOfChannels = this->getNumberOfChannels(); #ifdef HAS_OPENMP #pragma omp for #endif for( int i = 0; i < numberOfChannels; i++ ) { vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(m_LSMReader->GetFileName()); reader->SetUpdateChannel( i ); reader->SetUpdateTimePoint(iTime); reader->Update(); // get image vtkSmartPointer image = reader->GetOutput(); // capacity of image -> rescale in multichannelmode int type = image->GetScalarSize(); double threshold = pow((double)2, (int)8*type) - 1; m_MaxImage = threshold; // max pixel in image double range = image->GetScalarRange()[1]; if(m_MaxThreshold < range) { m_MaxThreshold = range; } // Get Color double random1 = reader-> GetChannelColorComponent(i, 0); double value1 = random1; double random2 = reader-> GetChannelColorComponent(i, 1); double value2 = random2; double random3 = reader-> GetChannelColorComponent(i, 2); double value3 = random3; std::vector color( 4 ); color[0] = value1; color[1] = value2; color[2] = value3; color[3] = 255; // Create LUT vtkSmartPointer lut = createLUT(color[0], color[1], color[2], color[3]); // create name... std::stringstream channelName; channelName << "Channel "; channelName << i; // Update the MegaImageStructure // image, LUT, channel, time point m_MegaImageContainer.insert(GoMegaImageStructure(i, lut, image, color, true, channelName.str())); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoLSMImageProcessor:: setTimePoint(const unsigned int& iTime) { if( iTime != this->m_CurrentTimePoint ) { //check if time point exists if(iTime < m_BoundsTime[0] && iTime <= m_BoundsTime[1]) { return; } this->m_CurrentTimePoint = iTime; // update the container // Get Number of channels from reader int numberOfChannels = this->getNumberOfChannels(); #ifdef HAS_OPENMP #pragma omp for #endif for( int i = 0; i < numberOfChannels; i++ ) { vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(m_LSMReader->GetFileName()); reader->SetUpdateChannel( i ); reader->SetUpdateTimePoint(iTime); reader->Update(); // get image vtkSmartPointer image = reader->GetOutput(); // could iterate on sth else... GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Index >().find( i ); if(it!=m_MegaImageContainer.get< Index >().end()) { m_MegaImageContainer.get< Index >().modify( it , set_image(image) ); } } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoLSMImageProcessor:: setDoppler(const unsigned int& iTime, const unsigned int& iPrevious) { //to optimize doppler view later on (void) iPrevious; //check if time point exists if(iTime >= m_BoundsTime[0] && iTime <= m_BoundsTime[1]) { } else { return; } std::vector dopplerTime = getDopplerTime(iTime); int dopplerSize = static_cast(this->getDopplerSize()); #ifdef HAS_OPENMP #pragma omp for #endif for(int i=0; i < dopplerSize; ++i) { if(dopplerTime[i] >= 0) { vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(m_LSMReader->GetFileName()); reader->SetUpdateChannel(m_DopplerChannel); reader->SetUpdateTimePoint(dopplerTime[i]); reader->Update(); // get image vtkSmartPointer image = reader->GetOutput(); // hue: 0 to 0.7 double* rgb = vtkMath::HSVToRGB( static_cast(i)/static_cast(dopplerSize),1,1); // color from red to blue std::vector color; color.push_back(rgb[0]*255); color.push_back(rgb[1]*255); color.push_back(rgb[2]*255); color.push_back(255); // Create LUT vtkSmartPointer lut = createLUT(color[0], color[1], color[2], color[3]); // channel name std::stringstream channelName; //channelName << "t: "; channelName << dopplerTime[i]; // Update the MegaImageStructure // image, LUT, channel, time point m_MegaImageContainer.insert(GoMegaImageStructure(dopplerTime[i], lut, image, color, true, channelName.str())); } } } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/GoImage/GoImageProcessor.cxx0000644000175000017500000005134311667757442022027 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoImageProcessor.h" // external library include #include "vtkLookupTable.h" #include "vtkMath.h" #include "vtkImageMapToColors.h" #include "vtkImageBlend.h" #include "vtkPointData.h" #include "vtkImageShiftScale.h" //histogram #include "vtkImageExtractComponents.h" #include "vtkImageAccumulate.h" #include "vtkPiecewiseFunction.h" #include // temp #include "vtkImageWeightedSum.h" //-------------------------------------------------------------------------- GoImageProcessor::GoImageProcessor():m_Output(NULL), m_MaxThreshold(0),m_MaxImage(0), m_DopplerMode(false), m_DopplerStep(1), m_DopplerTime( 3, 0 ), m_DopplerChannel(0), m_DopplerSize(3) { m_CurrentTimePoint = std::numeric_limits< unsigned int >::max(); m_BoundsTime[0] = 0; m_BoundsTime[1] = 0; m_BoundsChannel[0] = 0; m_BoundsChannel[1] = 0; m_Extent[0] = 0; m_Extent[1] = 0; m_Extent[2] = 0; m_Extent[3] = 0; m_Extent[4] = 0; m_Extent[5] = 0; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoImageProcessor::GoImageProcessor(const GoImageProcessor & iE): m_MegaImageContainer(iE.m_MegaImageContainer), m_Output(iE.m_Output), m_DopplerMode(iE.m_DopplerMode), m_DopplerStep(iE.m_DopplerStep), m_DopplerTime(iE.m_DopplerTime), m_DopplerChannel(iE.m_DopplerChannel), m_DopplerSize(iE.m_DopplerSize) { m_BoundsTime[0] = iE.m_BoundsTime[0]; m_BoundsTime[1] = iE.m_BoundsTime[1]; m_BoundsChannel[0] = iE.m_BoundsChannel[0]; m_BoundsChannel[1] = iE.m_BoundsChannel[1]; m_Extent[0] = iE.m_Extent[0]; m_Extent[1] = iE.m_Extent[1]; m_Extent[2] = iE.m_Extent[2]; m_Extent[3] = iE.m_Extent[3]; m_Extent[4] = iE.m_Extent[4]; m_Extent[5] = iE.m_Extent[5]; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoImageProcessor:: ~GoImageProcessor() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer GoImageProcessor:: createLUT(const double& iRed, const double& iGreen, const double& iBlue, const double& iAlpha) { vtkSmartPointer lut = vtkSmartPointer::New(); double* HSV = vtkMath::RGBToHSV(iRed,iGreen,iBlue); lut->SetAlphaRange(0, 1); lut->SetHueRange(HSV[0], HSV[0]); lut->SetSaturationRange(1, 1); lut->SetValueRange(0, 1); lut->SetNumberOfTableValues(m_MaxThreshold); double* range = new double[2]; range[0] = 0; range[1] = m_MaxThreshold; lut->SetRange(range); lut->Build(); delete range; return lut; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer GoImageProcessor:: getLookuptable(const std::string& iName) const { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iName); if(it!=m_MegaImageContainer.get< Name >().end()) { return it->LUT; } return NULL; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer GoImageProcessor:: getLookuptable() const { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Visibility >().find(true); assert(it!=m_MegaImageContainer.get< Visibility >().end()); return it->LUT; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer GoImageProcessor:: getOpacityTransferFunction(const std::string& iName) const { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iName); if(it!=m_MegaImageContainer.get< Name >().end()) { return it->OpacityTF; } return NULL; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector GoImageProcessor:: getOpacityTransferFunctions() { std::vector opacityTFs; typedef GoMegaImageStructureMultiIndexContainer::index::type::iterator IteratorType; IteratorType it0, it1; boost::tuples::tie( it0, it1 ) = m_MegaImageContainer.get< Visibility >().equal_range(true); while( it0 != it1 ) { opacityTFs.push_back( it0->OpacityTF ); ++it0; } return opacityTFs; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector GoImageProcessor:: getColor(const std::string& iName) const { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iName); assert(it!=m_MegaImageContainer.get< Name >().end()); return it->Color; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoImageProcessor:: setColor(const std::string& iName, std::vector& iColor) { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iName); if(it!=m_MegaImageContainer.get< Name >().end()) { m_MegaImageContainer.get< Name >().modify( it , set_color(iColor)); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoImageProcessor:: setLUTParameters(const std::string& iName, int iGamma, int iMin, int iMax) { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iName); if(it!=m_MegaImageContainer.get< Name >().end()) { m_MegaImageContainer.get< Name >().modify( it , set_LUT_Parameters(iGamma, iMin, iMax) ); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector GoImageProcessor:: getLUTParameters(const std::string& iName) { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iName); assert(it!=m_MegaImageContainer.get< Name >().end()); std::vector parameters(3); parameters[0] = it->Gamma; parameters[1] = it->Min; parameters[2] = it->Max; return parameters; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::map GoImageProcessor:: getAlpha(const std::string& iName) const { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iName); assert(it!=m_MegaImageContainer.get< Name >().end()); return it->Alpha; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer GoImageProcessor:: getHistogram(const std::string& iName) const { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iName); assert(it!=m_MegaImageContainer.get< Name >().end()); return it->Histogram; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer GoImageProcessor:: colorImage(vtkSmartPointer iImage, vtkSmartPointer iLUT) { vtkSmartPointer coloredImage = vtkSmartPointer::New(); coloredImage->SetLookupTable(iLUT); coloredImage->SetInput( iImage ); coloredImage->SetOutputFormatToRGB(); coloredImage->SetNumberOfThreads(VTK_MAX_THREADS); coloredImage->ReleaseDataFlagOn(); coloredImage->Update(); return coloredImage->GetOutput(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer GoImageProcessor:: getImageBW(const std::string& iName) { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iName); assert(it!=m_MegaImageContainer.get< Name >().end()); return it->Image; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer GoImageProcessor:: getImageBW(const unsigned int& iIndex) { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Index >().find(iIndex); if(it!=m_MegaImageContainer.get< Index >().end()) { return it->Image; } return NULL; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer GoImageProcessor:: getImageBW() { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Visibility >().find(true); if(it!=m_MegaImageContainer.get< Visibility >().end()) { return it->Image; } return NULL; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector GoImageProcessor:: getColoredImages() { std::vector images; typedef GoMegaImageStructureMultiIndexContainer::index::type::iterator IteratorType; IteratorType it0, it1; boost::tuples::tie( it0, it1 ) = m_MegaImageContainer.get< Visibility >().equal_range(true); while( it0 != it1 ) { // requiered deepcopy.... vtkImageData* image = vtkImageData::New(); image->DeepCopy( this->colorImage( it0->Image, it0->LUT ) ); images.push_back(image); ++it0; } return images; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer GoImageProcessor:: getVisibleImages() { vtkSmartPointer blendedImage = vtkSmartPointer::New(); blendedImage->RemoveAllInputs(); blendedImage->SetBlendModeToCompound(); blendedImage->ReleaseDataFlagOn(); blendedImage->SetNumberOfThreads(VTK_MAX_THREADS); typedef GoMegaImageStructureMultiIndexContainer::index::type::iterator IteratorType; IteratorType it0, it1; boost::tuples::tie( it0, it1 ) = m_MegaImageContainer.get< Visibility >().equal_range(true); int N(0); std::vector< IteratorType > tempVector; while( it0 != it1 ) { tempVector.push_back( it0 ); ++it0; ++N; } #ifdef HAS_OPENMP #pragma omp for #endif for( int j = 0; j < N; j++ ) { it0 = tempVector[j]; vtkSmartPointer temp = this->colorImage(it0->Image, it0->LUT); vtkSmartPointer image = vtkSmartPointer::New(); image->DeepCopy(temp); temp = NULL; blendedImage->AddInput(image); } blendedImage->Update(); double rangeR[2]; blendedImage->GetOutput()->GetPointData()->GetScalars()->GetRange(rangeR, 0); double rangeG[2]; blendedImage->GetOutput()->GetPointData()->GetScalars()->GetRange(rangeG, 1); double rangeB[2]; blendedImage->GetOutput()->GetPointData()->GetScalars()->GetRange(rangeB, 2); double range = std::max(rangeB[1], std::max(rangeR[1], rangeG[1])); if( range != 0. ) { vtkSmartPointer scale = vtkSmartPointer::New(); scale->SetInput(blendedImage->GetOutput()); scale->SetScale(m_MaxImage/range); scale->SetOutputScalarTypeToUnsignedChar(); scale->ReleaseDataFlagOn(); scale->SetNumberOfThreads(VTK_MAX_THREADS); scale->Update(); blendedImage = NULL; return scale->GetOutput(); } return blendedImage->GetOutput(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- unsigned int* GoImageProcessor:: getBoundsTime() { return m_BoundsTime; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- unsigned int* GoImageProcessor:: getBoundsChannel() { return m_BoundsChannel; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int* GoImageProcessor:: getExtent() { if( !m_MegaImageContainer.empty() ) { if( ( m_MegaImageContainer.begin() )->Image ) { return ( m_MegaImageContainer.begin() )->Image->GetExtent(); } } return NULL; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- unsigned int GoImageProcessor:: getNumberOfTimePoints() { return m_BoundsTime[1] - m_BoundsTime[0] + 1; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- unsigned int GoImageProcessor:: getNumberOfChannels() { return m_BoundsChannel[1] - m_BoundsChannel[0] + 1; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- unsigned int GoImageProcessor:: getTimeInterval() const { return m_TimeInterval; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- unsigned int GoImageProcessor:: getDopplerStep() { return m_DopplerStep; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoImageProcessor:: setDopplerStep(unsigned int iStep) { m_DopplerStep = iStep; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector GoImageProcessor:: getDopplerTime(unsigned int iTime) { // get min t point int time = iTime - (m_DopplerSize/2)*m_DopplerStep; for(unsigned int i=0; i(m_BoundsTime[0])) { m_DopplerTime[i] = -1; } if (m_DopplerTime[i] > static_cast(m_BoundsTime[1])) { m_DopplerTime[i] = -1; } } return m_DopplerTime; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoImageProcessor:: setDopplerMode(const bool& iEnable, const unsigned int& iChannel) { m_DopplerMode = iEnable; m_DopplerChannel = iChannel; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool GoImageProcessor:: getDopplerMode() { return m_DopplerMode; } //-------------------------------------------------------------------------- unsigned int GoImageProcessor:: getDopplerChannel() { return m_DopplerChannel; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- unsigned int GoImageProcessor:: getDopplerSize() { return m_DopplerSize; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoImageProcessor:: setDopplerSize(int iSize) { m_DopplerSize = iSize; m_DopplerTime.resize(iSize); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string GoImageProcessor:: getChannelName(const unsigned int& iIndex) { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Index >().find(iIndex); if(it!=m_MegaImageContainer.get< Index >().end()) { return it->Name; } return ""; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoImageProcessor:: visibilityChanged(std::string iName, bool iVisibility) { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iName); if(it!=m_MegaImageContainer.get< Name >().end()) { m_MegaImageContainer.get< Name >().modify( it , set_visibility(iVisibility)); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- unsigned int GoImageProcessor:: getNumberOfVisibleChannels() { typedef GoMegaImageStructureMultiIndexContainer::index::type::iterator IteratorType; IteratorType it0, it1; boost::tuples::tie( it0, it1 ) = m_MegaImageContainer.get< Visibility >().equal_range(true); unsigned int numberOfVisibleChannels( 0 ); while( it0 != it1 ) { ++it0; ++numberOfVisibleChannels; } return numberOfVisibleChannels; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoImageProcessor:: updatePoints(std::string iName, std::map< unsigned int, unsigned int> iPointsAlpha) { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iName); if(it!=m_MegaImageContainer.get< Name >().end()) { m_MegaImageContainer.get< Name >().modify( it , set_PointsAlpha(iPointsAlpha)); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int GoImageProcessor:: getMaxThreshold() { return m_MaxThreshold; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int GoImageProcessor:: getMaxImage() { return m_MaxImage; } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/GoImage/GoImageProcessor.h0000644000175000017500000004035411667757442021454 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef GoImageProcessor_H #define GoImageProcessor_H // Required for dynamic libs on Windows (QGoIOExport) #include "QGoIOConfigure.h" // external library include // VTK #include "vtkSmartPointer.h" // ITK #include "itkInvertIntensityImageFilter.h" // BOOST #include #include #include #include // include project #include "GoMegaImageStructure.h" // external include class vtkLookupTable; class vtkImageData; class vtkImageAccumulate; class QString; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /** \struct set_visibility \brief change visibility of given structure \sa GoMegaImageStructure */ struct set_visibility { set_visibility(bool iVisibility):visibility(iVisibility){} void operator()(GoMegaImageStructure& iStructure) { iStructure.setVisibility(visibility); } private: bool visibility; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /** \struct set_color \brief change color of given structure \sa GoMegaImageStructure */ struct set_color { set_color(std::vector iColor):color(iColor){} void operator()(GoMegaImageStructure& iStructure) { iStructure.setColor(color); } private: std::vector color; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /** \struct set_LUT_Parameters \brief change parameters of LUT \sa GoMegaImageStructure */ struct set_LUT_Parameters { set_LUT_Parameters(int iGamma, int iMin, int iMax): gamma(iGamma), min(iMin), max(iMax){} void operator()(GoMegaImageStructure& iStructure) { iStructure.setLUTParameters(gamma, min, max); } private: int gamma; int min; int max; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /** \struct set_image \brief change visibility of given structure \sa GoMegaImageStructure */ struct set_image { set_image(vtkImageData* iImage):image(iImage){} void operator()(GoMegaImageStructure& iStructure) { iStructure.setImage(image); } private: vtkImageData* image; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /** \struct set_image \brief change visibility of given structure \sa GoMegaImageStructure */ struct set_PointsAlpha { set_PointsAlpha(std::map< unsigned int, unsigned int> iPoints):points(iPoints){} void operator()(GoMegaImageStructure& iStructure) { iStructure.set_PointsAlpha(points); } private: std::map< unsigned int, unsigned int> points; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /* tags for accessing the corresponding indices of GoMegaImageStructure */ struct Index{}; struct Visibility{}; struct Name{}; /* Define a multi_index_container of images with following indices: * - a non-unique index sorted by GoMegaImageStructure::Index, * - a non-unique index sorted by GoMegaImageStructure::Visibility, * - a non-unique index sorted by GoMegaImageStructure::Channel, */ typedef boost::multi_index_container< GoMegaImageStructure, boost::multi_index::indexed_by< boost::multi_index::ordered_non_unique< boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoMegaImageStructure,unsigned int,Index)>, boost::multi_index::ordered_non_unique< boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoMegaImageStructure,bool,Visibility)>, boost::multi_index::hashed_non_unique< boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoMegaImageStructure,std::string,Name)> > > GoMegaImageStructureMultiIndexContainer; //----------------------------------------------------------------------------- /** \defgroup GoImage GoImage */ /** * \struct GoImageProcessor * \brief Interface between image reader and vtkImageData * \ingroup GoImage */ class QGOIO_EXPORT GoImageProcessor { public: /** Constructor */ GoImageProcessor(); /** Constructor */ GoImageProcessor( const GoImageProcessor& iE ); /** Destructor */ virtual ~GoImageProcessor(); /** Printing one element. std::cout << element << std::endl; */ friend std::ostream & operator<< (std::ostream & os, const GoImageProcessor & c) { //os << "TraceID " << c.TraceID << std::endl; return os; } // LUT //--------------------------------------------------------------------------- /** * \brief create a lookuptable (LUT) given r, g, b, a and range * LUT will go from black to the color. * \param[in] iRed red value * \param[in] iGreen green value * \param[in] iBlue blue value * \param[in] iAlpha alpha value * \return new LUT **/ vtkSmartPointer createLUT(const double& iRed, const double& iGreen, const double& iBlue, const double& iAlpha); /** * \brief get LUT from channel name. Useful for the Transfer function editor. * \param[in] iName channel of interest. * (See getChannelName(index) to get channel name from index.) * \return pointer to LUT **/ vtkSmartPointer getLookuptable(const std::string& iName) const; /** * \brief get LUT of the first visible channel. Useful is we are in single channel visualization mode. * \param[in] iName channel of interest. * (See getChannelName(index) to get channel name from index.) * \return pointer to LUT **/ vtkSmartPointer getLookuptable() const; // opacity transfer functions //--------------------------------------------------------------------------- /** * \brief get opacity from channel name. Useful for the transfer function editor while volume rendering. * \param[in] iName channel of interest. * (See getChannelName(index) to get channel name from index.) * \return pointer to opacity Transfer Function **/ vtkSmartPointer getOpacityTransferFunction(const std::string& iName) const; /** * \brief get vector of visible opacity transfer functions. Useful for the transfer function editor while volume rendering. * \return vector of pointer to opacity TF **/ std::vector getOpacityTransferFunctions(); // colors //--------------------------------------------------------------------------- /** * \brief get color from channel name. * \param[in] iName channel of interest. * (See getChannelName(index) to get channel name from index.) * \return vector of double: rgba [0-255] **/ std::vector getColor(const std::string& iName) const; void setColor(const std::string& iName, std::vector& iColor); void setLUTParameters(const std::string& iName, int iGamma, int iMin, int iMax); std::vector getLUTParameters(const std::string& iName); /** * \brief get points to update r, g, b and a TFs in TF editor. * \param[in] iName channel of interest. * (See getChannelName(index) to get channel name from index.) * \return vector of map.1 vector: rgba, map: position/value **/ std::map getAlpha( const std::string& iName) const; /** * \brief store points from TF editor * \param[in] iChannel channel of interest. * \param[in] iPointsRGBA new points **/ void updatePoints(std::string iChannel, std::map< unsigned int, unsigned int> iPointsAlpha); /** * \brief get histogram from 1 channel image * \param[in] iChannel channel of interest. * \return pointer to histogram **/ vtkSmartPointer< vtkImageAccumulate> getHistogram(const std::string& iName) const; /** * \brief load all the channels for the given time point into the * GoMegaImageStructure * \param[in] iTime requested time point **/ virtual void initTimePoint(const unsigned int& iTime) = 0; /** * \brief update images from the current GoMegaImageStructure * \param[in] iTime requested time point **/ virtual void setTimePoint(const unsigned int& iTime) = 0; /** * \brief load all time points of the given channel into the * GoMegaImageStructure. Called Doppler View. * \param[in] iTime requested central time point * \param[in] iPrevious -to be used for optimization? * \note need to store parameters if we want to go through volume * efficiently (not reload everything all the time) **/ virtual void setDoppler(const unsigned int& iTime, const unsigned int& iPrevious) = 0; // images //--------------------------------------------------------------------------- /** * \brief get raw (not colored) image given index * \param[in] iIndex requested index * \note Used to compute the mesh attributes at load time * \return raw image. **/ vtkSmartPointer getImageBW(const std::string& iName); vtkSmartPointer getImageBW(const unsigned int& iIndex); /** * \brief get first raw (not colored) visible image * \param[in] iIndex requested index * \return raw image. **/ vtkSmartPointer getImageBW(); /** * \brief get name of a channel given its index. * \param[in] iIndex requested index * \return channel name **/ std::string getChannelName(const unsigned int& iIndex); /** * \brief get all the visible images colored separately (N images). * \return vector containing all the visible colored images **/ std::vector getColoredImages(); /** * \brief get an ITK image (vs vtkImageData) given its index * \return ITK image pointer **/ template< class PixelType, const unsigned int VImageDimension > typename itk::Image< PixelType, VImageDimension >::Pointer getImageITK(std::string iIndex, bool iIsInverted = false) { GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Name >().find(iIndex); assert(it!=m_MegaImageContainer.get< Name >().end()); if(iIsInverted) { //get image and invert it typedef itk::Image ImageType; typedef itk::InvertIntensityImageFilter InvertFilterType; typename InvertFilterType::Pointer invertFilter = InvertFilterType::New(); invertFilter->SetInput( it->Convert2ITK() ); invertFilter->Update(); typename ImageType::Pointer itkImage = invertFilter->GetOutput(); itkImage->DisconnectPipeline(); return itkImage; } else { return it->Convert2ITK(); } return NULL; } /** * \brief get all the -visible- images present in the containerl. * Colors the image and combuine them into 1 image. * \return 1 colored image. **/ vtkSmartPointer getVisibleImages(); // Image parameters //--------------------------------------------------------------------------- unsigned int* getBoundsTime(); unsigned int* getBoundsChannel(); int* getExtent(); unsigned int getNumberOfTimePoints(); unsigned int getNumberOfChannels(); unsigned int getTimeInterval() const; // Doppler parameters //--------------------------------------------------------------------------- unsigned int getDopplerStep(); void setDopplerStep(unsigned int iStep); std::vector getDopplerTime(unsigned int iTime); void setDopplerMode(const bool& iEnable, const unsigned int& iChannel); bool getDopplerMode(); unsigned int getDopplerChannel(); void setDopplerSize(int iSize); unsigned int getDopplerSize(); /** * \brief change visibility of one channel given its name. * \param[in] iName channel of interest * \param[in] iVisibility new visibility **/ void visibilityChanged(std::string iName, bool iVisibility); /** * \brief get number of visible channels * \return number of visible channels **/ unsigned int getNumberOfVisibleChannels(); int getMaxThreshold(); int getMaxImage(); protected: /* * \brief Color an image given the original image and a lookuptable (LUT) * \param[in] iImage image to be colored * \param[in] iLUT LUT to be applied to the image * \return colored image */ vtkSmartPointer colorImage(vtkSmartPointer iImage, vtkSmartPointer iLUT); GoMegaImageStructureMultiIndexContainer m_MegaImageContainer; vtkSmartPointer m_Output; unsigned int m_CurrentTimePoint; // Image parameters //-------------------- unsigned int m_BoundsTime[2]; unsigned int m_BoundsChannel[2]; int m_Extent[6]; unsigned int m_TimeInterval; int m_MaxThreshold; int m_MaxImage; //-------------------- // Doppler view parameters //-------------------- bool m_DopplerMode; unsigned int m_DopplerStep; std::vector m_DopplerTime; unsigned int m_DopplerChannel; unsigned int m_DopplerSize; //-------------------- private: // overload "=" operator GoImageProcessor& operator=(const GoImageProcessor &rhs) { // Only do assignment if RHS is a different object from this. if (this != &rhs) { this->m_MegaImageContainer = rhs.m_MegaImageContainer; this->m_BoundsTime[0] = rhs.m_BoundsTime[0]; this->m_BoundsTime[1] = rhs.m_BoundsTime[1]; this->m_BoundsChannel[0] = rhs.m_BoundsChannel[0]; this->m_BoundsChannel[1] = rhs.m_BoundsChannel[1]; this->m_Extent[0] = rhs.m_Extent[0]; this->m_Extent[1] = rhs.m_Extent[1]; this->m_Extent[2] = rhs.m_Extent[2]; this->m_Extent[3] = rhs.m_Extent[3]; this->m_Extent[4] = rhs.m_Extent[4]; this->m_Extent[5] = rhs.m_Extent[5]; this->m_TimeInterval = rhs.m_TimeInterval; this->m_MaxThreshold = rhs.m_MaxThreshold; this->m_DopplerMode = rhs.m_DopplerMode; this->m_DopplerStep = rhs.m_DopplerStep; this->m_DopplerTime = rhs.m_DopplerTime; this->m_DopplerChannel = rhs.m_DopplerChannel; } return *this; } }; #endif // GoImageProcessor_H GoFigure2-v0.9.0/Code/IO/GoImage/GoMegaImageProcessor.cxx0000644000175000017500000003000211667757442022606 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoMegaImageProcessor.h" #include "vtkMath.h" //-------------------------------------------------------------------------- void GoMegaImageProcessor:: setReader(itk::MegaCaptureReader::Pointer iReader) { m_MegaImageReader = iReader; // update general parameters //-------------------- // todo Nicolas- Create a method for that... m_BoundsTime[0] = m_MegaImageReader->GetMinTimePoint(); m_BoundsTime[1] = m_MegaImageReader->GetMaxTimePoint(); m_BoundsChannel[0] = m_MegaImageReader->GetMinChannel(); m_BoundsChannel[1] = m_MegaImageReader->GetMaxChannel(); m_TimeInterval = m_MegaImageReader->GetTimeInterval(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoMegaImageProcessor:: initTimePoint(const unsigned int& iTime) { if( iTime != this->m_CurrentTimePoint ) { //check if time point exists if(iTime >= m_BoundsTime[0] && iTime <= m_BoundsTime[1]) { this->m_CurrentTimePoint = iTime; m_MegaImageReader->SetTimePoint(iTime); m_MegaImageReader->Update(); m_MegaImageContainer.clear(); } else { return; } // update the container // Get Number of channels from reader int n = getNumberOfChannels(); // while(numberOfChannels>0) #ifdef HAS_OPENMP #pragma omp parallel for #endif for( int kk = 0; kk < n; ++kk ) { int numberOfChannels = n - ( kk + 1 ); // --numberOfChannels; // Get useful information from the reader // Nicolas Get Image or get output...? vtkSmartPointer image = m_MegaImageReader->GetOutput(numberOfChannels); // capacity of image -> rescale in multichannelmode int type = image->GetScalarSize(); double threshold = pow((double)2, (int)8*type) - 1; m_MaxImage = threshold; // max pixel in image double range = image->GetScalarRange()[1]; if(m_MaxThreshold < range) { m_MaxThreshold = range; } // Get Color std::vector >channelColor = m_MegaImageReader->GetChannelColor(); double random1 = channelColor[numberOfChannels][0]; double value1 = random1; double random2 = channelColor[numberOfChannels][1]; double value2 = random2; double random3 = channelColor[numberOfChannels][2]; double value3 = random3; std::vector color( 4 ); color[0] = value1; color[1] = value2; color[2] = value3; color[3] = 255; // Create LUT vtkSmartPointer lut = createLUT(color[0], color[1], color[2], color[3]); // create name... std::stringstream channelName; channelName << "Channel "; channelName << numberOfChannels; // Update the MegaImageStructure // image, LUT, channel, time point m_MegaImageContainer.insert(GoMegaImageStructure(numberOfChannels, lut, image, color, true, channelName.str())); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoMegaImageProcessor:: setTimePoint(const unsigned int& iTime) { if( iTime != this->m_CurrentTimePoint ) { //check if time point exists if(iTime >= m_BoundsTime[0] && iTime <= m_BoundsTime[1]) { m_MegaImageReader->SetTimePoint(iTime); m_MegaImageReader->Update(); } else { return; } this->m_CurrentTimePoint = iTime; // update the container // Get Number of channels from reader //int numberOfChannels = getNumberOfChannels(); int n = getNumberOfChannels(); #ifdef HAS_OPENMP #pragma omp parallel for #endif for( int kk = 0; kk < n; kk++ ) { int numberOfChannels = n - ( kk + 1 ); // Get useful information from the reader // Nicolas Get Image or get output...? vtkSmartPointer image = m_MegaImageReader->GetOutput(numberOfChannels); // capacity of image -> rescale in multichannelmode int type = image->GetScalarSize(); double threshold = pow((double)2, (int)8*type) - 1; m_MaxImage = threshold; // max pixel in image double range = image->GetScalarRange()[1]; if(m_MaxThreshold < range) { m_MaxThreshold = range; } GoMegaImageStructureMultiIndexContainer::index::type::iterator it = m_MegaImageContainer.get< Index >().find(numberOfChannels); if(it!=m_MegaImageContainer.get< Index >().end()) { m_MegaImageContainer.get< Index >().modify( it , set_image(image) ); } } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoMegaImageProcessor:: setDoppler(const unsigned int& iTime, const unsigned int& iPrevious) { //to optimize doppler view later on (void) iPrevious; //check if time point exists if(iTime >= m_BoundsTime[0] && iTime <= m_BoundsTime[1]) { m_MegaImageReader->SetTimePoint(iTime); m_MegaImageReader->Update(); m_MegaImageContainer.clear(); } else { return; } std::vector dopplerTime = getDopplerTime(iTime); int DopplerSize = static_cast< int >( this->getDopplerSize() ); #ifdef HAS_OPENMP #pragma omp parallel for #endif for(int i=0; i < DopplerSize; ++i) { if(dopplerTime[i] >= 0) { // Get useful information from the reader // Nicolas Get Image or get output...? vtkSmartPointer image = m_MegaImageReader->GetImage(m_DopplerChannel,dopplerTime[i]); // hue: 0 to 0.7 double* rgb = vtkMath::HSVToRGB( static_cast(i)/static_cast(getDopplerSize()),1,1); // color from red to blue std::vector color; color.push_back(rgb[0]*255); color.push_back(rgb[1]*255); color.push_back(rgb[2]*255); color.push_back(255); // Create LUT vtkSmartPointer lut = createLUT(color[0], color[1], color[2], color[3]); // channel name std::stringstream channelName; //channelName << "t: "; channelName << dopplerTime[i]; // Update the MegaImageStructure // image, LUT, channel, time point m_MegaImageContainer.insert(GoMegaImageStructure(dopplerTime[i], lut, image, color, true, channelName.str())); } } /* vtkSmartPointer< vtkImageAppendComponents > append_filter = vtkSmartPointer< vtkImageAppendComponents >::New(); // if step != 1 and we have previous and next time point loaded if( m_DopplerStep != 1 || iPreviousT == 0 ) { // resize internal image // clean the vector since is is a vector of smartpointers m_InternalImages.resize(3, NULL); vtkSmartPointer< vtkImageData > i0 = vtkSmartPointer< vtkImageData >::New(); i0->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t0) ); m_InternalImages[0] = i0; append_filter->AddInput(m_InternalImages[0]); vtkSmartPointer< vtkImageData > i1 = vtkSmartPointer< vtkImageData >::New(); i1->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t1) ); m_InternalImages[1] = i1; append_filter->AddInput(m_InternalImages[1]); vtkSmartPointer< vtkImageData > i2 = vtkSmartPointer< vtkImageData >::New(); i2->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t2) ); m_InternalImages[2] = i2; append_filter->AddInput(m_InternalImages[2]); } else { // if we go FORWARD and step == 1 if( iPreviousT < m_TCoord) { // assume we imcrease t point all the time for testing vtkSmartPointer< vtkImageData > i0 = vtkSmartPointer< vtkImageData >::New(); i0->ShallowCopy(m_InternalImages[1]); // clean smartpointer m_InternalImages[0] = NULL; m_InternalImages[0] = i0; append_filter->AddInput(m_InternalImages[0]); vtkSmartPointer< vtkImageData > i1 = vtkSmartPointer< vtkImageData >::New(); i1->ShallowCopy(m_InternalImages[2]); // clean smartpointer m_InternalImages[1] = NULL; m_InternalImages[1] = i1; append_filter->AddInput(m_InternalImages[1]); vtkSmartPointer< vtkImageData > i2 = vtkSmartPointer< vtkImageData >::New(); i2->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t2) ); // clean smartpointer m_InternalImages[2] = NULL; m_InternalImages[2] = i2; append_filter->AddInput(m_InternalImages[2]); } // if we go BACKWARD and step == 1 else { vtkSmartPointer< vtkImageData > i2 = vtkSmartPointer< vtkImageData >::New(); i2->ShallowCopy(m_InternalImages[1]); // clean smartpointer m_InternalImages[2] = NULL; m_InternalImages[2] = i2; append_filter->AddInput(m_InternalImages[2]); vtkSmartPointer< vtkImageData > i1 = vtkSmartPointer< vtkImageData >::New(); i1->ShallowCopy(m_InternalImages[0]); // clean smartpointer m_InternalImages[1] = NULL; m_InternalImages[1] = i1; append_filter->AddInput(m_InternalImages[1]); vtkSmartPointer< vtkImageData > i0 = vtkSmartPointer< vtkImageData >::New(); i0->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t0) ); // clean smartpointer m_InternalImages[0] = NULL; m_InternalImages[0] = i0; append_filter->AddInput(m_InternalImages[0]); } } */ } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/vtkImageWriterHelper.h0000644000175000017500000000516411667757442021040 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkImageWriterHelper_h #define __vtkImageWriterHelper_h #include class vtkImageData; //------------------------------------------------------------------------- template< class TWriter > void vtkWriteImage(vtkImageData *iImage, const std::string & iFileName) { typedef TWriter WriterType; WriterType *writer = WriterType::New(); writer->SetInput(iImage); writer->SetFileName( iFileName.c_str() ); writer->Write(); writer->Delete(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TWriter > void vtkWriteImage(vtkImageData *iImage, const QString & iFileName) { vtkWriteImage< TWriter >( iImage, iFileName.toStdString() ); } //------------------------------------------------------------------------- #endif GoFigure2-v0.9.0/Code/IO/vtkPolyDataMySQLContourWriter.cxx0000644000175000017500000000601511667757442023202 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkPolyDataMySQLContourWriter.h" #include #include "vtkObjectFactory.h" #include "vtkMath.h" #include "vtkIdList.h" #include "vtkSmartPointer.h" vtkCxxRevisionMacro(vtkPolyDataMySQLContourWriter, "$Revision$"); vtkStandardNewMacro(vtkPolyDataMySQLContourWriter); //-------------------------------------------------------------------------- vtkPolyDataMySQLContourWriter::vtkPolyDataMySQLContourWriter() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyDataMySQLContourWriter:: ~vtkPolyDataMySQLContourWriter() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string vtkPolyDataMySQLContourWriter::GetMySQLText(vtkPolyData *iPolyData) { vtkIdType N = iPolyData->GetNumberOfPoints(); double pt[3]; std::stringstream oMyString; oMyString << N << " "; for ( vtkIdType i = 0; i < N; i++ ) { iPolyData->GetPoint(i, pt); oMyString << pt[0] << " " << pt[1] << " " << pt[2] << " "; } return oMyString.str(); } //--------------------------------------------------------------------------GoFigure2-v0.9.0/Code/IO/TreeNodeStructure.h0000644000175000017500000000611411667757442020356 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __TreeNodeStructure_h #define __TreeNodeStructure_h #include "TraceStructure.h" #include "QGoIOConfigure.h" #ifndef DOXYGEN_SHOULD_SKIP_THIS #include "StructureHelper.h" #endif #include "vtkActor.h" #include "vtkPolyData.h" /** * \struct TreeNodeStructure * \brief Structure which represent a tree node. * \ingroup Track Trace */ template class QGOIO_EXPORT TreeNodeStructure : public TraceStructure { public: TreeNodeStructure() : TraceStructure(), m_Mother( NULL ) { m_Child.resize(0); } TreeNodeStructure( const TreeNodeStructure & iE ) : TraceStructure( iE ), m_Mother(iE.m_Mother) { m_Child = iE.m_Child; } ~TreeNodeStructure(){}; virtual void ReleaseData() { if(ActorXY) { ActorXY->Delete(); ActorXY = NULL; } if(ActorXZ) { ActorXZ->Delete(); ActorXZ = NULL; } if(ActorYZ) { ActorYZ->Delete(); ActorYZ = NULL; } if(ActorXYZ) { ActorXYZ->Delete(); ActorXYZ = NULL; } if(Nodes) { Nodes->Delete(); Nodes = NULL; } } const bool IsRoot() const { return ( this->m_Mother == NULL ); } const bool IsLeaf() const { return ( !this->m_Child.size() ); } T* m_Mother; std::vector m_Child; }; #endif GoFigure2-v0.9.0/Code/IO/StructureHelper.h0000644000175000017500000000404211667757442020066 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __StructureHelper_h #define __StructureHelper_h #ifndef DOXYGEN_SHOULD_SKIP_THIS // General attributes struct TraceID {}; struct CollectionID {}; struct TCoord {}; struct Highlighted {}; struct Visible {}; // Lineage specific struct TrackRootID{}; #endif #endif GoFigure2-v0.9.0/Code/IO/SelectQueryDatabaseHelper.cxx0000644000175000017500000016663511667757442022354 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "SelectQueryDatabaseHelper.h" #include "vtkMySQLDatabase.h" #include "vtkSQLQuery.h" #include "vtkStdString.h" #include "vtkSmartPointer.h" #include "vtkVariant.h" #include "vtkPolyDataMySQLContourReader.h" #include "vtkPolyDataMySQLMeshReader.h" #include "vtkPolyDataMySQLTrackReader.h" #include #include #include std::vector< std::string > ListAllValuesForOneColumn(vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnName, const std::string & TableName, std::string OrderByColumnName) { std::string QueryString = SelectQueryStream(TableName, ColumnName, OrderByColumnName); return ExecuteSelectQuery< std::vector< std::string > >(DatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ boost::unordered_map< std::string, std::string > MapTwoColumnsFromTable( vtkMySQLDatabase *DatabaseConnector, const std::vector< std::string > & iColumnNames, const std::string & iTableName, std::string iField, std::string iValue) { boost::unordered_map< std::string, std::string > Result = boost::unordered_map< std::string, std::string >(); if ( iColumnNames.size() != 2 ) { std::cout << "can not map if the size of the vector for the selected fields is different than 2 "; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return Result; } std::string QueryString; if ( iField.empty() ) { QueryString = SelectQueryStream(iTableName, iColumnNames); } else { QueryString = SelectQueryStreamCondition(iTableName, iColumnNames, iField, iValue); } vtkSQLQuery *query = DatabaseConnector->GetQueryInstance(); query->SetQuery( QueryString.c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "List of all fields query failed" << query->GetLastErrorText() ); query->Delete(); return Result; } while ( query->NextRow() ) { Result[query->DataValue(0).ToString()] = query->DataValue(1).ToString(); } query->Delete(); return Result; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::pair< std::string, std::string > > VectorTwoColumnsFromTable(vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnNameOne, const std::string & ColumnNameTwo, const std::string & TableName, const std::string & OrderByColumnName) { std::vector< std::pair< std::string, std::string > > result; std::vector< std::string > ColumnNames(2); ColumnNames[0] = ColumnNameOne; ColumnNames[1] = ColumnNameTwo; std::string QueryString = SelectQueryStream(TableName, ColumnNames, OrderByColumnName); vtkSQLQuery *query = DatabaseConnector->GetQueryInstance(); query->SetQuery( QueryString.c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "select 2 columns query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return result; } while ( query->NextRow() ) { std::pair< std::string, std::string > Pair; Pair.first = query->DataValue(0).ToString(); Pair.second = query->DataValue(1).ToString(); result.push_back(Pair); } query->Delete(); return result; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > ListSpecificValuesForRow( vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, const std::string & field, const std::string & value) { std::string QueryString = SelectQueryStreamCondition(TableName, "*", field, value); return ExecuteSelectQuery< std::vector< std::string > >(DatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ int FindOneID(vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::string & value) { int ID = -1; std::string QueryString = SelectQueryStreamCondition(TableName, ColumnName, field, value); std::vector< std::string > Results = ExecuteSelectQuery< std::vector< std::string > >( DatabaseConnector, QueryString); if ( Results.size() > 1 ) { std::cout << "there is not an unique ID"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return ID; } if ( !Results.empty() ) { ID = atoi( Results[0].c_str() ); } return ID; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ int FindOneID(vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::vector< FieldWithValue > & iConditions) { std::string QueryString = SelectQueryStreamListConditions(TableName, ColumnName, iConditions, "AND"); int ID = -1; std::vector< int > Results = ExecuteSelectQuery< std::vector< int > >( DatabaseConnector, QueryString); if ( !Results.empty() ) { ID = Results[0]; } return ID; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > FindSeveralIDs(vtkMySQLDatabase *iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::vector< FieldWithValue > & iConditions) { std::string QueryString = SelectQueryStreamListConditions(TableName, ColumnName, iConditions, "AND"); return ExecuteSelectQuery< std::vector< std::string > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > ListSpecificValuesForOneColumn( vtkMySQLDatabase *iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::string & value, //bool Distinct, bool ExcludeZero) { std::vector< FieldWithValue > VectorConditions; FieldWithValue EqualValue = { field, value, "=" }; VectorConditions.push_back(EqualValue); if ( ExcludeZero ) { FieldWithValue DiffZero = { ColumnName, "0", "<>" }; VectorConditions.push_back(DiffZero); } std::string QueryString = SelectQueryStreamListConditions(TableName, ColumnName, VectorConditions, "AND"); return ExecuteSelectQuery< std::vector< std::string > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > ListSpecificValuesForOneColumn( vtkMySQLDatabase *iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::string & value, const std::string & ColumnNameOrder) { std::string QueryString = SelectQueryStreamCondition(TableName, ColumnName, field, value, ColumnNameOrder); return ExecuteSelectQuery< std::vector< std::string > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > ListSpecificValuesForOneColumn( vtkMySQLDatabase *iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::vector< std::string > & VectorValues, bool Distinct, bool ExcludeZero) { std::string Conditions; if ( ExcludeZero ) { std::vector< FieldWithValue > VectorConditions(1); FieldWithValue DiffZero = { ColumnName, "0", "<>" }; VectorConditions[0] = DiffZero; Conditions = GetConditions(VectorConditions, "AND"); Conditions = Conditions.substr(0, Conditions.size() - 1); Conditions += " AND "; } Conditions += GetConditions(field, VectorValues, "OR"); if ( ExcludeZero ) { Conditions += ")"; } std::string QueryString = SelectQueryStreamCondition(TableName, ColumnName, Conditions, Distinct); return ExecuteSelectQuery< std::vector< std::string > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::list< unsigned int > ListSpecificValuesForOneColumn( vtkMySQLDatabase *iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::list< unsigned int > & iListValues, bool Distinct, bool ExcludeZero) { std::vector< unsigned int > VectorValues( iListValues.begin(), iListValues.end() ); std::string Conditions; if ( ExcludeZero ) { std::vector< FieldWithValue > VectorConditions(1); FieldWithValue DiffZero = { ColumnName, "0", "<>" }; VectorConditions[0] = DiffZero; Conditions = GetConditions(VectorConditions, "AND"); Conditions = Conditions.substr(0, Conditions.size() - 1); if ( !VectorValues.empty() ) { Conditions += " AND "; } } Conditions += GetConditions(field, VectorValues, "OR"); if ( ExcludeZero ) { Conditions += ")"; } std::string QueryString = SelectQueryStreamCondition(TableName, ColumnName, Conditions, Distinct); return ExecuteSelectQuery< std::list< unsigned int > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::list< unsigned int > ListSpecificValuesForOneColumn( vtkMySQLDatabase *iDatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & fieldOne, const std::list< unsigned int > & ListValuesOne, const std::string & fieldTwo, const std::string & ValueFieldTwo) { std::vector< unsigned int > VectorValuesOne( ListValuesOne.begin(), ListValuesOne.end() ); FieldWithValue AndCondition = { fieldTwo, ValueFieldTwo, "=" }; std::string Conditions = GetAndORConditions(AndCondition, fieldOne, VectorValuesOne); std::string QueryString = SelectQueryStreamCondition(TableName, ColumnName, Conditions); return ExecuteSelectQuery< std::list< unsigned int > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::pair< std::string, std::string > > ListSpecificValuesForTwoColumns( vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, const std::string & ColumnNameOne, const std::string & ColumnNameTwo, const std::string & field, const std::string & value, const std::string & ColumnNameOrder) { std::vector< std::pair< std::string, std::string > > result; std::vector< std::string > SelectedColumns(2); SelectedColumns[0] = ColumnNameOne; SelectedColumns[1] = ColumnNameTwo; std::string QueryString = SelectQueryStreamCondition(TableName, SelectedColumns, field, value, ColumnNameOrder); vtkSQLQuery *query = DatabaseConnector->GetQueryInstance(); query->SetQuery( QueryString.c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "select 2 columns query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return result; } while ( query->NextRow() ) { std::pair< std::string, std::string > Pair; Pair.first = query->DataValue(0).ToString(); Pair.second = query->DataValue(1).ToString(); result.push_back(Pair); } query->Delete(); return result; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ReturnOnlyOneValue( vtkMySQLDatabase *DatabaseConnector, const std::string & TableName, const std::string & ColumnName, const std::string & field, const std::string & value) { std::string result; std::string Conditions = GetConditions(field, value); Conditions += " LIMIT 1"; std::string QueryString = SelectGeneralQueryConditions(ColumnName, TableName, Conditions); return ExecuteSelectQueryOneValue< std::string >(DatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ int MaxValueForOneColumnInTable( vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnName, const std::string & TableName) { std::string What = "MAX("; What += ColumnName; What += ")"; std::string QueryString = SelectGeneralQuery(What, TableName); return ExecuteSelectQueryOneValue< int >(DatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ int MaxValueForOneColumnInTable( vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnName, const std::string & TableName, const std::string & field, const std::string & value) { std::string What = "MAX("; What += ColumnName; What += ")"; std::string QueryString = SelectQueryStreamCondition(TableName, What, field, value); return ExecuteSelectQueryOneValue< int >(DatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ int MaxValueForOneColumnInTable( vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnName, const std::string & TableName, const std::string & field, const std::vector< std::string > & VectorValues) { std::string What = "MAX("; What += ColumnName; What += ")"; std::string QueryString = SelectQueryStreamListConditions(TableName, What, field, VectorValues); return ExecuteSelectQueryOneValue< int >(DatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ int MinValueForOneColumnInTable( vtkMySQLDatabase *DatabaseConnector, const std::string & ColumnName, const std::string & TableName, const std::string & field, const std::vector< std::string > & VectorValues) { std::string What = "MIN("; What += ColumnName; What += ")"; std::string QueryString = SelectQueryStreamListConditions(TableName, What, field, VectorValues); return ExecuteSelectQueryOneValue< int >(DatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //query: "SELECT TableOne.ColumnOne, TableTwo.ColumnTwo FROM TableOne //JOIN TableTwo ON (TableOne.Foreignkey = TableTwo.PrimaryKey) //WHERE field = value; std::vector< std::pair< int, std::string > > ListSpecificValuesForTwoColumnsAndTwoTables( vtkMySQLDatabase *DatabaseConnector, const std::string & TableOne, const std::string & ColumnOne, const std::string & TableTwo, const std::string & ColumnTwo, const std::string & ForeignKey, const std::string & PrimaryKey, const std::string & field, const std::string & value) { std::vector< std::pair< int, std::string > > result; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream querystream; querystream << "SELECT "; querystream << TableOne; querystream << "."; querystream << ColumnOne; querystream << ","; querystream << TableTwo; querystream << "."; querystream << ColumnTwo; querystream << " FROM "; querystream << TableOne; querystream << " JOIN "; querystream << TableTwo; querystream << " ON ("; querystream << TableOne; querystream << "."; querystream << ForeignKey; querystream << " = "; querystream << TableTwo; querystream << "."; querystream << PrimaryKey; querystream << " WHERE "; querystream << field; querystream << " = '"; querystream << value; querystream << "';"; query->SetQuery( querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "join on 2 tables query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return result; } while ( query->NextRow() ) { { std::pair< int, std::string > temp; temp.first = query->DataValue(0).ToInt(); temp.second = query->DataValue(1).ToString(); result.push_back(temp); } } query->Delete(); return result; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::vector< std::string > > GetValuesFromSeveralTables( vtkMySQLDatabase *DatabaseConnector, const std::string & MainTable, const std::vector< std::string > & SelectFields, const std::string & field, const std::string & value, const std::vector< std::string > & JoinTablesOnTraceTable, bool Distinct) { std::vector< std::vector< std::string > > Results; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream Querystream; Querystream << "SELECT "; if ( Distinct ) { Querystream << "DISTINCT "; } unsigned int i; for ( i = 0; i < SelectFields.size() - 1; i++ ) { Querystream << SelectFields[i]; Querystream << ","; } Querystream << SelectFields[i]; Querystream << " FROM "; Querystream << MainTable; unsigned int j = 0; while ( j < JoinTablesOnTraceTable.size() ) { Querystream << " LEFT JOIN "; Querystream << JoinTablesOnTraceTable[j]; Querystream << " ON "; Querystream << JoinTablesOnTraceTable[j + 1]; Querystream << " "; j = j + 2; } Querystream << "WHERE "; Querystream << MainTable; Querystream << "."; Querystream << field; Querystream << " = "; Querystream << value; Querystream << ";"; query->SetQuery( Querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "return info Contours query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return Results; } while ( query->NextRow() ) { std::vector< std::string > ResultsForOneRow; for ( int k = 0; k < query->GetNumberOfFields(); k++ ) { ResultsForOneRow.push_back( query->DataValue(k).ToString() ); } Results.push_back(ResultsForOneRow); } query->Delete(); return Results; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::vector< std::string > > GetValuesFromSeveralTables( vtkMySQLDatabase *DatabaseConnector, const std::string & MainTable, const std::vector< std::string > & SelectFields, const std::string & field, const std::string & value, const std::vector< std::string > & JoinTablesOnTraceTable, bool Distinct, const std::vector & iWhereOrConditions) { std::vector< std::vector< std::string > > Results; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream Querystream; Querystream << "SELECT "; if ( Distinct ) { Querystream << "DISTINCT "; } unsigned int i; for ( i = 0; i < SelectFields.size() - 1; i++ ) { Querystream << SelectFields[i]; Querystream << ","; } Querystream << SelectFields[i]; Querystream << " FROM "; Querystream << MainTable; unsigned int j = 0; while ( j < JoinTablesOnTraceTable.size() ) { Querystream << " LEFT JOIN "; Querystream << JoinTablesOnTraceTable[j]; Querystream << " ON "; Querystream << JoinTablesOnTraceTable[j + 1]; Querystream << " "; j = j + 2; } Querystream << "WHERE ( "; Querystream << MainTable; Querystream << "."; Querystream << field; Querystream << " = "; Querystream << value; Querystream << " AND ("; unsigned int k = 0; while ( k < iWhereOrConditions.size() -1) { Querystream << iWhereOrConditions[k].Field; Querystream << " = "; Querystream << iWhereOrConditions[k].Value; Querystream << " OR "; k = k + 1; } Querystream << iWhereOrConditions[k].Field; Querystream << " = "; Querystream << iWhereOrConditions[k].Value; Querystream << ") );"; query->SetQuery( Querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "return info Contours query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return Results; } while ( query->NextRow() ) { std::vector< std::string > ResultsForOneRow; for ( int k = 0; k < query->GetNumberOfFields(); k++ ) { ResultsForOneRow.push_back( query->DataValue(k).ToString() ); } Results.push_back(ResultsForOneRow); } query->Delete(); return Results; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::vector< std::string > > GetValuesFromSeveralTables( vtkMySQLDatabase *DatabaseConnector, const std::string & MainTable, const std::vector< std::string > & SelectFields, const std::vector< std::string > & WhereAndConditions, const std::vector< std::string > & JoinTablesOnTraceTable, bool Distinct) { std::vector< std::vector< std::string > > Results; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream Querystream; Querystream << "SELECT "; if ( Distinct ) { Querystream << "DISTINCT "; } unsigned int i; for ( i = 0; i < SelectFields.size() - 1; i++ ) { Querystream << SelectFields[i]; Querystream << ","; } Querystream << SelectFields[i]; Querystream << " FROM ("; Querystream << MainTable; unsigned int j = 0; while ( j < JoinTablesOnTraceTable.size() - 1 ) { Querystream << " LEFT JOIN "; Querystream << JoinTablesOnTraceTable[j]; Querystream << " ON "; Querystream << JoinTablesOnTraceTable[j + 1]; Querystream << " "; j = j + 2; } unsigned int k = 0; Querystream << ") WHERE ("; while ( k < WhereAndConditions.size() - 2 ) { Querystream << WhereAndConditions[k]; Querystream << " = "; Querystream << WhereAndConditions[k + 1]; Querystream << " AND "; k = k + 2; } Querystream << WhereAndConditions[k]; Querystream << " = "; Querystream << WhereAndConditions[k + 1]; Querystream << ");"; query->SetQuery( Querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "return info Contours query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return Results; } while ( query->NextRow() ) { std::vector< std::string > ResultsForOneRow; for ( int kk = 0; kk < query->GetNumberOfFields(); kk++ ) { ResultsForOneRow.push_back( query->DataValue(kk).ToString() ); } Results.push_back(ResultsForOneRow); } query->Delete(); return Results; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > GetSamefieldFromTwoTables( vtkMySQLDatabase *DatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const std::string & iField, const std::string & iValue, const std::string & iFieldTwo, const std::vector< std::string > & iListConditionsTwo) { std::vector< std::string > result; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream querystream; querystream << SelectQueryStreamCondition(iTableOne, iColumn, iField, iValue); querystream << " UNION "; querystream << SelectQueryStreamListConditions(iTableTwo, iColumn, iFieldTwo, iListConditionsTwo); query->SetQuery( querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "List of all values for 2 tables query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return result; } while ( query->NextRow() ) { for ( int i = 0; i < query->GetNumberOfFields(); i++ ) { result.push_back( query->DataValue(i).ToString() ); } } query->Delete(); return result; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::list< unsigned int > GetTwoFieldsFromTwoTables( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const FieldWithValue & iOnCondition, const std::string & iColumnOne, const std::string & iColumnTwo, const std::string & iField, const std::vector< std::string > & iListValues, bool Distinct) { std::string QueryString = SelectQueryStreamListConditions(iTableOne, iColumnOne, iField, iListValues, Distinct); QueryString += " UNION "; std::string What = GetLeftJoinTwoTables(iTableOne, iTableTwo, iOnCondition); QueryString += SelectQueryStreamListConditions(What, iColumnTwo, iField, iListValues, Distinct); return ExecuteSelectQuery< std::list< unsigned int > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > GetSamefieldsFromTwoTables(vtkMySQLDatabase *DatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumnOne, const std::string & iColumnTwo, const std::string & iField, const std::string & iValue) { std::vector< std::string > result; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream querystream; querystream << SelectQueryStreamCondition(iTableOne, iColumnOne, iField, iValue); querystream << " UNION "; querystream << SelectQueryStreamCondition(iTableOne, iColumnTwo, iField, iValue); querystream << " UNION "; querystream << SelectQueryStreamCondition(iTableTwo, iColumnOne, iField, iValue); querystream << " UNION "; querystream << SelectQueryStreamCondition(iTableTwo, iColumnTwo, iField, iValue); query->SetQuery( querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "List of all values for 2 tables query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return result; } while ( query->NextRow() ) { for ( int i = 0; i < query->GetNumberOfFields(); i++ ) { result.push_back( query->DataValue(i).ToString() ); } } query->Delete(); return result; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > GetSamefieldsFromTwoTables(vtkMySQLDatabase *DatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumnOne, const std::string & iColumnTwo, const std::string & iField, const std::string & iValue, const std::string & iFieldTwo, const std::vector< std::string > & iListConditionsTwo) { std::vector< std::string > result; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream querystream; querystream << SelectQueryStreamCondition(iTableOne, iColumnOne, iField, iValue); querystream << " UNION "; querystream << SelectQueryStreamCondition(iTableOne, iColumnTwo, iField, iValue); querystream << " UNION "; querystream << SelectQueryStreamListConditions(iTableTwo, iColumnOne, iFieldTwo, iListConditionsTwo); querystream << " UNION "; querystream << SelectQueryStreamListConditions(iTableTwo, iColumnTwo, iFieldTwo, iListConditionsTwo); query->SetQuery( querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "List of all values for 2 tables query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return result; } while ( query->NextRow() ) { for ( int i = 0; i < query->GetNumberOfFields(); i++ ) { result.push_back( query->DataValue(i).ToString() ); } } query->Delete(); return result; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::vector< std::string > GetSameFieldsFromSeveralTables( vtkMySQLDatabase *DatabaseConnector, const std::vector< std::string > & iColumnNames, const std::vector< std::string > & iVectorTablesNames, const std::vector< std::string > & iVectorConditionFieldNames, const std::vector< std::vector< std::string > > & iVectorConditionsValues) { std::vector< std::string > result; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream querystream; unsigned int i = 0; while ( i < iVectorTablesNames.size() - 1 ) { for ( unsigned int j = 0; j < iColumnNames.size(); j++ ) { querystream << SelectQueryStreamListConditions( iVectorTablesNames[i], iColumnNames[j], iVectorConditionFieldNames[i], iVectorConditionsValues[i], true); querystream << " UNION DISTINCT "; } i++; } unsigned j = 0; while ( j < iColumnNames.size() - 1 ) { querystream << SelectQueryStreamListConditions( iVectorTablesNames[i], iColumnNames[j], iVectorConditionFieldNames[i], iVectorConditionsValues[i], true); querystream << " UNION DISTINCT "; j++; } querystream << SelectQueryStreamListConditions( iVectorTablesNames[i], iColumnNames[j], iVectorConditionFieldNames[i], iVectorConditionsValues[i], true); query->SetQuery( querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "List of same field for different tables query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return result; } while ( query->NextRow() ) { for ( int k = 0; k < query->GetNumberOfFields(); k++ ) { result.push_back( query->DataValue(k).ToString() ); } } query->Delete(); return result; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- //SELECT iColumnName FROM TableName WHERE ( (iFieldOne = // iVectorConditionFieldOne(i) // OR iFieldOne = iVectorConditionFieldOne(i+1...) AND (iFieldTwo = // iVectorConditionFieldTwo(j) OR //iVectorConditionFieldTwo(j+1)... ) ); std::vector< std::string > GetSpecificValueFromOneTableWithConditionsOnTwoColumns( vtkMySQLDatabase *DatabaseConnector, const std::string & iColumnName, const std::string & iTableName, const std::string & iFieldOne, const std::vector< std::string > & iVectorConditionFieldOne, const std::string & iFieldTwo, const std::vector< std::string > & iVectorConditionFieldTwo) { std::vector< std::string > result; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream querystream; querystream << "SELECT "; querystream << iColumnName; querystream << " FROM "; querystream << iTableName; querystream << " WHERE (("; unsigned int i = 0; while ( i < iVectorConditionFieldOne.size() - 1 ) { querystream << iFieldOne; querystream << " = '"; querystream << iVectorConditionFieldOne.at(i); querystream << "' OR "; i++; } querystream << iFieldOne; querystream << " = '"; querystream << iVectorConditionFieldOne.at(i); querystream << "') AND ("; unsigned j = 0; while ( j < iVectorConditionFieldTwo.size() - 1 ) { querystream << iFieldTwo; querystream << " = '"; querystream << iVectorConditionFieldTwo.at(j); querystream << "' OR "; j++; } querystream << iFieldTwo; querystream << " = '"; querystream << iVectorConditionFieldTwo.at(j); querystream << "'))"; query->SetQuery( querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "GetSpecificValueFromOneTableWithConditionsOnTwoColumns query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return result; } while ( query->NextRow() ) { for ( int k = 0; k < query->GetNumberOfFields(); k++ ) { result.push_back( query->DataValue(k).ToString() ); } } query->Delete(); return result; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GetColumnForBoundedValue(const std::string & iColumnName, const std::string & iTableName, const std::string & iImgSessionID, const std::string & iCoordType, const std::string & iValue, vtkMySQLDatabase *DatabaseConnector) { std::list< unsigned int > result; vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream querystream; querystream << "SELECT T1."; querystream << iColumnName; querystream << " FROM (SELECT "; querystream << iTableName; querystream << "."; querystream << iColumnName; querystream << " FROM "; querystream << iTableName; querystream << " LEFT JOIN coordinate ON "; querystream << iTableName; querystream << ".CoordIDMax = coordinate.coordid WHERE (ImagingsessionID = "; querystream << iImgSessionID; querystream << " AND Coordinate."; querystream << iCoordType; querystream << " > "; querystream << iValue; querystream << ")) AS T1 INNER JOIN (SELECT "; querystream << iTableName; querystream << "."; querystream << iColumnName; querystream << " FROM "; querystream << iTableName; querystream << " LEFT JOIN coordinate ON "; querystream << iTableName; querystream << ".CoordIDMin = coordinate.coordid WHERE (ImagingsessionID = "; querystream << iImgSessionID; querystream << " AND Coordinate."; querystream << iCoordType; querystream << " < "; querystream << iValue; querystream << ")) AS T2 on T1."; querystream << iColumnName; querystream << " = T2."; querystream << iColumnName; query->SetQuery( querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "GetColumnForBoundedValue query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return result; } while ( query->NextRow() ) { for ( int k = 0; k < query->GetNumberOfFields(); k++ ) { result.push_back( query->DataValue(k).ToInt() ); } } query->Delete(); return result; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GetSpecificValuesEqualToZero( vtkMySQLDatabase *iDatabaseConnector, const std::string & iColumnName, const std::string & iTableName, const std::vector< std::string > & iVectorConditionFieldOne, const std::string & iFieldTwo) { std::list< unsigned int > result; vtkSQLQuery * query = iDatabaseConnector->GetQueryInstance(); std::stringstream querystream; std::string temp = SelectQueryStreamListConditions(iTableName, iColumnName, iColumnName, iVectorConditionFieldOne); temp = temp.substr(0, temp.size() - 1); querystream << temp; querystream << " AND "; querystream << iFieldTwo; querystream << " = 0);"; query->SetQuery( querystream.str().c_str() ); /** \todo Lydie: check when several meshesID are in the query*/ if ( !query->Execute() ) { itkGenericExceptionMacro( << "GetColumnForBoundedValue query failed" << query->GetLastErrorText() ); iDatabaseConnector->Close(); iDatabaseConnector->Delete(); query->Delete(); return result; } while ( query->NextRow() ) { for ( int k = 0; k < query->GetNumberOfFields(); k++ ) { result.push_back( query->DataValue(k).ToInt() ); } } query->Delete(); return result; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GetAllSelectedValuesFromTwoTables( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::vector< FieldWithValue > & iFieldsWithValues, bool Distinct) { std::string Where = GetLeftJoinTwoTables(iTableOne, iTableTwo, iJoinCondition); std::string QueryString = SelectQueryStreamListConditions(Where, iColumn, iFieldsWithValues, "AND", Distinct); return ExecuteSelectQuery< std::list< unsigned int > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector< std::string > GetAllSelectedValuesFromTwoTables( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::vector< std::string > & iSelectedFields, const FieldWithValue & iJoinCondition, const std::vector< FieldWithValue > & iFieldsWithValues, std::string iConditionConnector, std::string ColumnNameOrder) { std::string Where = GetLeftJoinTwoTables(iTableOne, iTableTwo, iJoinCondition); std::string QueryString = SelectQueryStreamListConditions(Where, iSelectedFields, iFieldsWithValues, iConditionConnector, false, ColumnNameOrder); /*if (!ColumnNameOrder.empty()) { QueryString = SelectQueryStreamListConditions(Where, iSelectedFields, iFieldsWithValues, "AND", false, ColumnNameOrder); }*/ return ExecuteSelectQuery< std::vector< std::string > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GetAllSelectedValuesFromTwoTables(vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::string & iField, const std::vector< std::string > & iVectorValues, bool Distinct, bool NonNULLRows) { std::string Where = GetLeftJoinTwoTables(iTableOne, iTableTwo, iJoinCondition, NonNULLRows); std::string QueryString = SelectQueryStreamListConditions(Where, iColumn, iField, iVectorValues, Distinct); return ExecuteSelectQuery< std::list< unsigned int > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GetAllSelectedValuesFromTwoTables(vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::string & iField, const std::vector< std::string > & iVectorValues, const FieldWithValue & iAndCondition) { std::string Where = GetLeftJoinTwoTables(iTableOne, iTableTwo, iJoinCondition); std::string Conditions = "("; Conditions += GetConditions< std::string >(iField, iVectorValues, "OR"); Conditions += " AND "; std::vector< FieldWithValue > AndCondition(1); AndCondition[0] = iAndCondition; Conditions += GetConditions(AndCondition); Conditions += ")"; std::string QueryString = SelectGeneralQueryConditions(iColumn, Where, Conditions); return ExecuteSelectQuery< std::list< unsigned int > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list GetAllSelectedValuesFromTwoTables( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::vector & iSelectedFields, const FieldWithValue & iJoinCondition, const std::string & iField, const std::string & iValue, bool NonNULLRows) { std::string Where = GetLeftJoinTwoTables(iTableOne, iTableTwo, iJoinCondition, true); std::string QueryString = SelectQueryStreamCondition(Where, iSelectedFields, iField, iValue); return ExecuteSelectQuery< std::list< unsigned int > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GetMaxValueFromTwoTables(vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::string & iField, const std::vector< std::string > & iVectorValues, const FieldWithValue & iAndCondition) { std::string What = "MAX("; What += iColumn; What += ")"; std::string Where = GetLeftJoinTwoTables(iTableOne, iTableTwo, iJoinCondition); std::string Conditions = "("; Conditions += GetConditions< std::string >(iField, iVectorValues, "OR"); Conditions += " AND "; std::vector< FieldWithValue > AndCondition(1); AndCondition[0] = iAndCondition; Conditions += GetConditions(AndCondition); Conditions += ")"; std::string QueryString = SelectGeneralQueryConditions(What, Where, Conditions); return ExecuteSelectQueryOneValue< int >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GetListValuesFromTwoTablesAndCondition( vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::string & iField, const std::vector< std::string > & iVectorValues, const FieldWithValue & iAndCondition) { std::string Where = GetLeftJoinTwoTables(iTableOne, iTableTwo, iJoinCondition); std::string Conditions = "("; Conditions += GetConditions< std::string >(iField, iVectorValues, "OR"); Conditions += " AND "; std::vector< FieldWithValue > AndCondition(1); AndCondition[0] = iAndCondition; Conditions += GetConditions(AndCondition); Conditions += ")"; std::string QueryString = SelectGeneralQueryConditions(iColumn, Where, Conditions); return ExecuteSelectQuery< std::list< unsigned int > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GetDoublonValuesFromTwoTables(vtkMySQLDatabase *iDatabaseConnector, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iColumn, const FieldWithValue & iJoinCondition, const std::string & iField, const std::vector< std::string > & iVectValues) //, std::string GroupByColumn) { std::string Where = GetLeftJoinTwoTables(iTableOne, iTableTwo, iJoinCondition); std::string Conditions = GetConditions< std::string >(iField, iVectValues, "OR"); Conditions += GetGroupBy(iColumn, 1); std::string QueryString = SelectQueryStreamCondition(Where, iColumn, Conditions); return ExecuteSelectQuery< std::list< unsigned int > >(iDatabaseConnector, QueryString); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector< std::string > GetOrderByWithLimit(vtkMySQLDatabase *iDatabaseConnector, const std::string & iColumnName, const std::string & iTableName, const std::string & iField, const std::string & iValue, bool ASC, const std::string & iNumberLimit) { std::stringstream QueryStream; QueryStream << SelectQueryStreamCondition(iTableName, iColumnName, iField, iValue); QueryStream << " ORDER BY "; QueryStream << iColumnName; if ( ASC ) { QueryStream << " ASC LIMIT "; } else { QueryStream << " DESC LIMIT "; } QueryStream << iNumberLimit; return ExecuteSelectQuery< std::vector< std::string > >( iDatabaseConnector, QueryStream.str() ); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string GetCoordinateValuesQueryString(const std::string & iTableName, const std::string & iField, const std::string & iValue, bool iMin) { std::stringstream Querystream; Querystream << "SELECT XCoord,YCoord,ZCoord,TCoord,"; Querystream << iTableName; Querystream << "ID from "; Querystream << iTableName; Querystream << " LEFT JOIN coordinate on "; Querystream << iTableName; Querystream << ".coordID"; if ( iMin ) { Querystream << "Min = coordinate.coordID WHERE "; } else { Querystream << "Max = coordinate.coordID WHERE "; } Querystream << iField; Querystream << " = "; Querystream << iValue; return Querystream.str(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void ModifyStructureWithSpecificities(ContourMeshStructure & ioStructure, unsigned int iTCoord, const std::string & iPoints, const std::string & iTraceName) { ioStructure.TCoord = iTCoord; vtkPolyData *output = vtkPolyData::New(); if ( !iPoints.empty() ) { if ( iTraceName.compare("contour") == 0 ) { vtkSmartPointer< vtkPolyDataMySQLContourReader > convert_reader = vtkSmartPointer< vtkPolyDataMySQLContourReader >::New(); output->DeepCopy( convert_reader->GetPolyData(iPoints) ); } else { if ( iTraceName.compare("mesh") == 0 ) { vtkIdType N; std::stringstream str(iPoints); str >> N; if ( N > 0 ) { vtkSmartPointer< vtkPolyDataMySQLMeshReader > convert_reader = vtkSmartPointer< vtkPolyDataMySQLMeshReader >::New(); output->DeepCopy( convert_reader->GetPolyData(iPoints) ); } else { output->Delete(); output = NULL; } } } ioStructure.Nodes = output; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void ModifyStructureWithSpecificities(TrackStructure & ioStructure, unsigned int iTCoord, const std::string & iPoints, const std::string & iTraceName) { (void)iTCoord; if ( iTraceName != "track" ) { std::cout << "this method is only for track and don't have TCoord at this moment"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return; } if ( !iPoints.empty() ) { vtkSmartPointer< vtkPolyDataMySQLTrackReader > convert_reader = vtkSmartPointer< vtkPolyDataMySQLTrackReader >::New(); vtkIdType N; std::stringstream str(iPoints); str >> N; if ( N > 0 ) { vtkPolyData *output = vtkPolyData::New(); output->DeepCopy( convert_reader->GetPolyData(iPoints) ); ioStructure.PointsMap = convert_reader->GetMap(iPoints); ioStructure.Nodes = output; } } else { ioStructure.Nodes = NULL; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void ModifyStructureWithSpecificities(LineageStructure & ioStructure, unsigned int iTrackRootID, const std::string & iPoints, const std::string & iTraceName) { (void) iPoints; if ( iTraceName != "lineage" ) { std::cout << "this method is only for lineage"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return; } ioStructure.TrackRootID = iTrackRootID; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::list< double * > GetCenterBoundingBoxes(vtkMySQLDatabase *DatabaseConnector, const std::string & iTableName, const std::string & iField, const std::string & iValue) { std::list< double * > Results = std::list< double * >(); vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream Querystream; Querystream << "SELECT XCoord,YCoord,ZCoord,TCoord FROM ("; Querystream << GetCoordinateValuesQueryString(iTableName, iField, iValue, true); Querystream << " UNION "; Querystream << GetCoordinateValuesQueryString(iTableName, iField, iValue, false); Querystream << " ORDER BY "; Querystream << iTableName; Querystream << "ID ASC ) AS T1"; query->SetQuery( Querystream.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "return coordmin and max query failed" << query->GetLastErrorText() ); DatabaseConnector->Close(); DatabaseConnector->Delete(); query->Delete(); return Results; } while ( query->NextRow() ) { double *Center = new double[4]; double minx, miny, minz, mint, maxx, maxy, maxz, maxt; minx = query->DataValue(0).ToDouble(); miny = query->DataValue(1).ToDouble(); minz = query->DataValue(2).ToDouble(); mint = query->DataValue(3).ToDouble(); if ( query->NextRow() ) { maxx = query->DataValue(0).ToDouble(); maxy = query->DataValue(1).ToDouble(); maxz = query->DataValue(2).ToDouble(); maxt = query->DataValue(3).ToDouble(); } else { std::cout << "pb query to return center bounding box"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return Results; } Center[0] = ( minx + maxx ) / 2; Center[1] = ( miny + maxy ) / 2; Center[2] = ( minz + maxz ) / 2; Center[3] = ( mint + maxt ) / 2; Results.push_back(Center); } return Results; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ int NumberOfElementForGivenImagingSessionAndTrace( vtkMySQLDatabase *DatabaseConnector, unsigned int iImagingSession, const std::string & iTrace) { std::string What = "COUNT(*)"; std::string Where = iTrace; std::string Condition = "ImagingSessionID = "; std::stringstream s; s << iImagingSession; Condition += s.str(); std::string QueryString = SelectGeneralQueryConditions(What,Where,Condition); return ExecuteSelectQueryOneValue< int >(DatabaseConnector, QueryString); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ int NumberOfElementForGivenImagingSessionAndTraceForGivenTimePoint( vtkMySQLDatabase *DatabaseConnector, unsigned int iImagingSession, const std::string & iTrace, int iTimePoint) { // What std::string What = "COUNT(*)"; // Where FieldWithValue CoordIDMin = { "CoordIDMin", "CoordID", "=" }; std::string Where = GetLeftJoinTwoTables(iTrace, "coordinate", CoordIDMin); // Condition std::string Condition = "(ImagingSessionID = "; std::stringstream s; s << iImagingSession; Condition += s.str(); Condition += " AND TCoord = "; std::stringstream timePoint; timePoint << iTimePoint; Condition += timePoint.str() + ")"; std::string QueryString = SelectGeneralQueryConditions(What,Where,Condition); int test = ExecuteSelectQueryOneValue< int >(DatabaseConnector, QueryString); return test; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ /* int NumberOfTimePointsForGivenImagingSession( vtkMySQLDatabase *DatabaseConnector, unsigned int iImagingSession) { FieldWithValue CoordMaxCondition = { "CoordIDMax", "CoordID", "=" }; std::string What = GetLeftJoinTwoTables("imagingsession", "coordinate", CoordMaxCondition); // std::string What = "COUNT(*)"; // std::string Where = iTrace; // std::string Condition = "ImagingSessionID = "; // std::stringstream s; // s << iImagingSession; // Condition += s.str(); // // std::string QueryString = SelectGeneralQueryConditions(What,Where,Condition); // return ExecuteSelectQueryOneValue< int >(DatabaseConnector, // QueryString); } //------------------------------------------------------------------------------ */ GoFigure2-v0.9.0/Code/IO/MegaCaptureHeaderReader.h0000644000175000017500000000604711667757442021366 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __MegaCaptureHeaderReader_h #define __MegaCaptureHeaderReader_h #include #include #include "QGoIOConfigure.h" #if defined( WIN32 ) #pragma warning( disable: 4251 ) #endif /** \class MegaCaptureHeaderReader \brief */ class QGOIO_EXPORT MegaCaptureHeaderReader { public: explicit MegaCaptureHeaderReader(const std::string & iFileName = ""); ~MegaCaptureHeaderReader(); void SetFileName(const std::string & iFileName); void Read(); double m_TimeInterval; double m_VoxelSizeX; double m_VoxelSizeY; double m_VoxelSizeZ; unsigned int m_DimensionX; unsigned int m_DimensionY; unsigned int m_NumberOfChannels; unsigned int m_ChannelDepth; std::vector< std::vector< int > > m_ChannelColor; std::string m_CreationDate; protected: std::string m_FileName; std::vector< int > ConvertUnsignedLongColorToRGBIntColor( const unsigned long & iColor); bool CheckKeyWord(std::string iWord, std::string iCompare, int& iLineNumber, std::string iExtraKeyWord = ""); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBImport.h0000755000175000017500000003077611667757442016714 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBImport_h #define __GoDBImport_h #include "vtkMySQLDatabase.h" #include "ContourMeshStructure.h" #include "ContourMeshContainer.h" #include #include #include "QGoIOConfigure.h" /** \class GoDBImport \brief This class get the data of traces from a textfile and save them into the GoFigure Database \ingroup DB */ class QGOIO_EXPORT GoDBImport { public: GoDBImport(std::string iServerName, std::string iLogin, std::string iPassword, int iImagingSessionID, std::string iFilename, int iCurrentTimePoint); virtual ~GoDBImport(); /** \brief get the data needed from the import file to save the contours listed in it, including the color, the mesh they belong to, the tracks the previous meshes belong to, etc...and fill the vectors of new IDs and the needed info for the visu to add these new contours*/ void ImportContours(); /** \brief get the data needed from the import file to save the meshes listed in it, including the color,their intensities,the tracks they belong to, the lineages the previous tracks belong to, etc...and fill the vectors of new IDs and the needed info for the visu to add these new meshes */ void ImportMeshes(); /** \brief get the data needed from the import file to save the tracks listed in it, including the color,their meshes and intensities,the lineages they belong to etc... and fill the vectors of new IDs and the needed info for the visu to add these new tracks and meshes. */ void ImportTracks(); /** \brief return a vector of the IDs for the meshes read from the import file and saved in the database*/ std::vector< int > GetVectorNewMeshIDs() { return this->m_NewMeshIDs; } /** \brief return a vector of the IDs for the contours read from the import file and saved in the database*/ std::vector< int > GetVectorNewContourIDs() { return this->m_NewContourIDs; } /** \brief return a vector of the IDs for the tracks read from the the import file and saved in the database*/ std::vector< int > GetVectorNewTracksIDs() { return this->m_NewTracksIDs; } /** \brief return a vector of the info needed to add in the visu the contours read from the import file and saved in the database*/ ContourMeshContainer * GetNewContourInfo() { return this->m_NewContourInfoForVisu; } private: vtkMySQLDatabase * m_DatabaseConnector; std::string m_ServerName; std::string m_Password; std::string m_Login; int m_ImagingSessionID; int m_CurrentTimePoint; std::ifstream m_InFile; std::vector< int > m_NewMeshIDs; std::vector< int > m_NewContourIDs; std::vector< int > m_NewTracksIDs; std::vector< int > m_NewLineageIDs; ContourMeshContainer *m_NewContourInfoForVisu; ContourMeshContainer *m_NewMeshInfoForVisu; typedef std::map< int, int > IntMapType; /** \brief Return the name of the field contained in the line*/ std::string FindFieldName(std::string iLine); /** \brief Return the value contained in the line and "NoValueOnTheLine" if the line doesn't contain any*/ std::string GetValueForTheLine(std::string iLine); /** \brief Return true if the line containes "Number Of"*/ bool IsLineForNumberOfEntities(std::string iLine); /** \brief Get the values from the Infile, save the non traces entities, fill the matching map for old and new IDs and return the current line content*/ std::string SaveNoTracesEntities(IntMapType & ioMapColorIDs, IntMapType & ioMapCellTypeIDs, IntMapType & ioMapSubCellTypeIDs, IntMapType & ioMapCoordIDs); void OpenDBConnection(); void CloseDBConnection(); /** \brief Get the info for the traces from the import file and from the matching IDs maps previously filled, then save them in the database if their bounding box doesn't match any existing ones and save the intensities for the meshes if SaveIntensities is set to true*/ void SaveTracesEntities(const IntMapType & iMapColorIDs, const IntMapType & iMapCoordIDs, const std::string & iLineContent, const IntMapType & iMapCellTypeIDs, const IntMapType & iMapSubCellTypeIDs, bool SaveIntensities = false); /** \brief fill the info needed for the new imported contours to add them in the visu*/ //void FillContourInfoForVisu( //std::vector iListContourIDs); //void FillMeshInfoForVisu(std::vector iListMeshIDs); void SaveIntensityForMesh(std::string & ioLineContent, const IntMapType & iMapMeshIDs, const IntMapType & iMapColorIDs); /** \brief get the values from the import file,save the corresponding number of entities in the database, return the last line content from the import file and update the matchingIDs with the new ones matching the old ones written in the import file*/ template< typename T > std::string SaveImportedEntitiesInDatabase(int iNumberOfEntities, IntMapType & ioMapMatchingIDs) { std::string LineContent; #ifdef HAS_OPENMP #pragma omp for #endif for ( int i = 0; i < iNumberOfEntities; i++ ) { T EntityToSave; LineContent = this->GetValuesFromInfile< T >(EntityToSave); int OldID = atoi( EntityToSave.GetMapValue( EntityToSave.GetTableIDName() ).c_str() ); if (OldID > 0) // in case their is an error in the file to import { EntityToSave.SetField(EntityToSave.GetTableIDName(), "0"); int NewID = EntityToSave.SaveInDB(this->m_DatabaseConnector); ioMapMatchingIDs[OldID] = NewID; } } return LineContent; } /** \brief Get the values from the import File to fill the corresponding GoDBRow*/ template< typename T > std::string GetValuesFromInfile(T & ioEntityToFill) { std::string LineContent; getline(this->m_InFile, LineContent); std::string FieldName = this->FindFieldName(LineContent); std::string ValueForField = this->GetValueForTheLine(LineContent); while ( ValueForField != "NoValueOnTheLine" ) { ioEntityToFill.SetField(FieldName, ValueForField); getline(this->m_InFile, LineContent); ValueForField = this->GetValueForTheLine(LineContent); FieldName = this->FindFieldName(LineContent); } //skip the line : getline(this->m_InFile, LineContent); return LineContent; } /** \brief replace in the entity to be saved the fieldname with the new IDs created that matches the old one in the iMapIDs*/ template< typename T > void ReplaceTheFieldWithNewIDs(const IntMapType & iMapIDs, std::string iFieldName, T & ioEntity) { typename IntMapType::const_iterator iter = iMapIDs.find( atoi( ioEntity.GetMapValue(iFieldName).c_str() ) ); //in case the value of the field name is 0 which corresponds to //an not yet associated value, it won't be found in the map: if ( iter == iMapIDs.end() ) { return; } int NewID = iter->second; ioEntity.SetField(iFieldName, NewID); } /** \brief replace old IDs found in the import file with new created IDs in the trace to be saved for common fields for the 4 traces: colorID, coordIDMin, CoordIDMax and CollectionID*/ template< typename T > void ReplaceCommonFieldsForTraces(T & ioEntityToSave, const IntMapType & iMapColorIDs, const IntMapType & iMapCoordIDs, const IntMapType & iMapCollectionIDs) { ioEntityToSave.SetField( "ImagingSessionID", this->m_ImagingSessionID); this->ReplaceTheFieldWithNewIDs< T >( iMapColorIDs, "ColorID", ioEntityToSave); this->ReplaceTheFieldWithNewIDs< T >( iMapCoordIDs, "CoordIDMax", ioEntityToSave); this->ReplaceTheFieldWithNewIDs< T >( iMapCoordIDs, "CoordIDMin", ioEntityToSave); if ( ioEntityToSave.GetCollectionIDName() != "NoneID" ) { this->ReplaceTheFieldWithNewIDs< T >( iMapCollectionIDs, ioEntityToSave.GetCollectionIDName(), ioEntityToSave); } } /** brief save all the entities in the database for a given trace*/ template< typename T > void SaveTraces(const IntMapType & iMapColorIDs, const IntMapType & iMapCoordIDs, const IntMapType & iMapCollectionIDs, std::string & ioLineContent, std::vector< int > & ioNewTracesIDs, IntMapType & ioMapTraceIDs, const IntMapType & iMapIDsSpecificOne, const IntMapType & iMapIDsSpecificTwo ) { T TraceToSave; int NumberOfTraces = atoi( this->GetValueForTheLine(ioLineContent).c_str() ); getline(this->m_InFile, ioLineContent); #ifdef HAS_OPENMP #pragma omp for #endif for ( int i = 0; i < NumberOfTraces; i++ ) { ioLineContent = this->GetValuesFromInfile< T >( TraceToSave); //for mesh, need to get the new celltype/subcelltype: if ( TraceToSave.GetTableName() == "mesh" ) { if ( !iMapIDsSpecificOne.empty() ) { this->ReplaceTheFieldWithNewIDs< T >( iMapIDsSpecificOne, "CellTypeID", TraceToSave); } if ( !iMapIDsSpecificTwo.empty() ) { this->ReplaceTheFieldWithNewIDs< T >( iMapIDsSpecificTwo, "SubCellularID", TraceToSave); } } this->ReplaceCommonFieldsForTraces( TraceToSave, iMapColorIDs, iMapCoordIDs, iMapCollectionIDs); int OldTraceID = atoi( TraceToSave.GetMapValue( TraceToSave.GetTableIDName() ).c_str() ); /*in order the query works, the TraceID to be saved has to be set to 0 otherwise if the TraceID already exists,the query will return the error "Duplicate entry TraceID for key primary":*/ TraceToSave.SetField(TraceToSave.GetTableIDName(), "0"); int NewTraceID = TraceToSave.DoesThisBoundingBoxExist(this->m_DatabaseConnector); if ( NewTraceID == -1 ) { NewTraceID = TraceToSave.SaveInDB(this->m_DatabaseConnector); // this->m_NewTraceIDs.push_back(NewTraceID); } else { std::cout << "The trace" << OldTraceID << " has the same bounding box as "; std::cout << "the existing trace " << NewTraceID; std::cout << "so the imported contours belonging to the mesh " << OldTraceID; std::cout << " will belong to the existing mesh " << NewTraceID << std::endl; } ioNewTracesIDs.push_back(NewTraceID); ioMapTraceIDs[OldTraceID] = NewTraceID; } } }; #endif GoFigure2-v0.9.0/Code/IO/CMakeLists.txt0000644000175000017500000000656511667757442017331 0ustar mathieumathieuIF( WIN32 ) IF( NOT CYGWIN ) IF( NOT MINGW ) IF( BUILD_SHARED_LIBS ) ADD_DEFINITIONS( -DQGoIO_EXPORT ) ENDIF( BUILD_SHARED_LIBS ) ENDIF( NOT MINGW ) ENDIF( NOT CYGWIN ) ENDIF( WIN32 ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/QGoIOConfigure.h.in ${CMAKE_CURRENT_BINARY_DIR}/QGoIOConfigure.h @ONLY IMMEDIATE ) SET( QGOIO_SRC TraceStructure.cxx ContourMeshStructure.cxx TrackStructure.cxx LineageStructure.cxx CreateDataBaseHelper.cxx GoDBTableWidgetContainer.cxx GoDBTWContainerForContourMesh.cxx GoDBTWContainerForTrackLineage.cxx GoDBTWContainerForMesh.cxx GoDBTWContainerForTrack.cxx GoDBTWContainerForLineage.cxx GoDBExport.cxx GoDBImport.cxx GoDBCollectionOfTraces.cxx # GoDB*Row GoDBRow/GoDBAuthorRow.cxx GoDBRow/GoDBChannelRow.cxx GoDBRow/GoDBColorRow.cxx GoDBRow/GoDBContourRow.cxx GoDBRow/GoDBCoordinateRow.cxx GoDBRow/GoDBImageRow.cxx GoDBRow/GoDBImgSessionRow.cxx GoDBRow/GoDBMeshRow.cxx GoDBRow/GoDBProjectRow.cxx GoDBRow/GoDBTraceRow.cxx GoDBRow/GoDBRow.cxx GoDBRow/GoDBTrackRow.cxx GoDBRow/GoDBTrackFamilyRow.cxx GoDBRow/GoDBLineageRow.cxx GoDBRow/GoDBNameDescRow.cxx GoDBRow/GoDBBookmarkRow.cxx GoDBRow/GoDBCellTypeRow.cxx GoDBRow/GoDBSubCellTypeRow.cxx GoDBRow/GoDBIntensityRow.cxx # Mega related files GoImage/GoImageProcessor.cxx GoImage/GoMegaImageProcessor.cxx GoImage/GoLSMImageProcessor.cxx itkMegaCaptureImport.cxx itkMegaCaptureReader.cxx MegaCaptureHeaderReader.cxx QueryDataBaseHelper.cxx SelectQueryDatabaseHelper.cxx QueryBuilderHelper.cxx # itkLsm3DSerieImport.cxx GoFigureFileInfoMultiIndexContainerHelper.cxx vtkPolyDataMySQLContourReader.cxx vtkPolyDataMySQLMeshReader.cxx vtkPolyDataMySQLTrackReader.cxx vtkPolyDataMySQLContourWriter.cxx vtkPolyDataMySQLMeshWriter.cxx vtkPolyDataMySQLTrackWriter.cxx LSMToMegaCapture.cxx # MeshTextFileImport.cxx # TrackTextFileImport.cxx ) SET_SOURCE_FILES_PROPERTIES( GoDBRow/GoDBRow.cxx GoDBRow/GoDBTraceRow.cxx GoDBTableWidgetContainer.cxx GoDBRow/GoDBNameDescRow.cxx ABSTRACT ) ADD_LIBRARY( QGoIO ${QGOIO_SRC} ) ADD_DEPENDENCIES( QGoIO vtkLSMReader ) TARGET_LINK_LIBRARIES( QGoIO ${QT_LIBRARIES} QGoIO vtkHybrid vtkIO vtkImaging vtkLSMReader ${ITK_LIBRARIES} ) SET_TARGET_PROPERTIES( QGoIO PROPERTIES VERSION ${GOFIGURE2_LIB_VERSION} SOVERSION ${GOFIGURE2_LIB_VERSION} ) # Runtime INSTALL( TARGETS QGoIO EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} NAMELINK_SKIP COMPONENT Libraries ) # Development INSTALL( TARGETS QGoIO EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries NAMELINK_ONLY ) FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE( GLOB __source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/*.txx" ) FILE( GLOB __binary_file_h "${CMAKE_CURRENT_BINARY_DIR}/*.h" ) FILE( GLOB __binary_file_txx "${CMAKE_CURRENT_BINARY_DIR}/*.txx" ) INSTALL( FILES ${__source_file_h} ${__source_file_txx} ${__binary_file_h} ${__binary_file_txx} DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Code/IO/GoFigureMeshAttributes.h0000644000175000017500000000436511667757442021331 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoFigureMeshAttributes_h #define __GoFigureMeshAttributes_h #include "boost/unordered_map.hpp" #include #include "QGoIOConfigure.h" /* \struct GoFigureMeshAttributes \brief Mesh attributes to be displayed in the table widget */ struct QGOIO_EXPORT GoFigureMeshAttributes { boost::unordered_map< std::string, int > m_TotalIntensityMap; boost::unordered_map< std::string, double > m_MeanIntensityMap; double m_Volume; double m_Area; int m_Size; }; #endif GoFigure2-v0.9.0/Code/IO/GoDBTWContainerForContourMesh.h0000755000175000017500000000546311667757442022470 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBTWContainerForContourMesh_h #define __GoDBTWContainerForContourMesh_h #include "GoDBTableWidgetContainer.h" #include "QGoIOConfigure.h" /** \class GoDBTWContainerForContourMesh \brief This class describes the specificities of the GoDBTableWidgetContainer for contour and mesh \ingroup DB */ class QGOIO_EXPORT GoDBTWContainerForContourMesh:public GoDBTableWidgetContainer { public: GoDBTWContainerForContourMesh(); GoDBTWContainerForContourMesh(std::string iCollectionName, std::string iTracesName, int iImgSessionID); ~GoDBTWContainerForContourMesh(); /** \brief return the index of the column in the RowContainer corresponding to the show/hide column */ int GetIndexShowColumn(); protected: //GoDBTableWidgetContainer method void SetCommonInfoForTwoTracesTable(); void FillColumnShowHide(vtkMySQLDatabase* iDatabaseConnector); void FillRowContainerWithDBValues( vtkMySQLDatabase *iDatabaseConnector, std::string iRestrictionName, std::string iRestrictionValue); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBCollectionOfTraces.h0000644000175000017500000006252611667757442021157 0ustar mathieumathieu /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBCollectionOfTraces_h #define __GoDBCollectionOfTraces_h #include "MegaVTK2Configure.h" #include "GoDBRecordSetHelper.h" #include "vtkMySQLDatabase.h" #include "GoDBRow.h" #include "GoDBCoordinateRow.h" #include "GoDBTraceInfoForTableWidget.h" #include "GoDBTableWidgetContainer.h" #include #include /** \class GoDBCollectionOfTraces \brief this class handles the interaction between the database and the children of QGoDBTraceManager \ingroup DB */ class QGOIO_EXPORT GoDBCollectionOfTraces { public: GoDBCollectionOfTraces(); //refactoring GoDBCollectionOfTraces( std::string CollectionName, std::string Traces, std::string iCollectionOfName, unsigned int iImgSessionID); virtual ~GoDBCollectionOfTraces(); typedef GoDBTableWidgetContainer::TWContainerType TWContainerType; typedef std::pair< std::string, QColor > NameWithColorData; /** \brief fill the global values for the collection of traces. \param[in] iCollectionName name of the collection exp: track \param[in] iTracesName name of the trace exp:mesh \param[in] iCollectionOfName name of the collectionOf exp: contour */ void SetCollectionInfo(std::string iCollectionName, std::string iTracesName, std::string iCollectionOfName); /** \brief set m_ImgSessionID to iImgSessionID */ void SetImgSessionID(unsigned int iImgSessionID); //Modif into Database /** \brief Delete the corresponding trace in the database \param[in] DatabaseConnector connection to the database \param[in] TraceToDelete ID of the trace to be deleted from the database */ void DeleteTraceInDB(int TraceToDelete, vtkMySQLDatabase *DatabaseConnector); //Modif into Database /** \brief Delete in the Database all the traces listed in the list of int \param[in] TracesToDelete delete from the database the traces with the ID listed in it \param[in] DatabaseConnector connection to the database */ void DeleteTracesInDB(std::list< unsigned int > TracesToDelete, vtkMySQLDatabase *DatabaseConnector); //Modif into Database /** \brief Update the collectionID of the selected traces in the DB traces table with the new collectionID \param[in] iListSelectedTraces IDs of the traces the collectionID need to be updated \param[in] iCollectionID new collectionID \param[in] iDatabaseConnector connection to the database */ void UpdateCollectionIDOfSelectedTraces( std::list< unsigned int > iListSelectedTraces, unsigned int iCollectionID, vtkMySQLDatabase *iDatabaseConnector); /** \brief \return the name of the trace of the current collection which is also a collection of */ std::string GetCollectionOf(); //******************************Modif-Refactoring************************************************ //public: //Modif into Database /** \brief Calculate the bounding box of the corresponding collection and update it in the database \param[in] iDatabaseConnector connection to the database \param[in] iCollectionID ID of the collection the bounding box is calculated */ void RecalculateDBBoundingBox( vtkMySQLDatabase *iDatabaseConnector, int iCollectionID); /** \brief Get the list of all the collectionIDs, distinct and different from zero for the corresponding traces IDs and recalculate the bounding boxes for them. \param[in] iDatabaseConnector connection to the database \param[in] iListTracesIDs list of the tracesIDs the collection need to be recalculated */ void RecalculateDBBoundingBox( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTracesIDs); /** \brief get all the distinct traces IDs with their QColor \param[in] iDatabaseConnector connection to the database \return std::list list of the TracesIDs with their QColor */ std::list< NameWithColorData > GetAllTracesIDsWithColor( vtkMySQLDatabase *iDatabaseConnector); /** \brief get all the distinct traces IDs with their QColor for a given timepoint \param[in] iDatabaseConnector connection to the database \param[in] iTimePoint timepoint for which the tracesIDs are expected \return std::list list of the TracesIDs with their QColor */ std::list< NameWithColorData > GetTracesIDsWithColorForATimePoint( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTimePoint); /** \brief save the collection in the database after getting an empty bounding box and return the corresponding ID \param[in] iDatabaseConnector connection to the database \param[in] iColor color for the new collection \param[in] iNewCollection collection with all the fields set except bounding box \param[in] iTimePoint timepoint for the collection (only for mesh) \tparam T child of GoDBTraceRow */ template< typename T > int CreateCollectionWithNoTracesNoPoints(vtkMySQLDatabase *iDatabaseConnector, NameWithColorData iColor, T iNewCollection, int iTimePoint = -1) { iNewCollection.SetField("ImagingSessionID", this->m_ImgSessionID); int CoordIDMax = GetCoordIDMaxForBoundingBoxWithNoTraces(iDatabaseConnector); int CoordIDMin = GetCoordIDMinForBoundingBoxWithNoTraces(iDatabaseConnector); if ( iTimePoint != -1 ) { this->SetTheTimePointCoordinatesForMesh( iTimePoint, CoordIDMax, CoordIDMin, iDatabaseConnector); } std::string CollectionID = iNewCollection.GetMapValue(this->m_CollectionIDName); if ( CollectionID != "0" ) { if (CollectionID == "noValue") //case for lineage { return this->CreateNewTraceInDB< T >( iNewCollection, iDatabaseConnector, CoordIDMin, CoordIDMax, iColor); } else { return this->CreateNewTraceInDB< T >( iNewCollection, iDatabaseConnector, CoordIDMin, CoordIDMax, iColor, ss_atoi< unsigned int >(CollectionID) ); } } else { return this->CreateNewTraceInDB< T >(iNewCollection, iDatabaseConnector, CoordIDMin, CoordIDMax, iColor, 0); } } /** \brief set the bounding box, the color and the collectionID of the trace,save it in the database and return the new TraceID created \param[in] iTrace \param[in] iDatabaseConnector connection to the database \param[in] iColor QColor and Name of the color for the trace \param[in] iCollectionID ID of the collection for the trace \tparam T children of GoDBTraceRow \return unsigned int New created TraceID */ template< typename T > unsigned int CreateNewTraceInDB(T iTrace, vtkMySQLDatabase *iDatabaseConnector, NameWithColorData iColor, unsigned int iCollectionID) { iTrace.SetColor(iColor.second.red(), iColor.second.green(), iColor.second.blue(), iColor.second.alpha(), iColor.first, iDatabaseConnector); iTrace.SetCollectionID(iCollectionID); return iTrace.SaveInDB(iDatabaseConnector); } /** \overload */ template< typename T > unsigned int CreateNewTraceInDB(T iTrace, vtkMySQLDatabase *iDatabaseConnector, unsigned int iCoordIDMin, unsigned int iCoordIDMax, NameWithColorData iColor, unsigned int iCollectionID) { iTrace.SetField( "CoordIDMin", ConvertToString< unsigned int >(iCoordIDMin) ); iTrace.SetField( "CoordIDMax", ConvertToString< unsigned int >(iCoordIDMax) ); iTrace.SetColor(iColor.second.red(), iColor.second.green(), iColor.second.blue(), iColor.second.alpha(), iColor.first, iDatabaseConnector); iTrace.SetCollectionID(iCollectionID); return iTrace.SaveInDB(iDatabaseConnector); } /** \overload */ template< typename T > //for lineage unsigned int CreateNewTraceInDB(T iTrace, vtkMySQLDatabase *iDatabaseConnector, unsigned int iCoordIDMin, unsigned int iCoordIDMax, NameWithColorData iColor) { iTrace.SetField( "CoordIDMin", ConvertToString< unsigned int >(iCoordIDMin) ); iTrace.SetField( "CoordIDMax", ConvertToString< unsigned int >(iCoordIDMax) ); iTrace.SetColor(iColor.second.red(), iColor.second.green(), iColor.second.blue(), iColor.second.alpha(), iColor.first, iDatabaseConnector); return iTrace.SaveInDB(iDatabaseConnector); } /** \brief update the color of the specified trace with iNewColor in the database \param[in] iTraceID ID of the trace with the color to modify \param[in] iNewColor name and rgba values of the new color \param[in] iDatabaseConnector connection to the database \tparam T children of GoDBTraceRow */ template< typename T > void ChangeColorForTrace(unsigned int iTraceID, NameWithColorData iNewColor, vtkMySQLDatabase *iDatabaseConnector) { T tempTrace; tempTrace.SetValuesForSpecificID(iTraceID, iDatabaseConnector); tempTrace.SetColor(iNewColor.second.red(), iNewColor.second.green(), iNewColor.second.blue(), iNewColor.second.alpha(), iNewColor.first, iDatabaseConnector); tempTrace.SaveInDB(iDatabaseConnector); } /** \brief get the list of IDs belonging to the iListTraces as collectionof \param[in] iDatabaseConnector connection to the database \param[in] iListTraces list of traces IDs for which the collectionof are needed \return std::list list of the tracesIDs */ std::list< unsigned int > GetListTracesIDsFromThisCollectionOf( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraces); /** \brief get the list of IDs that are collection of iListTraces \param[in] iDatabaseConnector connection to the database \param[in] iListTracesIDs list of traces IDs for which we need the collectionIDs \param[in] ExcludeZero if set to true, will not return the collectionID = 0 \param[in] Distinct if set to true, will not return doublon \return std::list list of the tracesIDs */ std::list< unsigned int > GetListCollectionIDs( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTracesIDs, bool ExcludeZero = true, bool Distinct = true); /** \brief get the list of tracesIDs that have no points \param[in] iListTracesIDs list of the tracesIDs to be checked \param[in] iDatabaseConnector connection to the database \return list of IDs for the traces that have no point and that are in iListTracesIDs */ std::list< unsigned int > GetListTracesIDWithNoPoints( std::list< unsigned int > iListTracesIDs, vtkMySQLDatabase *iDatabaseConnector); /** \brief get the IDs of the last saved traces in the database \param[in] iDatabaseConnector connection to the database \param[in] iNumberOfTraces number of IDs to get \return list of last created IDs */ std::list< unsigned int > GetLastCreatedTracesIDs( vtkMySQLDatabase *iDatabaseConnector, int iNumberOfTraces); /** \brief update in the database the iNameValue with iValue for the traces from iListTraceIDs \param[in] iDatabaseConnector connection to the database \param[in] iNameValue name of the field in the database \param[in] iValue value of the field \param[in] iListTraceIDs list of the traces with the value to be updated */ void UpdateValueForListTraces( vtkMySQLDatabase *iDatabaseConnector,std::string iNameValue, std::string iValue, std::list iListTraceIDs); /** \brief return a list of the coordinates of all the centers of the bounding boxes for all the collectionOf corresponding to the iTraceID \param[in] iDatabaseConnector connection to the database \param[in] iTraceID ID for the trace the bounding boxes of its collectionof traces are needed \return a list of x,y,z,t for all centers of bounding boxes */ std::list GetCoordinateCenterBoundingBox(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTraceID); /** \brief get the tracesIDs from the database which have iTimePoint as TCoordMin and iCollectionID as collectionID \param[in] iDatabaseConnector connection to the database \param[in] iCollectionID ID of the collection \param[in] iTimePoint timepoint for which the traces IDs are needed \return a list of the traces IDs corresponding to this iTimePoint and iCollectionID */ std::list GetTraceIDsWithTimePointAndCollectionID(vtkMySQLDatabase *iDatabaseConnector, unsigned int iCollectionID,unsigned int iTimePoint); /** \brief get the list of timepoints where several traces from the list of traces have the same ones \param[in] iDatabaseConnector connection to the database \param[in] iListTraceIDs list of the IDs of the traces to be checked \return list of timepoints with several traces from the list */ std::list GetTimePointWithSeveralTracesFromTheList( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs); /** \brief get the max of the IDs for the traceIDs in iListTraceIDs that have a timepoint equal to iTimePoint \param[in] iDatabaseConnector connection to the database \param[in] iListTraceIDs list of the IDs of the traces to be checked \param[in] iTimePoint timepoint for which the traceIDs are checked \return the max of the traceIDs for this timepoint */ int GetMaxTraceIDsForSpecificTimePoint(vtkMySQLDatabase *iDatabaseConnector, std::list iListTraceIDs,unsigned int iTimePoint); /** \brief get all the traceIDs except the iMaxTraceID for the timepoint \param[in] iDatabaseConnector connection to the database \param[in] iListTraceIDs list of the IDs of the traces to be checked \param[in] iTimePoint timepoint for which the traceIDs are checked \param[in] iMaxTraceID max of the traceIDs for this timepoint \return all the traceIDs for this timepoint different than the max one */ std::list GetNonMaxTraceIDsForSpecificTimePoint( vtkMySQLDatabase *iDatabaseConnector,std::list iListTraceIDs, unsigned int iTimePoint,unsigned int iMaxTraceID); /** \brief get the list of timepoints for each trace in iListTraceIDs \param[in] iDatabaseConnector connection to the database \param[in] iListTraceIDs list of the IDs for the traces the timepoints are needed \return all the timepoints for the traces in iListTraceIDs */ std::list GetListTimePointsFromTraceIDs( vtkMySQLDatabase *iDatabaseConnector,std::list iListTraceIDs); /** \brief get the tracesIDs contained in iListTraceIDs that have iCollectionID as a collectionID \param[in] iDatabaseConnector connection to the database \param[in] iListTraceIDs list of the IDs for the traces to be checked \param[in] iCollectionID ID of the collection the traces need to belong to \return the list of traces belonging to iCollectionID and to iListTraceIDs */ std::list GetTraceIDsBelongingToCollectionID( vtkMySQLDatabase *iDatabaseConnector,std::list iListTraceIDs, unsigned int iCollectionID); /** \brief get all the tracesIDs that belong to iListCollectionIDs \param[in] iDatabaseConnector connection to the database \param[in] iListCollectionIDs IDs of the collections \return the list of traces belonging to iListCollectionIDs */ std::list GetTraceIDsBelongingToCollectionID( vtkMySQLDatabase *iDatabaseConnector,std::list iListCollectionIDs); std::list GetTraceIDsBelongingToListTimePoints( vtkMySQLDatabase *iDatabaseConnector,std::list iListTPs); /** \brief get the timepoints (non distinct) for all the traceIDs in iListTraceIDs \param[in] iDatabaseConnector connection to the database \param[in] iListTraceIDs list of the IDs for the traces the timepoints are needed \return a list of all the timepoints (non distinct) */ std::list GetTimePointsForTraceIDs( vtkMySQLDatabase *iDatabaseConnector,std::list iListTraceIDs); /** \brief get the tracesIDs belonging to iListTraceIDs with a timepoint inf to iTimePoint \param[in] iDatabaseConnector connection to the database \param[in] iListTraceIDs list of the IDs for the traces to be checked \param[in] iTimePoint timepoint to be compared \return a list of all the traces with a timepoint inf to iTimePoint */ std::list GetTraceIDsWithTimePointInf( vtkMySQLDatabase *iDatabaseConnector,std::list iListTraceIDs, unsigned int iTimePoint); /** \brief get the timepoint min or max for the trace \param[in] iDatabaseConnector connection to the database \param[in] iTraceID ID of the trace the timepoint min is needed \param[in] MinTimePoint if true return the min timepoint, if false, return the max timepoint \return the timepoint min or max */ unsigned int GetBoundedBoxTimePoint( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTraceID, bool MinTimePoint = true); /** \brief get a list of structures filled with data from the database \param[in] iDatabaseConnector connection to the database \param[in] iImgSessionID \param[in] iListTraces IDs for the traces to be in the list \tparam ContourMeshStructure or TrackStructure \return a list of T structure */ template std::list GetListStructureFromDB( vtkMySQLDatabase* iDatabaseConnector, unsigned int iImgSessionID, std::list iListTraces) { std::list oListTracesResults; std::vector TraceAttributes = this->GetAttributesForTraces(); FieldWithValue CoordinateCondition = {"CoordIDMin", "CoordID", "="}; FieldWithValue ColorCondition = {"ColorID", "ColorID", "="}; GetInfoFromDBAndModifyListStructure( oListTracesResults, iDatabaseConnector, TraceAttributes, this->m_TracesName, "coordinate", "color", CoordinateCondition, ColorCondition, "ImagingSessionID", iImgSessionID, this->m_TracesIDName, iListTraces); return oListTracesResults; } /** \brief return the traceID with the lowest timepoint or -1 if there is not only one that have the lowest timepoint */ int GetTraceIDWithLowestTimePoint(vtkMySQLDatabase *iDatabaseConnector, std::list iListTraceIDs); std::list GetTrackFamilyDataFromDB( vtkMySQLDatabase *iDatabaseConnector); std::list GetTrackFamiliesForLineages( vtkMySQLDatabase *iDatabaseConnector, std::list iLineagesID); /** \brief return the trackFamilyIDs the track belongs to (as a mother or as a daughter) */ std::list GetTrackFamilyID(vtkMySQLDatabase *iDatabaseConnector, std::list iListTrackIDs); std::string GetPoints(vtkMySQLDatabase *iDatabaseConnector, std::string iTraceName, unsigned int iTraceID); std::vector GetTrackFamily(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID); bool isMother(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID); protected: std::string m_CollectionName; std::string m_CollectionIDName; std::string m_TracesName; std::string m_TracesIDName; std::string m_CollectionOfName; std::string m_CollectionOfIDName; unsigned int m_ImgSessionID; /** \brief Create a new collection Row in the collection table and return the collectionID from the created row: */ int CreateNewCollection(); /** \brief create a new collection in the database and return the corresponding ID */ int CreateNewCollection(vtkMySQLDatabase *DatabaseConnector, GoDBTraceRow & myNewObject); /** \brief Update in the database the coordid max and min of the trace*/ void UpdateBoundingBoxInDB(int iCoordIDMin, int iCoordIDMax, int iTraceID, vtkMySQLDatabase *iDatabaseConnector); //Modif into Database /** \brief change the collection ID of the trace*/ void UpdateCollectionIDOfSelectedTrace(int iSelectedTraceID, int inewCollectionID, vtkMySQLDatabase *DatabaseConnector); //******************************Modif-Refactoring************************************************ //protected: // get from Database and/or Modif into Database /** \brief modify the timepoint to iTimePoint for the coordmax and coordmin and replace the ioCoordIDMax/Min with the new saved coordinates in the database \param[in] iTimePoint TCoord to be replaced with for the coordmin and max \param[in,out] ioCoordIDMax in: ID for the coordinate max with the timepoint to be modified, out: ID of the coordinate max with the timepoint set as itimepoint \param[in,out] ioCoordIDMin in: ID for the coordinate min with the timepoint to be modified, out: ID of the coordinate min with the timepoint set as itimepoint \param[in] iDatabaseConnector connection to the database */ void SetTheTimePointCoordinatesForMesh(unsigned int iTimePoint, int & ioCoordIDMax, int & ioCoordIDMin, vtkMySQLDatabase *iDatabaseConnector); /** \brief return the CoordIDMax for a minimum bounding box \param[in] iDatabaseConnector connection to the database \return the ID for the coordinate Max of the bounding box */ int GetCoordIDMaxForBoundingBoxWithNoTraces( vtkMySQLDatabase *iDatabaseConnector); /** \brief return the CoordIDMin for a minimum bounding box \param[in] iDatabaseConnector connection to the database \return the ID for the coordinate min of the bounding box */ int GetCoordIDMinForBoundingBoxWithNoTraces( vtkMySQLDatabase *iDatabaseConnector); // get from Database and/or Modif into Database /** \brief get the min of all the coordinates of the collectionof traces belonging to the trace and record them in the database*/ int GetCoordMinID(vtkMySQLDatabase *DatabaseConnector, int iTraceID); //get from Database and/or Modif into Database /** \brief get the max of all the coordinates of the collectionof traces belonging to the trace and record them in the database*/ int GetCoordMaxID(vtkMySQLDatabase *DatabaseConnector, int iTraceID); /** \brief return the coordinate max of all the coordinates of the collectionOf traces*/ GoDBCoordinateRow GetCollectionOfTracesCoordMax( vtkMySQLDatabase *DatabaseConnector, std::list< unsigned int > iListCollectionOfTracesID); /** \brief return the coordinate min of all the coordinates of the selected traces*/ GoDBCoordinateRow GetCollectionOfTracesCoordMin( vtkMySQLDatabase *DatabaseConnector, std::list< unsigned int > iListCollectionOfTracesID); /** \brief get all the different parts needed for the query to get the color of traces from the database \param[in,out] ioSelectedFields will be filed with the attributes of the color DBtable \param[in,out] ioJoinTablesOnTraceTable will be filled with the conditions to link the color table and the trace table */ void GetFieldsNeededForQueryForColorData( std::vector< std::string > & ioSelectedFields, std::vector< std::string > & ioJoinTablesOnTraceTable); /** \brief get the data from the query results to fill a QColor and the corresponding ID \param[in] iResultsQuery vector containing results from a query with a name/ID and the corresponding rgba \return std::list list of the IDs with their corresponding QColor */ std::list< NameWithColorData > GetListNameWithColorDataFromResultsQuery( std::vector< std::vector< std::string > > iResultsQuery); std::vector GetAttributesForTraces(); }; #endif GoFigure2-v0.9.0/Code/IO/LSMToMegaCapture.h0000644000175000017500000000674411667757442020015 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __LSMToMegaCapture_h #define __LSMToMegaCapture_h #if defined( WIN32 ) #pragma warning( disable: 4251 ) #endif #include #include #include "GoFigureGlobalDefinition.h" #include "QGoIOConfigure.h" class vtkLSMReader; /** \brief Convert 1 LSM (5D file) into megacapture files */ class QGOIO_EXPORT LSMToMegaCapture { public: LSMToMegaCapture(); ~LSMToMegaCapture(); /** * \brief Set input lsm file. (Extract m_BaseName) * \param iFileName */ void SetFileName(const std::string & iFileName); /** * \brief Set the output format: PNG (default) or TIFF * \param iFileType */ void SetOutputFileType(const GoFigure::FileType & iFileType); void Export(const std::string & iDirectoryPath); void SetPlaque(const unsigned int & iPlaque); void SetRow(const unsigned int & iRow); void SetColumn(const unsigned int & iCol); void SetXTile(const unsigned int & iXt); void SetYTile(const unsigned int & iYt); void SetZTile(const unsigned int & iZt); std::vector< vtkLSMReader * > GetLSMReaders(); protected: std::string m_FileName; std::vector< vtkLSMReader * > m_LSMReaders; unsigned int m_Plaque; unsigned int m_Row; unsigned int m_Column; unsigned int m_XTile; unsigned int m_YTile; unsigned int m_ZTile; double m_XOverlap; double m_YOverlap; double m_ZOverlap; unsigned int m_NumberOfChannels; unsigned int m_NumberOfTimePoints; GoFigure::FileType m_FileType; std::string m_BaseName; }; #endif GoFigure2-v0.9.0/Code/IO/GoDBTWContainerForTrackLineage.h0000755000175000017500000000466511667757442022556 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBTWContainerForTrackLineage_h #define __GoDBTWContainerForTrackLineage_h #include "GoDBTableWidgetContainer.h" #include "QGoIOConfigure.h" /** \class GoDBTWContainerForTrackLineage \brief This class describes the specificities of the GoDBTableWidgetContainer for track and lineage \ingroup DB */ class QGOIO_EXPORT GoDBTWContainerForTrackLineage:public GoDBTableWidgetContainer { public: GoDBTWContainerForTrackLineage(std::string iCollectionName, std::string iTracesName, int iImgSessionID); ~GoDBTWContainerForTrackLineage(); protected: //GoDBTableWidgetContainer method void SetCommonInfoForTwoTracesTable(); }; #endif GoFigure2-v0.9.0/Code/IO/itkMegaCaptureImport.cxx0000644000175000017500000003521411667757442021406 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkMegaCaptureImport.h" namespace itk { //-------------------------------------------------------------------------------- MegaCaptureImport::MegaCaptureImport() { } //----------------------------------------------------------------------------- //-------------------------------------------------------------------------------- MegaCaptureImport:: ~MegaCaptureImport() { } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MegaCaptureImport::SetFileName(const std::string & iName) { if ( !m_FileName.empty() && !iName.empty() && m_FileName.compare(iName) != 0 ) { return; } if ( iName.empty() && m_FileName.empty() ) { return; } m_FileName = iName; this->Modified(); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MegaCaptureImport::CreateOutput() { size_t counter = 0; std::vector< std::string >::iterator nit; for ( nit = m_FileNameS.begin(); nit != m_FileNameS.end(); ++nit ) { GoFigureFileInfoHelper tempInfo; tempInfo.m_Filename = ( *nit ); std::string origFileName = itksys::SystemTools::GetFilenameName( ( *nit ).c_str() ); IntVectorType::reverse_iterator numGroupLengthItr = m_StartAndLengthNumGroup.second.rbegin(); IntVectorType::reverse_iterator numGroupStartItr = m_StartAndLengthNumGroup.first.rbegin(); std::vector< unsigned int > NumericalValues(m_NbSignificantMegaCaptureNumGroup, 0); int megaCaptureNumericalGroupCounter = 0; while ( ( numGroupLengthItr != m_StartAndLengthNumGroup.second.rend() ) && ( numGroupStartItr != m_StartAndLengthNumGroup.first.rend() ) && ( megaCaptureNumericalGroupCounter < m_NbSignificantMegaCaptureNumGroup ) ) { std::string ValueAsString( origFileName, ( *numGroupStartItr ), ( *numGroupLengthItr ) ); int tempidx = m_NbSignificantMegaCaptureNumGroup - 1 - megaCaptureNumericalGroupCounter; NumericalValues[tempidx] = atoi( ValueAsString.c_str() ); ++numGroupLengthItr; ++numGroupStartItr; ++megaCaptureNumericalGroupCounter; } // end for each numerical group if ( m_HeaderFileName == "" ) { // get the beginning of the filename to look for the headerfile: // first, get back to the starting position of the last numerical values // group which // corresponds to the PL number: numGroupStartItr = numGroupStartItr - 1; // then, substract the "PL-" from the position of the PL Number to find // the position of the last character to be part of the headerfile name: int LengthHeaderFile = *numGroupStartItr - 3; // get the headerfile name and add the .meg std::string fileNamePath = itksys::SystemTools::GetFilenamePath(m_FileName); m_HeaderFileName = fileNamePath + "/" + origFileName.substr(0, LengthHeaderFile) + ".meg"; } if ( m_NbSignificantMegaCaptureNumGroup == 9 ) { NewMegaCaptureFile(tempInfo, NumericalValues); m_OutputFileList.insert(tempInfo); } if ( m_NbSignificantMegaCaptureNumGroup == 6 ) { OldMegaCaptureFile(tempInfo, NumericalValues); m_OutputFileList.insert(tempInfo); } ++counter; this->SetProgress( 0.25 + 0.75 * static_cast< float >( counter ) / static_cast< float >( m_FileNameS.size() ) ); } // end for each filename m_FileNameS.clear(); } //----------------------------------------------------------------------------- GoFigureFileInfoHelperMultiIndexContainer MegaCaptureImport::GetOutput() { return m_OutputFileList; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MegaCaptureImport::Update() { Glob(); CreateOutput(); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MegaCaptureImport::Glob() { std::string FilenameModified = CleanFileName(m_FileName); m_StartAndLengthNumGroup = GetStartAndLengthOfNumericalGroupFilename(FilenameModified); // create the regular expression to glob the entire set of file std::string regExpFileName = FilenameModified; IntVectorType::reverse_iterator numGroupLengthItr = m_StartAndLengthNumGroup.second.rbegin(); IntVectorType::reverse_iterator numGroupStartItr = m_StartAndLengthNumGroup.first.rbegin(); if ( AreTheseNumericalGroupNewMegaCapture(m_StartAndLengthNumGroup) ) { m_NbSignificantMegaCaptureNumGroup = 9; } else { m_NbSignificantMegaCaptureNumGroup = 6; } std::string regExpString = "([0-9]+)"; int megaCaptureNumericalGroupCounter = 0; while ( numGroupLengthItr != m_StartAndLengthNumGroup.second.rend() && numGroupStartItr != m_StartAndLengthNumGroup.first.rend() && megaCaptureNumericalGroupCounter < m_NbSignificantMegaCaptureNumGroup ) { regExpFileName.replace(*numGroupStartItr, *numGroupLengthItr, regExpString); ++numGroupLengthItr; ++numGroupStartItr; ++megaCaptureNumericalGroupCounter; } this->SetProgress( 0.05 ); // Include only filenames that exactly match this regular expression. Don't // match filenames that have this string as a substring (ie. that have extra // prefixes or suffixes). regExpFileName = "^" + regExpFileName + "$"; // Use a RegularExpressionSeriesFileNames to find the files to return std::string unixArchetype = m_FileName; itksys::SystemTools::ConvertToUnixSlashes(unixArchetype); std::string origFileName = itksys::SystemTools::GetFilenameName( unixArchetype.c_str() ); std::string fileNamePath = itksys::SystemTools::GetFilenamePath( unixArchetype.c_str() ); std::string pathPrefix; itk::RegularExpressionSeriesFileNames::Pointer fit = itk::RegularExpressionSeriesFileNames::New(); fit->SetDirectory( fileNamePath.c_str() ); fit->SetRegularExpression( regExpFileName.c_str() ); fit->SetSubMatch(1); fit->NumericSortOn(); m_FileNameS = fit->GetFileNames(); this->SetProgress( 0.15 ); // re parse the indexes and length without the escape caracters std::string::iterator s_start = origFileName.begin(); std::string::iterator s_end = origFileName.end(); std::string::iterator s_it = s_start; int sIndex; while ( s_it != s_end ) { // If the element is a number, find its starting index and length. if ( ( *s_it ) >= '0' && ( *s_it ) <= '9' ) { sIndex = static_cast< int >( s_it - s_start ); m_StartAndLengthNumGroup.first.push_back(sIndex); // Loop to one past the end of the group of numbers. while ( s_it != origFileName.end() && ( *s_it ) >= '0' && ( *s_it ) <= '9' ) { ++s_it; } m_StartAndLengthNumGroup.second.push_back(static_cast< int > ( s_it - s_start ) - sIndex); if ( s_it == s_end ) { break; } } ++s_it; } this->SetProgress( 0.25 ); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- bool MegaCaptureImport::IsNewMegaCapture(const std::string & iFilename) { std::string FilenameModified = CleanFileName(iFilename); PairIntVectorType StartAndLengthNumericalGroup = GetStartAndLengthOfNumericalGroupFilename(FilenameModified); return AreTheseNumericalGroupNewMegaCapture(StartAndLengthNumericalGroup); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- bool MegaCaptureImport::AreTheseNumericalGroupNewMegaCapture( MegaCaptureImport::PairIntVectorType StartAndLengthNumericalGroup) { return ( StartAndLengthNumericalGroup.first.size() >= 9 ); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- std::string MegaCaptureImport::CleanFileName(const std::string & iFilename) { // glob all jpeg file names std::string unixArchetype = iFilename; itksys::SystemTools::ConvertToUnixSlashes(unixArchetype); if ( itksys::SystemTools::FileIsDirectory( unixArchetype.c_str() ) ) { // return type supposed to be one std::string! std::cout << "iFilename is directory" << std::endl; return std::string(); // return false; } // Parse the fileNameName and fileNamePath std::string origFileName = itksys::SystemTools::GetFilenameName( unixArchetype.c_str() ); std::string fileNamePath = itksys::SystemTools::GetFilenamePath( unixArchetype.c_str() ); std::string pathPrefix; std::string ofileNameModified; // "Clean" the filename by escaping any special characters with backslashes. // This allows us to pass in filenames that include these special characters. for ( unsigned int j = 0; j < origFileName.length(); j++ ) { char oneChar = origFileName[j]; if ( oneChar == '^' || oneChar == '$' || oneChar == '.' || oneChar == '[' || oneChar == ']' || oneChar == '-' || oneChar == '*' || oneChar == '+' || oneChar == '?' || oneChar == '(' || oneChar == ')' ) { ofileNameModified += "\\"; } ofileNameModified += oneChar; } // If there is no "/" in the name, the directory is not specified. // In that case, use the default ".". // This is necessary for the RegularExpressionSeriesFileNames. if ( fileNamePath == "" ) { fileNamePath = "."; pathPrefix = "./"; } else { pathPrefix = ""; } return ofileNameModified; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- MegaCaptureImport::PairIntVectorType MegaCaptureImport::GetStartAndLengthOfNumericalGroupFilename(const std::string & iFilename) { // parse and keep it for ouput generation PairIntVectorType oStartAndLength; std::string::const_iterator s_start = iFilename.begin(); std::string::const_iterator s_it = s_start; std::string::const_iterator s_end = iFilename.end(); int sIndex; while ( s_it != s_end ) { // If the element is a number, find its starting index and length. if ( ( *s_it ) >= '0' && ( *s_it ) <= '9' ) { sIndex = static_cast< int >( s_it - s_start ); //the first vector of oStartAndLength contains the index of all the // starting numbers of //the numerical group: oStartAndLength.first.push_back(sIndex); // Loop to one past the end of the group of numbers. while ( ( s_it != s_end ) && ( ( *s_it ) >= '0' ) && ( ( *s_it ) <= '9' ) ) { ++s_it; } //the second vector of oStartAndLength contains the length of the // numerical group: oStartAndLength.second.push_back( static_cast< int >( s_it - s_start ) - sIndex); if ( s_it == s_end ) { break; } } ++s_it; } return oStartAndLength; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MegaCaptureImport::OldMegaCaptureFile(GoFigureFileInfoHelper & ioTempInfo, const std::vector< unsigned int > & iNumericalValues) { ioTempInfo.m_CCoord = iNumericalValues[0]; ioTempInfo.m_RCoord = iNumericalValues[1]; ioTempInfo.m_YCoord = iNumericalValues[2]; ioTempInfo.m_XCoord = iNumericalValues[3]; ioTempInfo.m_TCoord = iNumericalValues[4]; ioTempInfo.m_ZCoord = iNumericalValues[5]; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MegaCaptureImport::NewMegaCaptureFile(GoFigureFileInfoHelper & ioTempInfo, const std::vector< unsigned int > & iNumericalValues) { ioTempInfo.m_PCoord = iNumericalValues[0]; ioTempInfo.m_CCoord = iNumericalValues[1]; ioTempInfo.m_RCoord = iNumericalValues[2]; ioTempInfo.m_ZTileCoord = iNumericalValues[3]; ioTempInfo.m_YTileCoord = iNumericalValues[4]; ioTempInfo.m_XTileCoord = iNumericalValues[5]; ioTempInfo.m_TCoord = iNumericalValues[6]; ioTempInfo.m_Channel = iNumericalValues[7]; ioTempInfo.m_ZCoord = iNumericalValues[8]; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- std::string MegaCaptureImport::GetHeaderFilename() { return m_HeaderFileName; } } GoFigure2-v0.9.0/Code/IO/QueryDataBaseHelper.h0000644000175000017500000001117411667757442020564 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QueryDatabaseHelper_h #define __QueryDatabaseHelper_h #include #include #include #include #include #include "itkMacro.h" #include "vtkMySQLDatabase.h" #include "QGoIOConfigure.h" QGOIO_EXPORT std::pair< bool, vtkMySQLDatabase * > ConnectToServer( std::string ServerName, std::string login, std::string Password); QGOIO_EXPORT std::pair< bool, vtkMySQLDatabase * > ConnectToDatabase( std::string ServerName, std::string login, std::string Password, std::string DBName); QGOIO_EXPORT vtkMySQLDatabase * OpenDatabaseConnection( std::string ServerName, std::string login, std::string Password, std::string DBName); /**\brief return true if the connection has been closed, false if the connection was already closed*/ QGOIO_EXPORT bool CloseDatabaseConnection( vtkMySQLDatabase *DatabaseConnector); QGOIO_EXPORT std::vector< std::string > ListDatabases( vtkMySQLDatabase *ServerConnector); QGOIO_EXPORT std::vector< std::string > ListTables( vtkMySQLDatabase *DatabaseConnector); //query: "UPDATE TableName SET field = newValue WHERE ColumnName = value" QGOIO_EXPORT void UpdateValueInDB(vtkMySQLDatabase *DatabaseConnector, std::string TableName, std::string field, std::string newValue, std::string ColumnName, std::string value); //query: "UPDATE TableName SET field = newValue WHERE (ColumnName = value or // ...)" QGOIO_EXPORT void UpdateValueInDB(vtkMySQLDatabase *DatabaseConnector, std::string iTableName, std::string ifield, std::string inewValue, std::vector< unsigned int > iVectIDs); void UpdateValueInDB(vtkMySQLDatabase *DatabaseConnector,std::string iTableName, std::string iColumnName, std::string iNewValue, std::string iField, std::vector iVectIDs); QGOIO_EXPORT void DropDatabase( vtkMySQLDatabase *ServerConnector, std::string DBName); QGOIO_EXPORT void DropTable( vtkMySQLDatabase *DatabaseConnector, std::string TableName); // query: "DELETE FROM TableName WHERE field = value" QGOIO_EXPORT void DeleteRow( vtkMySQLDatabase *DatabaseConnector, std::string TableName, std::string field, std::string value); // query: "DELETE FROM TableName WHERE (field = //value1 or field = value2...." QGOIO_EXPORT void DeleteRows( vtkMySQLDatabase *DatabaseConnector, std::string TableName, std::string field, std::vector< std::string > VectorValues); QGOIO_EXPORT bool DoesDatabaseExist( vtkMySQLDatabase *ServerConnector, std::string DBName); QGOIO_EXPORT bool DoesTableExist( vtkMySQLDatabase *DatabaseConnector, std::string TableName); //query: "DESCRIBE TableName" QGOIO_EXPORT std::vector< std::string > GetFieldNames(std::string TableName, vtkMySQLDatabase *ServerConnector); void ExecuteQuery(vtkMySQLDatabase * iDatabaseConnector, std::string iQuery); #endif GoFigure2-v0.9.0/Code/IO/MegaCaptureHeaderReader.cxx0000644000175000017500000001572511667757442021744 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "MegaCaptureHeaderReader.h" #include #include #include #include /*****************************************************************************/ MegaCaptureHeaderReader::MegaCaptureHeaderReader(const std::string & iFileName) : m_FileName(iFileName) { m_TimeInterval = 0.; m_VoxelSizeX = 0.; m_VoxelSizeY = 0.; m_VoxelSizeZ = 0.; m_DimensionX = 0; m_DimensionY = 0; m_NumberOfChannels = 0; m_ChannelDepth = 0; m_ChannelColor.resize(0); } /*****************************************************************************/ /*****************************************************************************/ MegaCaptureHeaderReader:: ~MegaCaptureHeaderReader() { } /*****************************************************************************/ /*****************************************************************************/ void MegaCaptureHeaderReader::SetFileName(const std::string & iFileName) { if ( iFileName.empty() ) { std::cerr << "empty filename" << std::endl; return; } else { m_FileName = iFileName; } } /*****************************************************************************/ /*****************************************************************************/ void MegaCaptureHeaderReader::Read() { std::string line; std::ifstream ifs(m_FileName.c_str(), std::ifstream::in); if ( ifs.is_open() ) { /** * \todo Nicolas- shoudln't we read it too */ // Skip the 5 first lines, i.e. // MegaCapture // // Version 3.0 // ExperimentTitle // ExperimentDescription int lineNumber(0); for ( int i = 0; i < 5; i++ ) { getline(ifs, line); ++lineNumber; } std::string word; ifs >> word >> m_TimeInterval; CheckKeyWord(word, "TimeInterval", lineNumber); /** * \todo Nicolas- shoudln't we read Objective too */ getline(ifs, line); // to get '\n' getline(ifs, line); // Objective Plan-Apochromat 20x/0.8 M27 ++lineNumber; ifs >> word >> m_VoxelSizeX; CheckKeyWord(word, "VoxelSizeX", lineNumber); ifs >> word >> m_VoxelSizeY; CheckKeyWord(word, "VoxelSizeY", lineNumber); ifs >> word >> m_VoxelSizeZ; CheckKeyWord(word, "VoxelSizeZ", lineNumber); ifs >> word >> m_DimensionX; CheckKeyWord(word, "DimensionX", lineNumber); ifs >> word >> m_DimensionY; CheckKeyWord(word, "DimensionY", lineNumber); /** * \todo Nicolas- shoudln't we read it too */ // DimensionPL 1 // DimensionCO 2 // DimensionRO 2 // DimensionZT 1 // DimensionYT 2 // DimensionXT 2 // DimensionTM 2 // DimensionZS 4 getline(ifs, line); // to get '\n' for ( int i = 0; i < 8; i++ ) { getline(ifs, line); ++lineNumber; } ifs >> word >> m_NumberOfChannels; CheckKeyWord(word, "DimensionCH", lineNumber); m_ChannelColor.resize(m_NumberOfChannels); unsigned long color; for ( unsigned int i = 0; i < m_NumberOfChannels; i++ ) { ifs >> word >> color; std::ostringstream channelColor1; channelColor1 << "ChannelColor" << std::setw(2) << std::setfill('0') << i; std::ostringstream channelColor2; channelColor2 << "ChannelColor" << i; CheckKeyWord(word, channelColor1.str(), lineNumber, channelColor2.str()); m_ChannelColor[i] = ConvertUnsignedLongColorToRGBIntColor(color); } ifs >> word >> m_ChannelDepth; CheckKeyWord(word, "ChannelDepth", lineNumber); /** * \todo Nicolas- Reading date from here might not be a good solution */ // FileType TIF // // // Filename // // D:/megacapture/image-PL00-CO00-RO00-ZT00-YT00-XT00-TM0000-ch00-zs0000.png for ( int i = 0; i < 5; i++ ) { getline(ifs, line); } std::string date, hours; ifs >> word >> date >> hours; m_CreationDate = date; m_CreationDate += " "; m_CreationDate += hours; //std::cout << "** " << m_CreationDate << std::endl; } else { std::cerr << "Unable to open file" << std::endl; } } std::vector< int > MegaCaptureHeaderReader::ConvertUnsignedLongColorToRGBIntColor(const unsigned long & iColor) { std::vector< int > oRGB(3); oRGB[0] = static_cast< int >( ( iColor / ( 256 * 256 ) ) % 256 ); oRGB[1] = static_cast< int >( ( iColor / 256 ) % 256 ); oRGB[2] = static_cast< int >( iColor % 256 ); return oRGB; } // std::string MegaCaptureHeaderReader:: // ConvertDayStringFormat( std::string iDate ) // { // std::string oDate; // oDate = iDate.substr( ); // } /*****************************************************************************/ /*****************************************************************************/ bool MegaCaptureHeaderReader:: CheckKeyWord(std::string iWord, std::string iCompare, int& iLineNumber, std::string iExtraKeyWord) { ++iLineNumber; if( (iWord.compare(iCompare) != 0) && (iWord.compare(iExtraKeyWord) != 0) ) { std::cerr << ">> ERROR: *" << iCompare << "* keyword should on the line *" << iLineNumber << "* of your .meg file"<< std::endl; throw std::string("Corrupted header file"); return false; } return true; } GoFigure2-v0.9.0/Code/IO/GoDBTWContainerForTrack.h0000644000175000017500000000636611667757442021266 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBTWContainerForTrack_h #define __GoDBTWContainerForTrack_h #include "GoDBTWContainerForTrackLineage.h" #include "QGoIOConfigure.h" #include "GoFigureTrackAttributes.h" /** \class GoDBTWContainerForTrack \brief This class describes the specificities of the GoDBTWContainerForTrackLineage for track \ingroup DB */ class QGOIO_EXPORT GoDBTWContainerForTrack:public GoDBTWContainerForTrackLineage { public: GoDBTWContainerForTrack(int iImgSessionID); ~GoDBTWContainerForTrack(); virtual TWContainerType GetContainerForOneSpecificTrace( vtkMySQLDatabase *iDatabaseConnector, int iTraceID ); /** \brief set m_TrackAttributes to iTrackAttributes, needs to be called before displaying the volume, area values \param[in] iTrackAttributes values for the track computed from visu */ void SetTrackAttributes(GoFigureTrackAttributes *iTrackAttributes); protected: GoFigureTrackAttributes* m_TrackAttributes; /** \brief add the specific info for a track to the columns description */ void SetSpecificInfoForTrackTable(); /** \brief get the values from m_TrackAttributes and the names of the calculated values from m_TrackAttributes and fill the corresponding columns of the row container with them */ void FillRowContainerForTrackComputedValues(); /** \brief */ void GetValuesAndNamesForTrackComputedValues(GoFigureTrackAttributes* iTrackAttributes, std::vector > &ioValues, std::vector &ioNames); }; #endif GoFigure2-v0.9.0/Code/IO/vtkPolyDataMySQLMeshReader.cxx0000644000175000017500000000746611667757442022406 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkPolyDataMySQLMeshReader.h" #include "vtkObjectFactory.h" #include "vtkCellArray.h" #include "vtkPolyData.h" #include vtkCxxRevisionMacro(vtkPolyDataMySQLMeshReader, "$Revision$"); vtkStandardNewMacro(vtkPolyDataMySQLMeshReader); //-------------------------------------------------------------------------- vtkPolyDataMySQLMeshReader::vtkPolyDataMySQLMeshReader() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyDataMySQLMeshReader:: ~vtkPolyDataMySQLMeshReader() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer< vtkPolyData > vtkPolyDataMySQLMeshReader::GetPolyData(const std::string & iString) { std::stringstream str(iString); vtkIdType N; str >> N; // if N == 0, the mesh is a collection of contours if ( N != 0 ) { vtkSmartPointer< vtkPolyData > oMesh; oMesh = vtkSmartPointer< vtkPolyData >::New(); vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New(); points->SetNumberOfPoints(N); double pt[3]; for ( vtkIdType i = 0; i < N; i++ ) { str >> pt[0] >> pt[1] >> pt[2]; points->SetPoint(i, pt); } oMesh->SetPoints(points); vtkSmartPointer< vtkCellArray > cells = vtkSmartPointer< vtkCellArray >::New(); str >> N; vtkSmartPointer< vtkIdList > cell_points = vtkSmartPointer< vtkIdList >::New(); vtkIdType NbOfPointsInCell; vtkIdType id; for ( vtkIdType i = 0; i < N; i++ ) { str >> NbOfPointsInCell; cell_points->Reset(); for ( vtkIdType k = 0; k < NbOfPointsInCell; k++ ) { str >> id; cell_points->InsertNextId(id); } cells->InsertNextCell(cell_points); } oMesh->SetPolys(cells); return oMesh; } return NULL; } //--------------------------------------------------------------------------GoFigure2-v0.9.0/Code/IO/GoDBCollectionOfTraces.cxx0000644000175000017500000014053111667757442021523 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBCollectionOfTraces.h" #include "SelectQueryDatabaseHelper.h" #include "QueryDataBaseHelper.h" #include "ConvertToStringHelper.h" #include "vtkMySQLDatabase.h" #include "GoDBCoordinateRow.h" #include "GoDBTableWidgetContainer.h" #include "GoDBMeshRow.h" #include "GoDBTrackRow.h" #include "GoDBLineageRow.h" #include #include #include #include #include GoDBCollectionOfTraces::GoDBCollectionOfTraces() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBCollectionOfTraces::GoDBCollectionOfTraces( std::string iCollectionName, std::string iTracesName, std::string iCollectionOfName, unsigned int iImgSessionID) { this->SetCollectionInfo(iCollectionName, iTracesName, iCollectionOfName); this->SetImgSessionID(iImgSessionID); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBCollectionOfTraces::~GoDBCollectionOfTraces() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBCollectionOfTraces::SetCollectionInfo(std::string iCollectionName, std::string iTracesName, std::string iCollectionOfName) { m_CollectionName = iCollectionName; m_CollectionIDName = m_CollectionName; m_CollectionIDName += "ID"; m_TracesName = iTracesName; m_TracesIDName = m_TracesName; m_TracesIDName += "ID"; m_CollectionOfName = iCollectionOfName; m_CollectionOfIDName = m_CollectionOfName; m_CollectionOfIDName += "ID"; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBCollectionOfTraces::SetImgSessionID(unsigned int iImgSessionID) { m_ImgSessionID = iImgSessionID; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //Modif into Database void GoDBCollectionOfTraces::DeleteTracesInDB(std::list< unsigned int > TracesToDelete, vtkMySQLDatabase *DatabaseConnector) { std::list< unsigned int >::iterator iter = TracesToDelete.begin(); while ( iter != TracesToDelete.end() ) { unsigned int ID = *iter; // if the trace is a mesh, we should delete its intensity as well if(m_TracesName.compare("mesh") == 0) { // delete the related intensity table DeleteRow(DatabaseConnector, "intensity" , m_TracesIDName, ConvertToString< unsigned int >(ID)); } DeleteRow( DatabaseConnector, m_TracesName, m_TracesIDName, ConvertToString< unsigned int >(ID) ); ++iter; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //Modif into Database void GoDBCollectionOfTraces::DeleteTraceInDB(int TraceToDelete, vtkMySQLDatabase *DatabaseConnector) { DeleteRow( DatabaseConnector, m_TracesName, m_TracesIDName, ConvertToString< int >(TraceToDelete) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //Modif into Database void GoDBCollectionOfTraces::UpdateCollectionIDOfSelectedTraces( std::list< unsigned int > iListSelectedTraces, unsigned int inewCollectionID, vtkMySQLDatabase *DatabaseConnector) { std::string newCollectionIDstring = ConvertToString< unsigned int >(inewCollectionID); std::list< unsigned int >::iterator iter = iListSelectedTraces.begin(); while ( iter != iListSelectedTraces.end() ) { unsigned int TraceID = *iter; UpdateValueInDB( DatabaseConnector, m_TracesName, m_CollectionIDName, newCollectionIDstring, m_TracesIDName, ConvertToString< unsigned int >(TraceID) ); ++iter; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //Modif into Database void GoDBCollectionOfTraces::UpdateCollectionIDOfSelectedTrace( int iSelectedTraceID, int inewCollectionID, vtkMySQLDatabase *DatabaseConnector) { UpdateValueInDB( DatabaseConnector, m_TracesName, m_CollectionIDName, ConvertToString< int >(inewCollectionID), m_TracesIDName, ConvertToString< int >(iSelectedTraceID) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBCollectionOfTraces::UpdateValueForListTraces( vtkMySQLDatabase *iDatabaseConnector, std::string iNameValue, std::string iValue, std::list< unsigned int > iListTraceIDs) { std::vector< unsigned int > VectIDs; std::copy( iListTraceIDs.begin(), iListTraceIDs.end(), std::back_inserter(VectIDs) ); UpdateValueInDB(iDatabaseConnector, this->m_TracesName, iNameValue, iValue, this->m_TracesIDName, VectIDs); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //Modif into Database void GoDBCollectionOfTraces::RecalculateDBBoundingBox( vtkMySQLDatabase *iDatabaseConnector, int iCollectionID) { //update the corresponding bounding box: int CoordIDMax = this->GetCoordMaxID(iDatabaseConnector, iCollectionID); int CoordIDMin = this->GetCoordMinID(iDatabaseConnector, iCollectionID); this->UpdateBoundingBoxInDB(CoordIDMin, CoordIDMax, iCollectionID, iDatabaseConnector); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBCollectionOfTraces::RecalculateDBBoundingBox( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTracesIDs) { std::list< unsigned int >::iterator iter = iListTracesIDs.begin(); while ( iter != iListTracesIDs.end() ) { this->RecalculateDBBoundingBox(iDatabaseConnector, *iter); ++iter; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::list< GoDBCollectionOfTraces::NameWithColorData > GoDBCollectionOfTraces::GetAllTracesIDsWithColor( vtkMySQLDatabase *iDatabaseConnector) { //First, build the query with selected fields and table to join with on // conditions: std::vector< std::string > SelectFields; std::vector< std::string > JoinTablesOnTraceTable; this->GetFieldsNeededForQueryForColorData(SelectFields, JoinTablesOnTraceTable); std::vector< std::vector< std::string > > ResultsQuery; ResultsQuery = GetValuesFromSeveralTables(iDatabaseConnector, this->m_TracesName, SelectFields, "ImagingSessionID", ConvertToString< unsigned int >( this->m_ImgSessionID), JoinTablesOnTraceTable, true); return this->GetListNameWithColorDataFromResultsQuery(ResultsQuery); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::list< GoDBCollectionOfTraces::NameWithColorData > GoDBCollectionOfTraces::GetTracesIDsWithColorForATimePoint( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTimePoint) { std::list< NameWithColorData > oListTraceIDs; //First, build the query with selected fields and table to join with on // conditions: std::vector< std::string > SelectFields; std::vector< std::string > JoinTablesOnTraceTable; this->GetFieldsNeededForQueryForColorData(SelectFields, JoinTablesOnTraceTable); std::string JoinTable = "coordinate"; JoinTablesOnTraceTable.push_back(JoinTable); std::string OnCondition = this->m_TracesName; OnCondition += "."; OnCondition += "CoordIDMin = coordinate.coordid"; JoinTablesOnTraceTable.push_back(OnCondition); std::vector< std::string > WhereAndConditions; OnCondition = this->m_TracesName; OnCondition += ".ImagingsessionID"; WhereAndConditions.push_back(OnCondition); WhereAndConditions.push_back( ConvertToString< unsigned int >(this->m_ImgSessionID) ); WhereAndConditions.push_back("coordinate.TCoord"); WhereAndConditions.push_back( ConvertToString< int >(iTimePoint) ); std::vector< std::vector< std::string > > ResultsQuery = GetValuesFromSeveralTables( iDatabaseConnector, this->m_TracesName, SelectFields, WhereAndConditions, JoinTablesOnTraceTable, true); return this->GetListNameWithColorDataFromResultsQuery(ResultsQuery); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBCollectionOfTraces::GetFieldsNeededForQueryForColorData( std::vector< std::string > & ioSelectedFields, std::vector< std::string > & ioJoinTablesOnTraceTable) { ioSelectedFields.push_back(this->m_TracesIDName); std::string Red = "color.Red"; ioSelectedFields.push_back(Red); std::string Green = "color.Green"; ioSelectedFields.push_back(Green); std::string Blue = "color.Blue"; ioSelectedFields.push_back(Blue); std::string Alpha = "color.Alpha"; ioSelectedFields.push_back(Alpha); std::string JoinTable = "color"; ioJoinTablesOnTraceTable.push_back(JoinTable); std::string OnCondition = this->m_TracesName; OnCondition += ".ColorID = color.ColorID"; ioJoinTablesOnTraceTable.push_back(OnCondition); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::list< GoDBCollectionOfTraces::NameWithColorData > GoDBCollectionOfTraces::GetListNameWithColorDataFromResultsQuery( std::vector< std::vector< std::string > > iResultsQuery) { std::list< NameWithColorData > oListNameWithColorData; unsigned int i = 0; std::vector< std::vector< std::string > >::iterator iter = iResultsQuery.begin(); while ( iter != iResultsQuery.end() ) { std::vector< std::string > ResultsOneRow = *iter; int intRed = atoi( ResultsOneRow[i + 1].c_str() ); int intGreen = atoi( ResultsOneRow[i + 2].c_str() ); int intBlue = atoi( ResultsOneRow[i + 3].c_str() ); int intAlpha = atoi( ResultsOneRow[i + 4].c_str() ); QColor Color(intRed, intGreen, intBlue, intAlpha); NameWithColorData temp; temp.first = ResultsOneRow[i]; temp.second = Color; oListNameWithColorData.push_back(temp); ++iter; } return oListNameWithColorData; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //Get From Database /*QStringList GoDBCollectionOfTraces::ListCollectionID( vtkMySQLDatabase* DatabaseConnector) { QStringList ListIDs; std::vector vectListIDs = ListAllValuesForOneColumn( DatabaseConnector, m_CollectionIDName, m_CollectionName); for (unsigned int i = 0; i < vectListIDs.size(); ++i) { ListIDs.append(vectListIDs[i].c_str()); } return ListIDs; }*/ //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //get from Database and/or Modif into Database int GoDBCollectionOfTraces::GetCoordMinID(vtkMySQLDatabase *iDatabaseConnector, int iTraceID) { //Get the list of the collectionof tracesID belonging to the iTraceID: std::list< unsigned int > ListTracesIDs; ListTracesIDs.push_back(iTraceID); std::list< unsigned int > ListCollectionOfTraces = this->GetListTracesIDsFromThisCollectionOf(iDatabaseConnector, ListTracesIDs); if ( ListCollectionOfTraces.empty() ) { return this->GetCoordIDMinForBoundingBoxWithNoTraces(iDatabaseConnector); } else { //Get the min of the traces: //std::vector< std::string > VectorCollectionOfTraces = //ListUnsgIntToVectorString(ListCollectionOfTraces); GoDBCoordinateRow TracesCoordMin = this->GetCollectionOfTracesCoordMin( iDatabaseConnector, ListCollectionOfTraces); return TracesCoordMin.SaveInDB(iDatabaseConnector); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //get from Database and/or Modif into Database int GoDBCollectionOfTraces::GetCoordMaxID(vtkMySQLDatabase *iDatabaseConnector, int iTraceID) { //Get the list of the tracesID belonging to the collection: std::list< unsigned int > ListTracesIDs; ListTracesIDs.push_back(iTraceID); std::list< unsigned int > ListCollectionOfTraces = this->GetListTracesIDsFromThisCollectionOf(iDatabaseConnector, ListTracesIDs); if ( ListCollectionOfTraces.empty() ) { return this->GetCoordIDMaxForBoundingBoxWithNoTraces(iDatabaseConnector); } else { //Get the max of the traces: //std::vector< std::string > VectorCollectionOfTraces = // ListUnsgIntToVectorString(ListCollectionOfTraces); GoDBCoordinateRow TracesCoordMax = this->GetCollectionOfTracesCoordMax( iDatabaseConnector, ListCollectionOfTraces); return TracesCoordMax.SaveInDB(iDatabaseConnector); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //get from Database and/or Modif into Database GoDBCoordinateRow GoDBCollectionOfTraces::GetCollectionOfTracesCoordMin( vtkMySQLDatabase *DatabaseConnector, std::list< unsigned int > iListCollectionOfTracesID) { GoDBCoordinateRow CoordMin; //First, get the coordID in the contour table that corresponds to the //coordIDMin of the Contours selected: std::list< unsigned int > ListCollectionOfTracesCoordIDMin = ListSpecificValuesForOneColumn(DatabaseConnector, this->m_CollectionOfName, "CoordIDMin", this->m_CollectionOfIDName, iListCollectionOfTracesID); //then, go to the coordinate table and compare the values for the coordID //corresponding to the coordIDMax of the selected contours: std::vector< std::string > ColumnNames = CoordMin.GetVectorColumnNames(); for ( unsigned int i = 0; i < ColumnNames.size(); i++ ) { //don't compare the coordID !!!: if ( ColumnNames[i] != "CoordID" ) { std::vector< std::string > VectorCollectionOfTracesCoordIDMin = ListUnsgIntToVectorString( ListCollectionOfTracesCoordIDMin); CoordMin.SetField( ColumnNames[i], MinValueForOneColumnInTable( DatabaseConnector, ColumnNames[i], "coordinate", "CoordID", VectorCollectionOfTracesCoordIDMin) ); } } return CoordMin; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBCoordinateRow GoDBCollectionOfTraces::GetCollectionOfTracesCoordMax( vtkMySQLDatabase *DatabaseConnector, std::list< unsigned int > iListCollectionOfTracesID) { GoDBCoordinateRow CoordMax; //First, get the coordID in the contour table that corresponds to the //coordIDMax of the Contours selected: std::list< unsigned int > ListCollectionOfTracesCoordIDMax = ListSpecificValuesForOneColumn(DatabaseConnector, this->m_CollectionOfName, "CoordIDMax", this->m_CollectionOfIDName, iListCollectionOfTracesID); //then, go to the coordinate table and compare the values for the coordID //corresponding to the coordIDMax of the selected contours: std::vector< std::string > ColumnNames = CoordMax.GetVectorColumnNames(); for ( unsigned int i = 0; i < ColumnNames.size(); i++ ) { //don't compare the coordID !!!: if ( ColumnNames[i] != "CoordID" ) { std::vector< std::string > VectorCollectionOfTracesCoordIDMax = ListUnsgIntToVectorString( ListCollectionOfTracesCoordIDMax); CoordMax.SetField( ColumnNames[i], MaxValueForOneColumnInTable( DatabaseConnector, ColumnNames[i], "coordinate", "CoordID", VectorCollectionOfTracesCoordIDMax) ); } } return CoordMax; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /*int GoDBCollectionOfTraces::CreateCollectionWithNoTraces( vtkMySQLDatabase* DatabaseConnector, GoDBTraceRow& iNewCollection, int iTimePoint) { iNewCollection.SetField("ImagingSessionID", this->m_ImgSessionID); int CoordIDMax = GetCoordIDMaxForBoundingBoxWithNoTraces(DatabaseConnector); int CoordIDMin = GetCoordIDMinForBoundingBoxWithNoTraces(DatabaseConnector); iNewCollection.SetField("CoordIDMax", CoordIDMax); iNewCollection.SetField("CoordIDMin", CoordIDMin); if (this->m_CollectionName == "mesh") { SetTheTimePointForMesh(iTimePoint, iNewCollection, DatabaseConnector); } return this->CreateNewCollection(DatabaseConnector, iNewCollection); }*/ //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int GoDBCollectionOfTraces::GetCoordIDMinForBoundingBoxWithNoTraces( vtkMySQLDatabase *iDatabaseConnector) { // As there is no traces in the collection, the bounding box is the minimum // one: // CoordIDMin correspond to the imagingsession Max: return FindOneID( iDatabaseConnector, "imagingsession", "CoordIDMax", "ImagingSessionID", ConvertToString< int >(this->m_ImgSessionID) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int GoDBCollectionOfTraces::GetCoordIDMaxForBoundingBoxWithNoTraces( vtkMySQLDatabase *iDatabaseConnector) { // As there is no traces in the collection, the bounding box is the minimum // one: // CoordIDMax correspond to the imagingsession Min: return FindOneID( iDatabaseConnector, "imagingsession", "CoordIDMin", "ImagingSessionID", ConvertToString< int >(this->m_ImgSessionID) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBCollectionOfTraces::SetTheTimePointCoordinatesForMesh( unsigned int iTimePoint, int & ioCoordIDMax, int & ioCoordIDMin, vtkMySQLDatabase *iDatabaseConnector) { GoDBCoordinateRow Coordinate; Coordinate.SetValuesForSpecificID(ioCoordIDMax, iDatabaseConnector); Coordinate.SetField< int >("TCoord", iTimePoint); Coordinate.SetField("CoordID", "0"); ioCoordIDMax = Coordinate.SaveInDB(iDatabaseConnector); Coordinate.SetValuesForSpecificID(ioCoordIDMin, iDatabaseConnector); Coordinate.SetField< int >("TCoord", iTimePoint); Coordinate.SetField("CoordID", "0"); ioCoordIDMin = Coordinate.SaveInDB(iDatabaseConnector); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int GoDBCollectionOfTraces::CreateNewCollection( vtkMySQLDatabase *DatabaseConnector, GoDBTraceRow & iNewCollection) { if ( this->m_CollectionName == "mesh" ) { GoDBMeshRow NewMesh; NewMesh.SafeDownCast(iNewCollection); return AddOnlyOneNewObjectInTable< GoDBMeshRow >( DatabaseConnector, this->m_CollectionName, &NewMesh, m_CollectionIDName); } if ( this->m_CollectionName == "track" ) { GoDBTrackRow *NewTrack = static_cast< GoDBTrackRow * >( &iNewCollection ); return AddOnlyOneNewObjectInTable< GoDBTrackRow >( DatabaseConnector, this->m_CollectionName, NewTrack, m_CollectionIDName); } if ( this->m_CollectionName == "lineage" ) { GoDBLineageRow *NewLineage = static_cast< GoDBLineageRow * >( &iNewCollection ); return AddOnlyOneNewObjectInTable< GoDBLineageRow >( DatabaseConnector, this->m_CollectionName, NewLineage, m_CollectionIDName); } return 0; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /*std::list< unsigned int > GoDBCollectionOfTraces::UpdateDBDataForAddedTracesToExistingCollection( std::list< unsigned int > iListSelectedTraces, int iNewCollectionID, vtkMySQLDatabase *iDatabaseConnector) { std::list< unsigned int > ListTraceIDWithBoundingBoxUpdated; std::vector< std::string > VectorSelectedTraces( iListSelectedTraces.size() ); std::list< unsigned int >::iterator iter = iListSelectedTraces.begin(); unsigned int i = 0; while ( iter != iListSelectedTraces.end() ) { unsigned int temp = *iter; VectorSelectedTraces.at(i) = ConvertToString< unsigned int >(temp); i++; iter++; } //update the bounding boxes for the previous collection if the traces had one: //std::list::iterator iter = iListSelectedTraces.begin(); std::vector< std::string > ListCollectionIDWithBoundingBoxToUpdate = ListSpecificValuesForOneColumn(iDatabaseConnector, this->m_TracesName, this->m_CollectionIDName, this->m_TracesIDName, VectorSelectedTraces, true, true); //change the collectionID of the selected trace to the new one: iter = iListSelectedTraces.begin(); while ( iter != iListSelectedTraces.end() ) { this->UpdateCollectionIDOfSelectedTrace(*iter, iNewCollectionID, iDatabaseConnector); iter++; } if ( !ListCollectionIDWithBoundingBoxToUpdate.empty() ) { //while (iter != iListSelectedTraces.end()) // { // int tempTraceID = *iter; // int tempCollectionID = FindOneID(iDatabaseConnector,this->m_TracesName, // this->m_CollectionIDName,this->m_TracesIDName, // ConvertToString(tempTraceID)); //change the collectionID of the selected trace to the new one: // this->UpdateCollectionIDOfSelectedTrace(tempTraceID,iNewCollectionID, // iDatabaseConnector); // if (tempCollectionID != 0) // { // this->RecalculateDBBoundingBox(iDatabaseConnector,tempCollectionID); // ListTraceIDWithBoundingBoxUpdated.push_back(tempCollectionID); // } // iter++; // } std::vector< std::string >::iterator iterVector = ListCollectionIDWithBoundingBoxToUpdate.begin(); while ( iterVector != ListCollectionIDWithBoundingBoxToUpdate.end() ) { std::string temp = *iterVector; this->RecalculateDBBoundingBox( iDatabaseConnector, atoi( temp.c_str() ) ); ListTraceIDWithBoundingBoxUpdated.push_back( atoi( temp.c_str() ) ); iterVector++; } } //Get the max and min coordid for the bounding box: int CoordMaxID; int CoordMinID; if ( !iListSelectedTraces.empty() ) { CoordMaxID = this->GetCoordMaxID(iDatabaseConnector, iNewCollectionID, iListSelectedTraces); CoordMinID = this->GetCoordMinID(iDatabaseConnector, iNewCollectionID, iListSelectedTraces); } else { CoordMaxID = this->GetCoordIDMaxForBoundingBoxWithNoTraces(iDatabaseConnector); CoordMinID = this->GetCoordIDMinForBoundingBoxWithNoTraces(iDatabaseConnector); } //Update the bounding box for the collection where traces are added: this->UpdateBoundingBoxInDB(CoordMinID, CoordMaxID, iNewCollectionID, iDatabaseConnector); return ListTraceIDWithBoundingBoxUpdated; }*/ //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string GoDBCollectionOfTraces::GetCollectionOf() { if ( this->m_TracesName == "contour" ) { return ""; } if ( this->m_TracesName == "mesh" ) { return "contour"; } if ( this->m_TracesName == "track" ) { return "mesh"; } if ( this->m_TracesName == "lineage" ) { return "track"; } return ""; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBCollectionOfTraces::UpdateBoundingBoxInDB(int iCoordIDMin, int iCoordIDMax, int iTraceID, vtkMySQLDatabase *iDatabaseConnector) { //update the bounding box for the max coord: UpdateValueInDB( iDatabaseConnector, this->m_TracesName, "CoordIDMax", ConvertToString< int >(iCoordIDMax), this->m_TracesIDName, ConvertToString< int >(iTraceID) ); //update the bounding box for the min coord: UpdateValueInDB( iDatabaseConnector, this->m_TracesName, "CoordIDMin", ConvertToString< int >(iCoordIDMin), this->m_TracesIDName, ConvertToString< int >(iTraceID) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::list< unsigned int > GoDBCollectionOfTraces::GetListTracesIDsFromThisCollectionOf( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraces) { std::list< unsigned int > ListTracesFromCollectionOf = std::list< unsigned int >(); if ( this->m_CollectionOfName != "None" ) { ListTracesFromCollectionOf = ListSpecificValuesForOneColumn(iDatabaseConnector, this->m_CollectionOfName, this->m_CollectionOfIDName, this->m_TracesIDName, iListTraces); } return ListTracesFromCollectionOf; } //------------------------------------------------------------------------- //------------------------------------------------------------------------ std::list< unsigned int > GoDBCollectionOfTraces::GetListCollectionIDs( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTracesIDs, bool ExcludeZero, bool Distinct) { std::list< unsigned int > ListCollectionIDs = std::list< unsigned int >(); if ( this->m_CollectionName != "None" ) { ListCollectionIDs = ListSpecificValuesForOneColumn( iDatabaseConnector, this->m_TracesName, this->m_CollectionIDName, this->m_TracesIDName, iListTracesIDs, Distinct, ExcludeZero); } return ListCollectionIDs; } //------------------------------------------------------------------------- //------------------------------------------------------------------------ std::list< unsigned int > GoDBCollectionOfTraces::GetListTracesIDWithNoPoints( std::list< unsigned int > iListTracesIDs, vtkMySQLDatabase *iDatabaseConnector) { std::vector< std::string > VectorTracesIDs = ListUnsgIntToVectorString(iListTracesIDs); if ( !VectorTracesIDs.empty() ) { return GetSpecificValuesEqualToZero( iDatabaseConnector, this->m_TracesIDName, this->m_TracesName, VectorTracesIDs, "points"); } else { return std::list< unsigned int >(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GoDBCollectionOfTraces::GetLastCreatedTracesIDs( vtkMySQLDatabase *iDatabaseConnector, int iNumberOfTraces) { std::vector< std::string > VectorTracesIDs = GetOrderByWithLimit( iDatabaseConnector, this->m_TracesIDName, this->m_TracesName, "imagingsessionid", ConvertToString< unsigned int >(this->m_ImgSessionID), false, ConvertToString< int >(iNumberOfTraces) ); return VectorStringToUnsgInt(VectorTracesIDs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< double * > GoDBCollectionOfTraces::GetCoordinateCenterBoundingBox( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTraceID) { return GetCenterBoundingBoxes( iDatabaseConnector, this->m_CollectionOfName, this->m_TracesIDName, ConvertToString< unsigned int >(iTraceID) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GoDBCollectionOfTraces::GetTraceIDsWithTimePointAndCollectionID( vtkMySQLDatabase *iDatabaseConnector, unsigned int iCollectionID, unsigned int iTimePoint) { FieldWithValue JoinCondition = { "CoordIDMin", "CoordID", "=" }; std::vector< FieldWithValue > Conditions(2); FieldWithValue CollectionID = { this->m_CollectionIDName, ConvertToString< unsigned int >( iCollectionID), "=" }; Conditions[0] = CollectionID; FieldWithValue TimePoint = { "TCoord", ConvertToString< unsigned int >(iTimePoint), "=" }; Conditions[1] = TimePoint; return GetAllSelectedValuesFromTwoTables( iDatabaseConnector, this->m_TracesName, "coordinate", this->m_TracesIDName, JoinCondition, Conditions); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GoDBCollectionOfTraces::GetTimePointWithSeveralTracesFromTheList( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs) { std::list< unsigned int > TimePoints = std::list< unsigned int >(); if ( !iListTraceIDs.empty() ) { FieldWithValue JoinCondition = { "CoordIDMin", "CoordID", "=" }; std::vector< std::string > VectTraceIDs = ListUnsgIntToVectorString(iListTraceIDs); TimePoints = GetDoublonValuesFromTwoTables( iDatabaseConnector, this->m_TracesName, "coordinate", "TCoord", JoinCondition, this->m_TracesIDName, VectTraceIDs); } return TimePoints; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBCollectionOfTraces::GetMaxTraceIDsForSpecificTimePoint( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs, unsigned int iTimePoint) { int oMaxTraceID = -1; if ( !iListTraceIDs.empty() ) { FieldWithValue JoinCondition = { "CoordIDMin", "CoordID", "=" }; std::vector< std::string > VectTraceIDs = ListUnsgIntToVectorString(iListTraceIDs); FieldWithValue TCoord = { "TCoord", ConvertToString< unsigned int >(iTimePoint), "=" }; oMaxTraceID = GetMaxValueFromTwoTables(iDatabaseConnector, this->m_TracesName, "coordinate", this->m_TracesIDName, JoinCondition, this->m_TracesIDName, VectTraceIDs, TCoord); } return oMaxTraceID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GoDBCollectionOfTraces::GetNonMaxTraceIDsForSpecificTimePoint( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs, unsigned int iTimePoint, unsigned int iMaxTraceID) { std::list< unsigned int >::iterator iter = std::find(iListTraceIDs.begin(), iListTraceIDs.end(), iMaxTraceID); iListTraceIDs.erase(iter); std::list< unsigned int > oListTraceIDs = std::list< unsigned int >(); if ( !iListTraceIDs.empty() ) { FieldWithValue JoinCondition = { "CoordIDMin", "CoordID", "=" }; std::vector< std::string > VectTraceIDs = ListUnsgIntToVectorString(iListTraceIDs); FieldWithValue TCoord = { "TCoord", ConvertToString< unsigned int >(iTimePoint), "=" }; oListTraceIDs = GetAllSelectedValuesFromTwoTables(iDatabaseConnector, this->m_TracesName, "coordinate", this->m_TracesIDName, JoinCondition, this->m_TracesIDName, VectTraceIDs, TCoord); } return oListTraceIDs; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GoDBCollectionOfTraces::GetListTimePointsFromTraceIDs( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs) { FieldWithValue JoinCondition = { "CoordIDMin", "CoordID", "=" }; std::vector< std::string > VectTraceIDs = ListUnsgIntToVectorString(iListTraceIDs); return GetAllSelectedValuesFromTwoTables(iDatabaseConnector, this->m_TracesName, "coordinate", "TCoord", JoinCondition, this->m_TracesIDName, VectTraceIDs, true); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GoDBCollectionOfTraces::GetTraceIDsBelongingToCollectionID( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs, unsigned int iCollectionID) { return ListSpecificValuesForOneColumn( iDatabaseConnector, this->m_TracesName, this->m_TracesIDName, this->m_TracesIDName, iListTraceIDs, this->m_CollectionIDName, ConvertToString< unsigned int >(iCollectionID) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GoDBCollectionOfTraces::GetTraceIDsBelongingToCollectionID( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListCollectionIDs) { return ListSpecificValuesForOneColumn(iDatabaseConnector, this->m_TracesName, this->m_TracesIDName, this->m_CollectionIDName, iListCollectionIDs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list GoDBCollectionOfTraces::GetTraceIDsBelongingToListTimePoints( vtkMySQLDatabase *iDatabaseConnector,std::list iListTPs) { FieldWithValue JoinCondition = { "CoordIDMin", "CoordID", "=" }; std::vector< std::string > VectTimePoints = ListUnsgIntToVectorString(iListTPs); FieldWithValue AndCondition = {"imagingsessionID", ConvertToString(this->m_ImgSessionID), "="}; return GetAllSelectedValuesFromTwoTables(iDatabaseConnector, this->m_TracesName, "coordinate", this->m_TracesIDName, JoinCondition, "TCoord", VectTimePoints, AndCondition); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GoDBCollectionOfTraces::GetTimePointsForTraceIDs( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs) { FieldWithValue JoinCondition = { "CoordIDMin", "CoordID", "=" }; std::vector< std::string > VectTraceIDs = ListUnsgIntToVectorString(iListTraceIDs); return GetAllSelectedValuesFromTwoTables(iDatabaseConnector, this->m_TracesName, "coordinate", "TCoord", JoinCondition, this->m_TracesIDName, VectTraceIDs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > GoDBCollectionOfTraces::GetTraceIDsWithTimePointInf(vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs, unsigned int iTimePoint) { FieldWithValue JoinCondition = { "CoordIDMin", "CoordID", "=" }; FieldWithValue AndCondition = { "TCoord", ConvertToString< unsigned int >(iTimePoint), "<" }; std::vector< std::string > VectTraceIDs = ListUnsgIntToVectorString(iListTraceIDs); return GetListValuesFromTwoTablesAndCondition( iDatabaseConnector, this->m_TracesName, "coordinate", this->m_TracesIDName, JoinCondition, this->m_TracesIDName, VectTraceIDs, AndCondition); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*unsigned int GoDBCollectionOfTraces::GetTimePointMin( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTraceID) { FieldWithValue JoinCondition = {"CoordIDMin", "CoordID", "="}; std::vector TraceID(1); TraceID.at(0) = ConvertToString(iTraceID); std::list results = GetAllSelectedValuesFromTwoTables( iDatabaseConnector, this->m_TracesName, "coordinate", "TCoord", JoinCondition, this->m_TracesIDName, TraceID); return results.front(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int GoDBCollectionOfTraces::GetTimePointMax( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTraceID) { FieldWithValue JoinCondition = {"CoordIDMax", "CoordID", "="}; std::vector TraceID(1); TraceID.at(0) = ConvertToString(iTraceID); std::list results = GetAllSelectedValuesFromTwoTables( iDatabaseConnector, this->m_TracesName, "coordinate", "TCoord", JoinCondition, this->m_TracesIDName, TraceID); return results.front(); }*/ //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int GoDBCollectionOfTraces::GetBoundedBoxTimePoint( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTraceID, bool MinTimePoint) { std::string WhichTimePoint = "CoordIDMin"; if ( !MinTimePoint ) { WhichTimePoint = "CoordIDMax"; } FieldWithValue JoinCondition = { WhichTimePoint, "CoordID", "=" }; std::vector< std::string > TraceID(1); TraceID.at(0) = ConvertToString< unsigned int >(iTraceID); std::list< unsigned int > results = GetAllSelectedValuesFromTwoTables( iDatabaseConnector, this->m_TracesName, "coordinate", "TCoord", JoinCondition, this->m_TracesIDName, TraceID); return results.front(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector< std::string > GoDBCollectionOfTraces::GetAttributesForTraces() { std::vector< std::string > oTraceAttributes; oTraceAttributes.push_back(this->m_TracesIDName); if (this->m_CollectionIDName != "NoneID") { oTraceAttributes.push_back(this->m_CollectionIDName); } else { oTraceAttributes.push_back("TrackIDRoot"); } oTraceAttributes.push_back("Red"); oTraceAttributes.push_back("Green"); oTraceAttributes.push_back("Blue"); oTraceAttributes.push_back("Alpha"); oTraceAttributes.push_back("Points"); oTraceAttributes.push_back("TCoord"); return oTraceAttributes; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int GoDBCollectionOfTraces::GetTraceIDWithLowestTimePoint( vtkMySQLDatabase *iDatabaseConnector, std::list iListTraceIDs ) { int oTraceID = -1; std::vector< std::string > SelectedFields(2); SelectedFields.at(0) = "track.trackid"; SelectedFields.at(1) = "coordinate.TCoord"; FieldWithValue JoinCondition = { "CoordIDMin", "CoordID", "=" }; std::vector Conditions = std::vector(); std::list::iterator iter = iListTraceIDs.begin(); while(iter != iListTraceIDs.end() ) { unsigned int Value = *iter; FieldWithValue Condition = {this->m_TracesIDName, ConvertToString(Value), "="}; Conditions.push_back(Condition); ++iter; } std::vector< std::string > ResultQuery = GetAllSelectedValuesFromTwoTables( iDatabaseConnector, this->m_TracesName, "coordinate", SelectedFields, JoinCondition, Conditions, "OR", "TCoord"); if (ResultQuery.size()>2) { if (ResultQuery.at(1) != ResultQuery.at(3)) //if the 2 lowest timepoints are different { oTraceID = ss_atoi(ResultQuery.at(0)); //return the 1rst traceID } } return oTraceID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list GoDBCollectionOfTraces::GetTrackFamilyDataFromDB( vtkMySQLDatabase *iDatabaseConnector) { std::vector VectColumnsTrackFamily(3); VectColumnsTrackFamily.at(0) = "TrackIDMother"; VectColumnsTrackFamily.at(1) = "TrackIDDaughter1"; VectColumnsTrackFamily.at(2) = "TrackIDDaughter2"; const FieldWithValue JoinCondition = {"TrackID", "TrackIDMother", "="}; return GetAllSelectedValuesFromTwoTables( iDatabaseConnector, std::string( "track" ), std::string( "trackfamily" ), VectColumnsTrackFamily, JoinCondition, std::string( "ImagingsessionID" ), ConvertToString(this->m_ImgSessionID), true); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list GoDBCollectionOfTraces::GetTrackFamiliesForLineages( vtkMySQLDatabase *iDatabaseConnector, std::list iLineagesID) { FieldWithValue JoinCondition = { "trackID", "TrackIDMother", "=" }; std::vector VectorLineages = ListUnsgIntToVectorString(iLineagesID); return GetAllSelectedValuesFromTwoTables( iDatabaseConnector, "track", "trackfamily", "trackfamily.trackfamilyID", JoinCondition, "track.lineageid", VectorLineages ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list GoDBCollectionOfTraces::GetTrackFamilyID( vtkMySQLDatabase *iDatabaseConnector, std::list iListTrackIDs) { FieldWithValue JoinCondition = { "trackID", "trackIDMother", "=" }; std::vector VectTrackIDs = ListUnsgIntToVectorString(iListTrackIDs); std::list oList = GetTwoFieldsFromTwoTables(iDatabaseConnector, this->m_TracesName, "trackfamily", JoinCondition, "track.trackfamilyID", "trackfamily.trackfamilyID", this->m_TracesIDName, VectTrackIDs, true); return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string GoDBCollectionOfTraces:: GetPoints(vtkMySQLDatabase *iDatabaseConnector, std::string iTraceName, unsigned int iTraceID) { // WHAT std::string QueryString = "SELECT Points "; // FROM QueryString += "FROM " + iTraceName; //WHERE // trace to Trace (mysql not case sensitive on linux but just in case) std::string traceID = iTraceName; std::transform(iTraceName.begin(), ++iTraceName.begin(),traceID.begin(), ::toupper); traceID += "ID"; QueryString += " WHERE " + traceID + " = "; // iTraceID int to string std::stringstream s; s << iTraceID; QueryString += s.str(); return ExecuteSelectQueryOneValue< std::string >( iDatabaseConnector, QueryString); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector GoDBCollectionOfTraces:: GetTrackFamily(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID) { // WHAT std::string QueryString = "SELECT * "; // FROM QueryString += "FROM trackfamily "; //WHERE // iTraceID int to string std::stringstream s; s << iTrackID; std::string trackID = s.str(); QueryString += " WHERE (TrackIDDaughter1=" + trackID; QueryString += " OR TrackIDDaughter2=" + trackID + ")"; return ExecuteSelectQuery< std::vector >( iDatabaseConnector, QueryString); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool GoDBCollectionOfTraces:: isMother(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID) { // WHAT std::string QueryString = "SELECT TrackIDMother "; // FROM QueryString += "FROM trackfamily "; //WHERE // iTraceID int to string std::stringstream s; s << iTrackID; std::string trackID = s.str(); QueryString += " WHERE TrackIDMother=" + trackID; std::string result = ExecuteSelectQueryOneValue< std::string >( iDatabaseConnector, QueryString); int numb; std::stringstream(result) >> numb; bool ismother = true; if(numb <= 0) { ismother = false; } return ismother; } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/GoDBExport.cxx0000644000175000017500000004617711667757442017275 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBExport.h" #include "SelectQueryDatabaseHelper.h" #include "QueryDataBaseHelper.h" #include "ConvertToStringHelper.h" #include "GoDBColorRow.h" #include "GoDBCellTypeRow.h" #include "GoDBSubCellTypeRow.h" #include "GoDBCoordinateRow.h" #include "GoDBContourRow.h" #include "GoDBMeshRow.h" #include "GoDBTrackRow.h" #include "GoDBLineageRow.h" #include "GoDBChannelRow.h" #include "GoDBIntensityRow.h" //-------------------------------------------------------------------------- GoDBExport::GoDBExport(std::string iServerName, std::string iLogin, std::string iPassword, int iImagingSessionID, std::string iFilename) { this->m_ServerName = iServerName; this->m_Login = iLogin; this->m_Password = iPassword; this->m_ImagingSessionID = iImagingSessionID; this->m_outfile.open (iFilename.c_str(), std::ios::out); } //-------------------------------------------------------------------------- GoDBExport::~GoDBExport() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::ExportContours() { this->WriteGeneraleInfo(); this->OpenDBConnection(); this->WriteOnTheOutputFile( "imagingsession", this->GetImagingSessionInfoFromDB() ); this->UpdateAllVectorTracesIDsToExportContours(); this->WriteTheColorsInfoFromDatabase(); this->WriteCellTypeAndSubCellTypeInfoFromDatabase(); this->WriteCoordinatesInfoFromDatabase(); this->WriteLineagesInfoFromDatabase(); this->WriteTracksInfoFromDatabase(); this->WriteMeshesInfoFromDatabase(); this->WriteContoursInfoFromDatabase(); this->CloseDBConnection(); this->m_outfile << this->GetNameWithSlashBrackets(this->m_NameDocXml); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::ExportMeshes() { this->WriteGeneraleInfo(); this->OpenDBConnection(); this->WriteOnTheOutputFile( "imagingsession", this->GetImagingSessionInfoFromDB() ); this->UpdateAllVectorTracesIDsToExportMeshes(); this->WriteTheColorsInfoFromDatabase(); this->WriteCellTypeAndSubCellTypeInfoFromDatabase(); this->WriteCoordinatesInfoFromDatabase(); this->WriteLineagesInfoFromDatabase(); this->WriteTracksInfoFromDatabase(); this->WriteMeshesInfoFromDatabase(); this->WriteChannelsInfoFromDatabase(); this->WriteIntensityInfoFromDatabase(); this->CloseDBConnection(); this->m_outfile << this->GetNameWithSlashBrackets(this->m_NameDocXml); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteGeneraleInfo() { this->m_NameDocXml = "ExportTraces"; int VersionNumber = 1; this->m_outfile << "" << std::endl; this->m_outfile << "<"; this->m_outfile << this->m_NameDocXml; this->m_outfile << " version=\""; this->m_outfile << VersionNumber; this->m_outfile << "\">" << std::endl; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< std::pair< std::string, std::string > > GoDBExport::GetImagingSessionInfoFromDB() { std::vector< std::pair< std::string, std::string > > infoImgSession; infoImgSession.push_back( this->GetOneInfoFromDBForImgSession("Name") ); infoImgSession.push_back( this->GetOneInfoFromDBForImgSession("CreationDate") ); infoImgSession.push_back( this->GetOneInfoFromDBForImgSession("MicroscopeName") ); return infoImgSession; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::pair< std::string, std::string > GoDBExport::GetOneInfoFromDBForImgSession( std::string iNameInfo) { std::pair< std::string, std::string > OneInfo; OneInfo.first = iNameInfo; OneInfo.second = ListSpecificValuesForOneColumn( this->m_DatabaseConnector, "imagingsession", iNameInfo, "ImagingSessionID", ConvertToString< int >(this->m_ImagingSessionID) ).at(0); return OneInfo; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::UpdateVectorContourIDsForExportContours() { this->m_VectorContourIDs = ListSpecificValuesForOneColumn( this->m_DatabaseConnector, "contour", "contourID", "imagingsessionID", ConvertToString< int >(this->m_ImagingSessionID) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::UpdateVectorContourIDsForExportMeshes() { this->m_VectorContourIDs.clear(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::UpdateVectorMeshIDsForExportContours() { if ( !this->m_VectorContourIDs.empty() ) { this->m_VectorMeshIDs = ListSpecificValuesForOneColumn( this->m_DatabaseConnector, "contour", "meshID", "contourID", this->m_VectorContourIDs, true, true); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::UpdateVectorMeshIDsForExportMeshes() { std::vector< FieldWithValue > Conditions(2); FieldWithValue ImgSession = { "ImagingSessionID", ConvertToString< int >(this->m_ImagingSessionID), "=" }; FieldWithValue Points = { "Points", "0", "<>" }; Conditions[0] = ImgSession; Conditions[1] = Points; this->m_VectorMeshIDs = FindSeveralIDs(this->m_DatabaseConnector, "mesh", "meshID", Conditions); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::UpdateVectorChannelIDsForExportMeshes() { this->m_VectorChannelIDs = ListSpecificValuesForOneColumn( this->m_DatabaseConnector, "channel", "ChannelID", "ImagingSessionID", ConvertToString< int >(this->m_ImagingSessionID) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::UpdateVectorTrackIDsToExportInfo() { if ( !this->m_VectorMeshIDs.empty() ) { this->m_VectorTrackIDs = ListSpecificValuesForOneColumn( this->m_DatabaseConnector, "mesh", "trackID", "meshID", this->m_VectorMeshIDs, true, true); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::UpdateVectorLineageIDsToExportInfo() { if ( !this->m_VectorTrackIDs.empty() ) { this->m_VectorLineageIDs = ListSpecificValuesForOneColumn( this->m_DatabaseConnector, "track", "lineageID", "trackID", this->m_VectorTrackIDs, true, true); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::UpdateAllVectorTracesIDsToExportContours() { this->UpdateVectorContourIDsForExportContours(); this->UpdateVectorMeshIDsForExportContours(); this->UpdateVectorTrackIDsToExportInfo(); this->UpdateVectorLineageIDsToExportInfo(); //no need for channel info when exporting contours at this time: this->m_VectorChannelIDs.clear(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::UpdateAllVectorTracesIDsToExportMeshes() { this->UpdateVectorContourIDsForExportMeshes(); this->UpdateVectorMeshIDsForExportMeshes(); this->UpdateVectorTrackIDsToExportInfo(); this->UpdateVectorLineageIDsToExportInfo(); this->UpdateVectorChannelIDsForExportMeshes(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteTheColorsInfoFromDatabase() { std::vector< std::string > TablesNames; std::vector< std::string > FieldNames; std::vector< std::vector< std::string > > VectorTracesIDs; this->GetVectorsTableNamesTracesIDsAndFields( TablesNames, VectorTracesIDs, FieldNames, true); std::vector< std::string > ListColorIDs = std::vector< std::string >(); if ( !VectorTracesIDs.empty() ) { std::vector< std::string > ColumnNames(1); ColumnNames[0] = "ColorID"; ListColorIDs = GetSameFieldsFromSeveralTables( this->m_DatabaseConnector, ColumnNames, TablesNames, FieldNames, VectorTracesIDs); } this->WriteTableInfoFromDB< GoDBColorRow >(ListColorIDs); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteCellTypeAndSubCellTypeInfoFromDatabase() { std::vector< std::string > ListCellTypeIDs = std::vector< std::string >(); std::vector< std::string > ListSubCellTypeIDs = std::vector< std::string >(); if ( !this->m_VectorMeshIDs.empty() ) { ListCellTypeIDs = ListSpecificValuesForOneColumn( this->m_DatabaseConnector, "mesh", "CellTypeID", "meshID", this->m_VectorMeshIDs, true, true); ListSubCellTypeIDs = ListSpecificValuesForOneColumn(this->m_DatabaseConnector, "mesh", "SubCellularID", "meshID", this->m_VectorMeshIDs, true, true); } this->WriteTableInfoFromDB< GoDBCellTypeRow >(ListCellTypeIDs); this->WriteTableInfoFromDB< GoDBSubCellTypeRow >(ListSubCellTypeIDs); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteCoordinatesInfoFromDatabase() { std::vector< std::string > TablesNames; std::vector< std::string > FieldNames; std::vector< std::vector< std::string > > VectorTracesIDs; this->GetVectorsTableNamesTracesIDsAndFields(TablesNames, VectorTracesIDs, FieldNames); std::vector< std::string > ColumnNames(2); ColumnNames[0] = "CoordIDMax"; ColumnNames[1] = "CoordIDMin"; std::vector< std::string > ListCoordIDs = std::vector< std::string >(); if ( !VectorTracesIDs.empty() ) { ListCoordIDs = GetSameFieldsFromSeveralTables( this->m_DatabaseConnector, ColumnNames, TablesNames, FieldNames, VectorTracesIDs); } this->WriteTableInfoFromDB< GoDBCoordinateRow >(ListCoordIDs); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteLineagesInfoFromDatabase() { this->WriteTableInfoFromDB< GoDBLineageRow >(this->m_VectorLineageIDs); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteTracksInfoFromDatabase() { this->WriteTableInfoFromDB< GoDBTrackRow >(this->m_VectorTrackIDs); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteMeshesInfoFromDatabase() { this->WriteTableInfoFromDB< GoDBMeshRow >(this->m_VectorMeshIDs); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteChannelsInfoFromDatabase() { this->WriteTableInfoFromDB< GoDBChannelRow >(this->m_VectorChannelIDs); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteIntensityInfoFromDatabase() { std::vector< std::string > VectorIntensityIDs = std::vector< std::string >(); if ( !this->m_VectorMeshIDs.empty() ) { VectorIntensityIDs = GetSpecificValueFromOneTableWithConditionsOnTwoColumns( this->m_DatabaseConnector, "IntensityID", "intensity", "meshID", this->m_VectorMeshIDs, "ChannelID", this->m_VectorChannelIDs); } this->WriteTableInfoFromDB< GoDBIntensityRow >(VectorIntensityIDs); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteContoursInfoFromDatabase() { this->WriteTableInfoFromDB< GoDBContourRow >(m_VectorContourIDs); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteOnTheOutputFile(std::string iNameOfEntity, std::vector< std::pair< std::string, std::string > > iInfoToWrite) { this->AddTabulation(); this->m_outfile << GetNameWithBrackets(iNameOfEntity) << std::endl; std::vector< std::pair< std::string, std::string > >::iterator iter = iInfoToWrite.begin(); while ( iter != iInfoToWrite.end() ) { this->AddTabulation(); this->AddTabulation(); this->m_outfile << this->GetNameWithBrackets(iter->first); this->m_outfile << iter->second; this->m_outfile << this->GetNameWithSlashBrackets(iter->first) << std::endl; ++iter; } this->AddTabulation(); this->m_outfile << GetNameWithSlashBrackets(iNameOfEntity) << std::endl; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::WriteNumberOfEntities(std::string iNameOfEntity, size_t iNumber) { this->AddTabulation(); std::string NameToWrite = "NumberOf"; NameToWrite += iNameOfEntity; this->m_outfile << this->GetNameWithBrackets(NameToWrite); this->m_outfile << iNumber; this->m_outfile << this->GetNameWithSlashBrackets(NameToWrite) << std::endl; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string GoDBExport::GetNameWithBrackets(std::string iName) { std::stringstream NameWithBrackets; NameWithBrackets << "<"; NameWithBrackets << iName; NameWithBrackets << ">"; return NameWithBrackets.str(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string GoDBExport::GetNameWithSlashBrackets(std::string iName) { std::stringstream NameWithBrackets; NameWithBrackets << ""; return NameWithBrackets.str(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::AddTabulation() { this->m_outfile << " "; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::OpenDBConnection() { this->m_DatabaseConnector = OpenDatabaseConnection(m_ServerName, m_Login, m_Password, "gofiguredatabase"); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::CloseDBConnection() { CloseDatabaseConnection(m_DatabaseConnector); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBExport::GetVectorsTableNamesTracesIDsAndFields( std::vector< std::string > & ioVectorTableNames, std::vector< std::vector< std::string > > & ioVectorTracesIDs, std::vector< std::string > & ioVectorFields, bool IncludeChannelIDs) { if ( !this->m_VectorContourIDs.empty() ) { ioVectorTableNames.push_back("contour"); ioVectorFields.push_back("contourID"); ioVectorTracesIDs.push_back(this->m_VectorContourIDs); } if ( !this->m_VectorMeshIDs.empty() ) { ioVectorTableNames.push_back("mesh"); ioVectorFields.push_back("meshID"); ioVectorTracesIDs.push_back(this->m_VectorMeshIDs); } if ( !this->m_VectorTrackIDs.empty() ) { ioVectorTableNames.push_back("track"); ioVectorFields.push_back("trackID"); ioVectorTracesIDs.push_back(this->m_VectorTrackIDs); } if ( !this->m_VectorLineageIDs.empty() ) { ioVectorTableNames.push_back("lineage"); ioVectorFields.push_back("lineageID"); ioVectorTracesIDs.push_back(this->m_VectorLineageIDs); } if ( IncludeChannelIDs ) { if ( !this->m_VectorChannelIDs.empty() ) { ioVectorTableNames.push_back("channel"); ioVectorFields.push_back("ChannelID"); ioVectorTracesIDs.push_back(this->m_VectorChannelIDs); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/TraceStructure.h0000644000175000017500000001375711667757442017722 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef TRACESTRUCTURE_H #define TRACESTRUCTURE_H #include "vtkSmartPointer.h" class vtkActor; class vtkPolyData; class vtkProperty; class vtkLookupTable; #include #include #include "QGoIOConfigure.h" #ifndef DOXYGEN_SHOULD_SKIP_THIS #include "StructureHelper.h" #endif /** \defgroup Trace Trace */ /** * \struct TraceStructure * \brief Structure which represent a trace (contour, mesh, track, lineage), * and used for interaction between Visualization and TableWidget * \ingroup Trace */ class QGOIO_EXPORT TraceStructure { public: /** TraceID */ unsigned int TraceID; /** CollectionID */ unsigned int CollectionID; /** Actor in the XY View */ vtkActor *ActorXY; /** Actor in the XZ View */ vtkActor *ActorXZ; /** Actor in the YZ View */ vtkActor *ActorYZ; /** Actor in the XYZ View */ vtkActor *ActorXYZ; vtkPolyData *Nodes; /** Is the track Highlighted in the Visualization ? */ bool Highlighted; /** Is the track Visible (appears on the screen) * in the Visualization ? */ bool Visible; /** color of the track. \note each component is in [0,1] */ double rgba[4]; /** Constructor */ TraceStructure(); /** Constructor */ TraceStructure( const unsigned int & iTraceID, const unsigned int & iCollectionID, std::vector< vtkActor * > iActors, vtkPolyData *iNodes, const bool & iHighlighted, const bool & iVisible, const double & r, const double & g, const double & b, const double & alpha); /** Constructor */ TraceStructure( const unsigned int & iTraceID, const unsigned int & iCollectionID, std::vector< vtkActor * > iActors, vtkPolyData *iNodes, const bool & iHighlighted, const bool & iVisible, double iRgba[4]); /** Constructor */ TraceStructure( const unsigned int & iTraceID, const unsigned int & iCollectionID, vtkActor *iActorXY, vtkActor *iActorYZ, vtkActor *iActorXZ, vtkActor *iActorXYZ, vtkPolyData *iNodes, const bool & iHighlighted, const bool & iVisible, const double & r, const double & g, const double & b, const double & alpha); /** Constructor */ TraceStructure( const TraceStructure& iE ); virtual ~TraceStructure(); /** \brief Set Property for all actors \param[in] iProperty */ void SetActorProperties( vtkProperty* iProperty ) const; /** \brief Set Visibility for all actors \param[in] iVisible */ void SetActorVisibility( const bool& iVisible ) const; /** \brief Set Scalar Data associated to the elements (use for color coding) \param[in] iName data name \param[in] iValue value */ void SetScalarData( const std::string& iName, const double& iValue ) const; /** \brief Set the scalar range (use for color coding) \param[in] iMin \param[in] iMax */ void SetScalarRange( const double& iMin, const double& iMax ) const; /** \brief Render with original colors (Remove the active scalars data).*/ void RenderWithOriginalColors() const; /** \brief Set the lookup table \param[in] iLut */ void SetLookupTable( const vtkLookupTable* iLut ) const; virtual void ReleaseData() const; /** Printing one element. std::cout << element << std::endl; */ friend std::ostream & operator<< (std::ostream & os, const TraceStructure & c) { os << "TraceID " << c.TraceID << std::endl; os << "Highlighted " << c.Highlighted << std::endl; os << "Visible " << c.Visible << std::endl; os << "RGBA [" << c.rgba[0] << ", " << c.rgba[1] << ", " << c.rgba[2] << ", " << c.rgba[3] << "]" << std::endl; os << "ActorXY " << c.ActorXY << std::endl; os << "ActorXZ " << c.ActorXZ << std::endl; os << "ActorYZ " << c.ActorYZ << std::endl; os << "ActorXYZ " << c.ActorXYZ << std::endl; os << "Nodes " << c.Nodes << std::endl; return os; } void ResetNodes() const; }; #endif // TRACESTRUCTURE_H GoFigure2-v0.9.0/Code/IO/GoDBRecordSet.h0000644000175000017500000003156111667757442017322 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBRecordSet_h #define __GoDBRecordSet_h #include #include #include #include #include #include "vtkVariant.h" #include "QueryDataBaseHelper.h" #include "vtkMySQLDatabase.h" #include "vtkSQLQuery.h" template< class TObject > class GoDBRecordSet { public: // row type typedef TObject OriginalObjectType; // decorate the row type to know if it was modified // allows for optimization when synchronising the data typedef std::pair< bool, OriginalObjectType > InternalObjectType; typedef std::vector< InternalObjectType > RowContainerType; GoDBRecordSet():IsWhereStringSet(false) {} ~GoDBRecordSet() {} std::vector< std::string > GetColumnNamesContainer() { return m_ColumnNamesContainer; } RowContainerType * GetRowContainer() { return &m_RowContainer; } /** \brief Add a new Object of OriginalObjectType (exp: GoDBprojectRow) in the m_RowContainer and set the bool to false*/ void AddObject(const OriginalObjectType & object) { m_RowContainer.push_back( InternalObjectType(false, object) ); } /* Insert Object note lydie:overwrite the object at the pos position in the m_RowContainer (not yet used)wouldn't that be better to call it "ReplaceObject" ? if the object has changed, why put the bool to true ??? */ void InsertObject(const int & pos, const OriginalObjectType & object) { if ( pos > m_RowContainer.size() ) { AddObject(object); return; } m_RowContainer[pos] = InternalObjectType(true, object); } /** \brief is there to be used in case there is a "WHERE" condition to add for the selection in PopulateFromDB()*/ void SetWhereString(const std::string& whereString) { this->m_WhereString = whereString; this->IsWhereStringSet = true; } void SetServerName(const std::string& iServerName) { this->ServerName = iServerName; } void SetDataBaseName(const std::string& iDataBaseName) { this->DataBaseName = iDataBaseName; } void SetTableName(const std::string& iTableName) { this->TableName = iTableName; } void SetUser(const std::string& iUser) { this->User = iUser; } void SetPassword(const std::string& iPassword) { this->PassWord = iPassword; } void SetConnector(vtkMySQLDatabase *iDatabaseConnector) { this->m_DatabaseConnector = iDatabaseConnector; } /** \brief help read content from DB: select all the fields for a given table (TableName)in the database and fills the m_RowContainer with the results: each row from the database will fill an InternalObjectType with true and an OriginalObjectType (exp; GoProjectRow). if there is a need to add a condition on the selection ( add a WHERE), have to use the function SetWhereString( std::string whereString ) from the same class. */ void PopulateFromDB() { this->PopulateColumnNamesContainer(); std::stringstream queryString; queryString << "SELECT * FROM " << this->TableName; if ( IsWhereStringSet ) { queryString << " WHERE " << m_WhereString; } queryString << ";"; vtkSQLQuery *query = m_DatabaseConnector->GetQueryInstance(); query->SetQuery( queryString.str().c_str() ); if ( !query->Execute() ) { // replace by exception std::cerr << "Create query failed" << std::endl; } else { if ( m_RowContainer.size() > 0 ) { m_RowContainer.clear(); } //here the m_RowContainer is filled with all the results of the previous // query: //SELECT * FROM table: while ( query->NextRow() ) { OriginalObjectType object; for ( size_t colID = 0; colID < m_ColumnNamesContainer.size(); colID++ ) { std::string ColumnName = m_ColumnNamesContainer[colID]; object.SetField( ColumnName, query->DataValue(colID).ToString() ); } m_RowContainer.push_back( InternalObjectType(true, object) ); } } //DataBaseConnector->Delete(); query->Delete(); } // save content to DB - ASYNCHRONOUS bool SaveInDB(bool Update = false) { if ( m_RowContainer.empty() ) { return true; } myIteratorType start = m_RowContainer.begin(); myIteratorType end = m_RowContainer.end(); std::sort( start, end, IsLess() ); this->PopulateColumnNamesContainer(); vtkSQLQuery *query = m_DatabaseConnector->GetQueryInstance(); if ( Update ) { if ( this->UpdateRows(query, start, end) ) { query->Delete(); return true; } else { query->Delete(); return false; } } else { if ( this->SaveEachRow(query, false) ) { query->Delete(); return true; } else { query->Delete(); return false; } } } private: /** functor to sort our RowContainer and optimize SQL requests \todo Why not do the opposite: false first and true later? Like this, we won't have to iterate on all the true first! Well, it needs to be more investigated!!!*/ struct IsLess { bool operator()(const InternalObjectType & A, const InternalObjectType & B) { // Dirty first if ( A.first && !B.first ) { return true; } return false; } }; // underlying container typedef typename std::vector< InternalObjectType >::iterator myIteratorType; std::vector< InternalObjectType > m_RowContainer; void PopulateColumnNamesContainer(); bool SaveEachRow(vtkSQLQuery *query, bool Update = false); bool SaveRows(vtkSQLQuery *query, const std::string & what, const myIteratorType & start, const myIteratorType & end); bool UpdateRows(vtkSQLQuery *query, const myIteratorType & start, const myIteratorType & end); // colum names container std::vector< std::string > m_ColumnNamesContainer; // DB variables vtkMySQLDatabase *m_DatabaseConnector; std::string ServerName; std::string DataBaseName; std::string TableName; std::string User; std::string PassWord; std::string m_WhereString; bool IsWhereStringSet; bool IsOpen; }; template< class TObject > bool GoDBRecordSet< TObject >::SaveEachRow(vtkSQLQuery *query, bool Update) { // modified rows myIteratorType start = m_RowContainer.begin(); myIteratorType firstFalseElement = start; myIteratorType end = m_RowContainer.end(); while ( ( *firstFalseElement ).first && firstFalseElement != end ) { ++firstFalseElement; } // Here we suppose read and write only, no overwrite //if( end-start > 0 ) // { // if( !SaveRows( query, "REPLACE ", start, end ) ) // { // return false; // } // } // new rows if ( end - firstFalseElement > 0 ) { if ( Update ) { if ( !UpdateRows(query, firstFalseElement, end) ) { return false; } } else { if ( !SaveRows(query, "INSERT ", firstFalseElement, end) ) { return false; } } } return true; } /**\brief uses the INSERT or REPLACE query to save all the objects GoDB..Row currently in the m_RowContainer located between start and end */ template< class TObject > bool GoDBRecordSet< TObject >::SaveRows(vtkSQLQuery *query, const std::string& what, const myIteratorType& start, const myIteratorType& end) { // safe test /*unsigned int NbOfCol = m_ColumnNamesContainer.size(); if( NbOfCol == 0 ) { // throw exception std::cerr << "Could not extract column names." << std::endl; return false; }*/ // invariant part of the query: corresponds to the insert/replace into table //(names of all the columns): myIteratorType rowIt = start; std::stringstream queryString; queryString << what << "INTO " << this->TableName; queryString << " ( "; queryString << rowIt->second.PrintColumnNames(); queryString << " ) "; queryString << " VALUES "; // row dependent part of the query: one row corresponds to the values of one //OriginalObjectType (exp:GoProjectRow)to be saved into the Database. So this // part //saves the values for all the OriginalObjectType contained in the vector // m_RowContainer: while ( rowIt != end ) { std::stringstream rowQueryString; rowQueryString << queryString.str(); rowQueryString << "("; rowQueryString << rowIt->second.PrintValues(); rowQueryString << ");"; query->SetQuery( rowQueryString.str().c_str() ); if ( !query->Execute() ) { // replace by exception std::cerr << "Save query failed: "; std::cerr << rowQueryString.str().c_str() << std::endl; return false; } ++rowIt; } return true; } /**\brief uses the INSERT or REPLACE query to save all the objects GoDB..Row currently in the m_RowContainer located between start and end */ template< class TObject > bool GoDBRecordSet< TObject >::UpdateRows(vtkSQLQuery *query, const myIteratorType& start, const myIteratorType& end) { myIteratorType rowIt = start; std::stringstream queryString; queryString << "UPDATE "; queryString << this->TableName << " SET "; queryString << rowIt->second.PrintColumnNamesWithValues(); queryString << " WHERE "; queryString << rowIt->second.GetTableIDName(); queryString << " = "; queryString << rowIt->second.GetMapValue( rowIt->second.GetTableIDName() ); // row dependent part of the query: one row corresponds to the values of one //OriginalObjectType (exp:GoProjectRow)to be saved into the Database. So this // part //saves the values for all the OriginalObjectType contained in the vector // m_RowContainer: while ( rowIt != end ) { queryString << ";"; query->SetQuery( queryString.str().c_str() ); if ( !query->Execute() ) { // replace by exception std::cerr << "Save query failed: "; std::cerr << queryString.str().c_str() << std::endl; return false; } rowIt++; } return true; } /** \brief fills the vector m_ColumnNamesContainer with the column names gotten from the database and in the same order as the query results will be given:(only way to retrieve which query->datavalue corresponds to which field). */ template< class TObject > void GoDBRecordSet< TObject >::PopulateColumnNamesContainer() { if ( m_ColumnNamesContainer.size() > 0 ) { m_ColumnNamesContainer.clear(); } vtkSQLQuery * query = m_DatabaseConnector->GetQueryInstance(); std::stringstream querystream; querystream << "SHOW COLUMNS FROM "; querystream << this->TableName; //querystream << " FROM "; //querystream << this->DataBaseName; querystream << ";"; query->SetQuery( querystream.str().c_str() ); if ( !query->Execute() ) { // replace by exception std::cerr << "Create query failed" << std::endl; } else { while ( query->NextRow() ) { m_ColumnNamesContainer.push_back( query->DataValue(0).ToString() ); } } query->Delete(); } #endif GoFigure2-v0.9.0/Code/IO/GoDBTWContainerForLineage.h0000644000175000017500000000612711667757442021561 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBTWContainerForLineage_h #define __GoDBTWContainerForLineage_h #include "GoDBTWContainerForTrackLineage.h" #include "QGoIOConfigure.h" #include "GoFigureLineageAttributes.h" /** \class GoDBTWContainerForLineage \brief This class describes the specificities of the GoDBTWContainerForTrackLineage for lineage \ingroup DB */ class QGOIO_EXPORT GoDBTWContainerForLineage:public GoDBTWContainerForTrackLineage { public: GoDBTWContainerForLineage(int iImgSessionID); ~GoDBTWContainerForLineage(); virtual TWContainerType GetContainerForOneSpecificTrace( vtkMySQLDatabase *iDatabaseConnector, int iTraceID ); void SetLineageAttributes(GoFigureLineageAttributes iLineageAttributes); protected: GoFigureLineageAttributes m_LineageAttributes; /** \brief add the specific info for a lineage to the columns description */ void SetSpecificInfoForLineageTable(); /** \brief get the values from m_LineageAttributes and the names of the calculated values from m_LineageAttributes and fill the corresponding columns of the row container with them */ void FillRowContainerForLineageComputedValues(); void GetValuesAndNamesForLineageComputedValues( GoFigureLineageAttributes iLineageAttributes, std::vector< std::vector< std::string > > & ioValues, std::vector< std::string > & ioNames); }; #endif GoFigure2-v0.9.0/Code/IO/vtkPolyDataMySQLTrackReader.h0000644000175000017500000000621511667757442022172 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkPolyDataMySQLTrackReader_h #define __vtkPolyDataMySQLTrackReader_h #include "vtkSmartPointer.h" #include "vtkObject.h" #include #include #include "QGoIOConfigure.h" class vtkPolyData; /** \defgroup MySQLReader MySQLReader \defgroup Track Track \defgroup Trace Trace */ /** \class vtkPolyDataMySQLTrackReader \brief Reads a string and convert it into a track polydata \ingroup MySQLReader Track Trace */ class QGOIO_EXPORT vtkPolyDataMySQLTrackReader:public vtkObject { public: /* * \brief Public constructor */ static vtkPolyDataMySQLTrackReader * New(); vtkTypeRevisionMacro(vtkPolyDataMySQLTrackReader, vtkObject); /* * \brief Generate a "Track Polydata" from a string * \param[in] iString base string to generate the polydata * \return pointer to the generated "Track Polydata" */ vtkSmartPointer GetPolyData(const std::string & iString); /* * \brief Generate a "Track Polydata" from a string * \param[in] iString base string to generate the polydata * \return pointer to the generated "Track Polydata" */ std::map< unsigned int, double* > GetMap(const std::string & iString); protected: vtkPolyDataMySQLTrackReader(); virtual ~vtkPolyDataMySQLTrackReader(); private: vtkPolyDataMySQLTrackReader(const vtkPolyDataMySQLTrackReader &); void operator=(const vtkPolyDataMySQLTrackReader &); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBTWContainerForMesh.cxx0000644000175000017500000004302611667757442021463 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBTWContainerForMesh.h" GoDBTWContainerForMesh::GoDBTWContainerForMesh(int iImgSessionID) : GoDBTWContainerForContourMesh("mesh", "track", iImgSessionID), m_MeshAttributes(NULL) { this->SetSpecificInfoForMeshTable(); //checker the columnsinfo } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBTWContainerForMesh::~GoDBTWContainerForMesh() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForMesh::SetColumnsInfoBasedOnChannelsInfo() { //Get the info for the total intensities per channel: GoDBTraceInfoForTableWidget temp; std::pair< GoDBTraceInfoForTableWidget, std::vector< std::string > > PairTemp; size_t NumberOfChannels = this->m_ChannelsInfo.size(); if ( this->m_ChannelsInfo.empty() ) { std::cout << "No info for the channels" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return; } for ( size_t i = 0; i < NumberOfChannels; i++ ) { std::string InfoName = "TotalIntensityForChannelID"; InfoName += this->m_ChannelsInfo.at(i).at(1); temp.InfoName = InfoName; temp.ColumnNameDatabase = "Value"; std::string ColumnNameTableWidget = "T.I."; ColumnNameTableWidget += this->m_ChannelsInfo.at(i).at(0); temp.ColumnNameTableWidget = ColumnNameTableWidget; temp.ToolTip = "Total Intensity For the Channel"; temp.TableNameDatabase = "intensity"; temp.TableForeignKeyDatabase = "MeshID"; temp.TableKeyDatabase = "MeshID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForMesh::SetSpecificInfoForMeshTable() { GoDBTraceInfoForTableWidget temp; std::pair< GoDBTraceInfoForTableWidget, std::vector< std::string > > PairTemp; //Get the info for the Volume: temp.InfoName = "Volume"; temp.ColumnNameTableWidget = "Volume"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Surface Area: temp.InfoName = "SurfaceArea"; temp.ColumnNameTableWidget = "SurfaceArea"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for CelltypeID: temp.InfoName = "CellTypeID"; temp.ColumnNameDatabase = "CellTypeID"; temp.TableNameDatabase = this->m_TracesName; temp.TableForeignKeyDatabase = "CellTypeID"; temp.TableKeyDatabase = "CellTypeID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the celltype name: temp.ColumnNameTableWidget = "CellType"; temp.ColumnNameDatabase = "Name"; temp.TypeName = "string"; temp.TableNameDatabase = "celltype"; temp.InfoName = "CellTypeName"; temp.TableForeignKeyDatabase = "CellTypeID"; temp.TableKeyDatabase = "CellTypeID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for SubCelltypeID: temp.InfoName = "SubCellTypeID"; temp.ColumnNameDatabase = "SubCellularID"; temp.TableNameDatabase = this->m_TracesName; temp.TableForeignKeyDatabase = "SubCellularID"; temp.TableKeyDatabase = "SubCellularID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the SubCellType name: temp.ColumnNameTableWidget = "SubCellType"; temp.ColumnNameDatabase = "Name"; temp.TypeName = "string"; temp.TableNameDatabase = "subcellulartype"; temp.InfoName = "SubCellTypeName"; temp.TableForeignKeyDatabase = "SubCellularID"; temp.TableKeyDatabase = "SubCellularID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForMesh::FillRowContainerForMeshValues( vtkMySQLDatabase *iDatabaseConnector, std::vector< std::string > iVectMeshIDs) { std::vector< std::vector< std::string > > ValuesToFill; std::vector< std::string > SelectFields; this->GetValuesForIntensities(iDatabaseConnector, iVectMeshIDs, ValuesToFill, SelectFields); //if the mesh was just created from the visu (so there is only one): if ( this->m_MeshAttributes != 0 && iVectMeshIDs.size() == 1 ) { this->GetValuesForSurfaceVolume(ValuesToFill, SelectFields); } this->FillRowContainer( ValuesToFill, SelectFields, "ColumnNameTableWidget"); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForMesh::GetValuesForIntensities( vtkMySQLDatabase *iDatabaseConnector, std::vector< std::string > iVectMeshIDs, std::vector< std::vector< std::string > > & ioValuesToFill, std::vector< std::string > & ioSelectFields) { if ( this->m_ChannelsInfo.empty() ) { this->SetChannelsInfo(iDatabaseConnector); } //fill the columns names to be filled in the row container: for ( unsigned int i = 0; i < this->m_ChannelsInfo.size(); i++ ) { std::string NameTableWidgetColumn = "T.I."; NameTableWidgetColumn += this->m_ChannelsInfo.at(i).at(0); ioSelectFields.push_back(NameTableWidgetColumn); } if ( iVectMeshIDs.empty() ) { return; } //get the needed data from the database: std::vector< std::string > SelectedFields(3); SelectedFields.at(0) = "mesh.meshid"; SelectedFields.at(1) = "left(points,10) as points"; SelectedFields.at(2) = "value"; std::vector< std::string > ResultQuery; if ( iVectMeshIDs.size() == 1 ) { this->GetIntensityValuesForOneMesh(iVectMeshIDs.front(), ioValuesToFill, iDatabaseConnector); } else { std::vector< FieldWithValue > Condition(1); FieldWithValue ImgSession = { "ImagingSessionID", ConvertToString< int >(this->m_ImgSessionID), "=" }; Condition[0] = ImgSession; FieldWithValue JoinCondition = { this->m_TracesIDName, this->m_TracesIDName, "=" }; ResultQuery = GetAllSelectedValuesFromTwoTables( iDatabaseConnector, this->m_TracesName, "intensity", SelectedFields, JoinCondition, Condition); this->GetValuesToFillForIntensityFromQueryResults( ResultQuery, iVectMeshIDs, ioValuesToFill); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForMesh::GetIntensityValuesForOneMesh(std::string iMeshID, std::vector< std::vector< std::string > > & ioValuesToFill, vtkMySQLDatabase *iDatabaseConnector) { std::vector< std::string > temp; for ( unsigned int i = 0; i < this->m_ChannelsInfo.size(); i++ ) { std::string ChannelIDValue = this->m_ChannelsInfo.at(i).at(1); std::vector< FieldWithValue > Conditions(2); FieldWithValue MeshID = { "MeshID", iMeshID, "=" }; FieldWithValue ChannelID = { "ChannelID", ChannelIDValue, "=" }; Conditions[0] = MeshID; Conditions[1] = ChannelID; int ValueIntensity = FindOneID(iDatabaseConnector, "intensity", "Value", Conditions); if ( ValueIntensity == -1 ) { temp.push_back(""); } else { temp.push_back( ConvertToString< int >(ValueIntensity) ); } } ioValuesToFill.push_back(temp); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForMesh::GetValuesToFillForIntensityFromQueryResults (std::vector< std::string > iResultQuery, std::vector< std::string > iVectMeshIDs, std::vector< std::vector< std::string > > & ioValuesToFill) { std::vector< std::string >::iterator iterResult = iResultQuery.begin(); //iResultQuery has meshid, points, value for channel0, meshid,points, //value for channel1.... std::vector< std::string >::iterator iterMeshID = iVectMeshIDs.begin(); size_t i; while ( ( iterMeshID != iVectMeshIDs.end() ) && ( iterResult != iResultQuery.end() ) ) { ++iterResult; std::vector< std::string > temp; std::string Points = *iterResult; std::string IntensityValue; if ( ( Points == "0" ) || ( Points == "" ) ) //if the mesh has no points, he // has no intensity { IntensityValue = ""; for ( i = 0; i < this->m_ChannelsInfo.size(); i++ ) { temp.push_back(IntensityValue); } // iterResult = iterResult + 2; if( iterResult != iResultQuery.end() ) { ++iterResult; } else { itkGenericExceptionMacro( << "iterResult == iResultQuery" ); } if( iterResult != iResultQuery.end() ) { ++iterResult; } else { itkGenericExceptionMacro( << "iterResult == iResultQuery" ); } } else { if( iterResult != iResultQuery.end() ) { ++iterResult; } else { itkGenericExceptionMacro( << "iterResult == iResultQuery" ); } for ( i = 0; i < this->m_ChannelsInfo.size() - 1; i++ ) { if ( iterResult != iResultQuery.end() ) { IntensityValue = *iterResult; temp.push_back(IntensityValue); } // iterResult = iterResult + 3; if( iterResult != iResultQuery.end() ) { ++iterResult; } else { itkGenericExceptionMacro( << "iterResult == iResultQuery" ); } if( iterResult != iResultQuery.end() ) { ++iterResult; } else { itkGenericExceptionMacro( << "iterResult == iResultQuery" ); } if( iterResult != iResultQuery.end() ) { ++iterResult; } else { itkGenericExceptionMacro( << "iterResult == iResultQuery" ); } } IntensityValue = *iterResult; temp.push_back(IntensityValue); if( iterResult != iResultQuery.end() ) { ++iterResult; } else { itkGenericExceptionMacro( << "iterResult == iResultQuery" ); } } ioValuesToFill.push_back(temp); ++iterMeshID; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForMesh::FillRowContainerForMeshValues( vtkMySQLDatabase *iDatabaseConnector, int iMeshID) { std::vector< std::string > MeshIDs; MeshIDs.push_back( ConvertToString< int >(iMeshID) ); this->FillRowContainerForMeshValues(iDatabaseConnector, MeshIDs); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForMesh::GetValuesForSurfaceVolume( std::vector< std::vector< std::string > > & ioValuesToFill, std::vector< std::string > & ioSelectFields) { if ( this->m_MeshAttributes != 0 ) { if ( ioValuesToFill.size() != 1 ) { std::cout << "more than 1 mesh for volume and surface values" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return; } else { std::vector< std::string > temp = ioValuesToFill.at(0); ioSelectFields.push_back("Volume"); temp.push_back( ConvertToString< double >(this->m_MeshAttributes->m_Volume) ); ioSelectFields.push_back("SurfaceArea"); temp.push_back( ConvertToString< double >(this->m_MeshAttributes->m_Area) ); ioValuesToFill.clear(); ioValuesToFill.push_back(temp); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBTableWidgetContainer::TWContainerType GoDBTWContainerForMesh::GetContainerLoadedWithAllFromDB( vtkMySQLDatabase *iDatabaseConnector, std::list iListTPs) { GoDBTableWidgetContainer::GetContainerLoadedWithAllFromDB(iDatabaseConnector, iListTPs); std::vector< std::string > VectMeshIDs; if (iListTPs.empty() ) { VectMeshIDs = ListSpecificValuesForOneColumn( iDatabaseConnector, "mesh", "MeshID", "ImagingSessionID", ConvertToString< unsigned int >(this->m_ImgSessionID) ); } else { FieldWithValue joinCondition = {"CoordIDMin", "CoordID", "="}; FieldWithValue andCondition = {"ImagingSessionID", ConvertToString< unsigned int >(this->m_ImgSessionID), "="}; std::vector< std::string > VectorValues = ListUnsgIntToVectorString(iListTPs); std::list MeshIDs = GetListValuesFromTwoTablesAndCondition( iDatabaseConnector, "mesh", "coordinate","MeshID", joinCondition, "coordinate.TCoord", VectorValues, andCondition); VectMeshIDs = ListUnsgIntToVectorString(MeshIDs); } this->FillRowContainerForMeshValues(iDatabaseConnector, VectMeshIDs); return this->m_RowContainer; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForMesh::SetChannelsInfo( vtkMySQLDatabase *iDatabaseConnector) { if ( this->m_ChannelsInfo.empty() ) { std::vector< std::string > SelectFields; SelectFields.push_back("Name"); SelectFields.push_back("channel.ChannelID"); std::vector< std::string > JoinTablesOnTraceTable; JoinTablesOnTraceTable.push_back("channel"); JoinTablesOnTraceTable.push_back("image.ChannelID = channel.ChannelID"); this->m_ChannelsInfo = GetValuesFromSeveralTables( iDatabaseConnector, "image", SelectFields, "ImagingSessionID", ConvertToString< unsigned int >(this->m_ImgSessionID), JoinTablesOnTraceTable, true); //this->SetSpecificColumnsInfoForMesh(); this->SetColumnsInfoBasedOnChannelsInfo(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBTableWidgetContainer::TWContainerType GoDBTWContainerForMesh::GetContainerForOneSpecificTrace( vtkMySQLDatabase *iDatabaseConnector, int iTraceID) { GoDBTableWidgetContainer::GetContainerForOneSpecificTrace(iDatabaseConnector, iTraceID); this->FillRowContainerForMeshValues(iDatabaseConnector, iTraceID); this->m_MeshAttributes = 0; return this->m_RowContainer; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForMesh::SetMeshAttributes( GoFigureMeshAttributes *iMeshAttributes) { this->m_MeshAttributes = iMeshAttributes; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/ContourMeshStructure.cxx0000644000175000017500000001571711667757442021503 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ContourMeshStructure.h" #include #include "vtkPolyData.h" #include "vtkProperty.h" #include "vtkActor.h" #include "vtkMapper.h" #include "vtkDoubleArray.h" #include "vtkPointData.h" #include "vtkLookupTable.h" //-------------------------------------------------------------------------- ContourMeshStructure::ContourMeshStructure() : TraceStructure(), TCoord(0) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- ContourMeshStructure::ContourMeshStructure(const unsigned int & iTraceID, const unsigned int & iCollectionID, std::vector< vtkActor * > iActors, vtkPolyData *iNodes, const unsigned int & iT, const bool & iHighlighted, const bool & iVisible, const double & r, const double & g, const double & b, const double & alpha) : TraceStructure(iTraceID, iCollectionID, iActors, iNodes, iHighlighted, iVisible, r, g, b, alpha), TCoord(iT) { if ( iActors.size() == 4 ) { ActorXY = iActors[0]; ActorXZ = iActors[1]; ActorYZ = iActors[2]; ActorXYZ = iActors[3]; } else { std::cerr << "iActors.size() != 4" << std::endl; return; } this->rgba[0] = r; this->rgba[1] = g; this->rgba[2] = b; this->rgba[3] = alpha; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- ContourMeshStructure::ContourMeshStructure(const unsigned int & iTraceID, const unsigned int & iCollectionID, std::vector< vtkActor * > iActors, vtkPolyData *iNodes, const unsigned int & iT, const bool & iHighlighted, const bool & iVisible, double iRgba[4]) : TraceStructure(iTraceID, iCollectionID, iActors, iNodes, iHighlighted, iVisible, iRgba), TCoord(iT) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- ContourMeshStructure::ContourMeshStructure(const unsigned int & iTraceID, const unsigned int & iCollectionID, vtkActor *iActorXY, vtkActor *iActorYZ, vtkActor *iActorXZ, vtkActor *iActorXYZ, vtkPolyData *iNodes, const unsigned int & iT, const bool & iHighlighted, const bool & iVisible, const double & r, const double & g, const double & b, const double & alpha) : TraceStructure(iTraceID, iCollectionID, iActorXY, iActorYZ, iActorXZ, iActorXYZ, iNodes, iHighlighted, iVisible, r, g, b, alpha), TCoord(iT) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- ContourMeshStructure::ContourMeshStructure(const ContourMeshStructure & iE) : TraceStructure(iE), TCoord(iE.TCoord) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- ContourMeshStructure::~ContourMeshStructure() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool ContourMeshStructure::IsAContour() { return ( this->GetDirection() != -1 ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int ContourMeshStructure::GetDirection() { double bounds[6]; this->Nodes->GetBounds(bounds); int oDir = -1; for ( int i = 0; i < 3; i++ ) { if ( bounds[2 * i] == bounds[2 * i + 1] ) { oDir = 2 - i; } } return oDir; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void ContourMeshStructure:: ModifyCollectionID(unsigned int iCollectionID) { this->CollectionID = iCollectionID; } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/GoDBExport.h0000644000175000017500000003033611667757442016710 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBExport_h #define __GoDBExport_h #include "vtkMySQLDatabase.h" #include #include "QGoIOConfigure.h" /** \class GoDBExport \brief export the data from the database into a textfile \ingroup DB */ class QGOIO_EXPORT GoDBExport { public: GoDBExport(std::string iServerName, std::string iLogin, std::string iPassword, int iImagingSessionID, std::string iFilename); virtual ~GoDBExport(); /** \brief get all the imagingsession info,the info for the contours, the meshes they belong to and the tracks the previous meshes belong to from the database and put them in a text file */ void ExportContours(); /** \brief get all the imagingsession info,the info for the meshes with points(that can be visualized), the tracks they belong to and the lineages the previous tracks belong to from the database and put them in a text file */ void ExportMeshes(); private: vtkMySQLDatabase *m_DatabaseConnector; std::string m_ServerName; std::string m_Password; std::string m_Login; int m_ImagingSessionID; std::fstream m_outfile; std::string m_NameDocXml; std::vector< std::string > m_VectorContourIDs; std::vector< std::string > m_VectorMeshIDs; std::vector< std::string > m_VectorTrackIDs; std::vector< std::string > m_VectorLineageIDs; std::vector< std::string > m_VectorChannelIDs; /** \brief get the info for imagingsession from the database \return a vector of pair containing the name of the info as .first and the info as .second. for Imagingsession such as Name, creation date and microscope name */ std::vector< std::pair< std::string, std::string > > GetImagingSessionInfoFromDB(); /** \brief get one info for the current imagingsession from the database corresponding to the iNameInfo \param[in] iNameInfo name of the field in the database \return a pair containing as .first the iNameInfo and as.second the corresponding info found in the Database for the table imagingsession */ std::pair< std::string, std::string > GetOneInfoFromDBForImgSession( std::string iNameInfo); /** \brief Write the generale info about the textfile */ void WriteGeneraleInfo(); /** \brief get the info from the database for all the entities from a table or with a limitation defined with field and value and write them in the output file after having written first the number of entities to be described \param[in] iField field defining the limitation \param[in] iValue value defining the limitation \tparam T children of GoDBRow */ template< typename T > void WriteTableInfoFromDB(std::string iField, std::string iValue) { T TableRow; std::vector< std::string > ListTableIDs = ListSpecificValuesForOneColumn( this->m_DatabaseConnector, TableRow.GetTableName(), TableRow.GetTableIDName(), iField, iValue); std::vector< std::string >::iterator iter = ListTableIDs.begin(); while ( iter != ListTableIDs.end() ) { std::vector< std::pair< std::string, std::string > > EntityInfo = this->GetOneEntityInfoFromDB(*iter, TableRow); this->WriteOnTheOutputFile(TableRow.GetTableName(), EntityInfo); iter++; } } /** \brief get the info from the database for all the entities from a table which IDs are in iListIDs and write them in the output file \param[in] iListIDs List of the IDs for which the info need to be written \tparam children of GoDBRow */ template< typename T > void WriteTableInfoFromDB(std::vector< std::string > iListIDs) { T TableRow; if ( iListIDs.empty() ) { this->WriteNumberOfEntities(TableRow.GetTableName(), 0); return; } this->WriteNumberOfEntities( TableRow.GetTableName(), iListIDs.size() ); std::vector< std::string >::iterator iter = iListIDs.begin(); while ( iter != iListIDs.end() ) { std::vector< std::pair< std::string, std::string > > EntityInfo = this->GetOneEntityInfoFromDB(*iter, TableRow); this->WriteOnTheOutputFile(TableRow.GetTableName(), EntityInfo); iter++; } } /** \brief get the info with their names for an entity from the database and put them in a vector of pair of string (name of the info + value of the info) \param[in] iEntityID ID of the entity for which the info are needed \param[in] iTableRow \tparam T children of GoDBRow \return vector of pair of string (name of the info + value of the info) */ template< typename T > std::vector< std::pair< std::string, std::string > > GetOneEntityInfoFromDB(std::string iEntityID, T iTableRow) { std::vector< std::pair< std::string, std::string > > oEntityInfo = std::vector< std::pair< std::string, std::string > >(); iTableRow.SetValuesForSpecificID(atoi( iEntityID.c_str() ), this->m_DatabaseConnector); std::vector< std::string > FieldNames = iTableRow.GetVectorColumnNames(); std::vector< std::string >::iterator iter = FieldNames.begin(); while ( iter != FieldNames.end() ) { std::pair< std::string, std::string > FieldInfo; FieldInfo.first = *iter; FieldInfo.second = iTableRow.GetMapValue(*iter); oEntityInfo.push_back(FieldInfo); iter++; } return oEntityInfo; } /** \brief fill the different vectors needed for the queries depending if the vectors of IDs are empty or not: get the tables names, the key for the table and the tracesIDs \param[in,out] ioVectorTableNames names of the tables \param[in,out] ioVectorTracesIDs IDs of the traces \param[in,out] ioVectorFields names of the database fields \param[in] IncludeChannelIDs */ void GetVectorsTableNamesTracesIDsAndFields( std::vector< std::string > & ioVectorTableNames, std::vector< std::vector< std::string > > & ioVectorTracesIDs, std::vector< std::string > & ioVectorFields, bool IncludeChannelIDs = false); /** \brief Get the celltype and subcelltype for the needed meshes from the database and write them on the output file */ void WriteCellTypeAndSubCellTypeInfoFromDatabase(); /** \brief get the contours info which IDs are in the m_VectorContourIDs from the database and write them on the output file */ void WriteContoursInfoFromDatabase(); /** \brief get the tracks info which IDs are in the m_VectorTrackIDs from the database and write them on the output file */ void WriteTracksInfoFromDatabase(); /** \brief get the meshes info which IDs are in the m_VectorMeshIDs from the database and write them on the output file */ void WriteMeshesInfoFromDatabase(); /** \brief get the lineages info which IDs are in the m_VectorLineageIDs from the database and write them on the output file */ void WriteLineagesInfoFromDatabase(); /** \brief get the channels info which IDs are in the m_VectorChannelIDs from the database and write them on the output file */ void WriteChannelsInfoFromDatabase(); /** \brief get the info for the intensities corresponding to the m_VectorMeshIDs and the m_VectorChannelIDs and write them on the output file */ void WriteIntensityInfoFromDatabase(); /** \brief get the IDs of the contour belonging to the current imagingsession and fill the m_VectorContourIDs with them */ void UpdateVectorContourIDsForExportContours(); /** \brief when exporting contours, if the contours belong to meshes, the info regarding these meshes are needed also, so fill m_VectorMeshIDs with these meshes IDs */ void UpdateVectorMeshIDsForExportContours(); /** \brief when exporting meshes, we don't export the potential contours associated to the meshes, so we clear m_VectorContourIDs */ void UpdateVectorContourIDsForExportMeshes(); /** \brief when exporting meshes, we export only the meshes with a 3D surface so we fill the m_VectorMeshIDs with the meshes with a non empty "Points" column from the database */ void UpdateVectorMeshIDsForExportMeshes(); /** \brief when exporting meshes, the total intensity per channel has to be calculated, and the info for the channels need to be stored */ void UpdateVectorChannelIDsForExportMeshes(); /** \brief check if for the meshes IDs found in the m_VectorMeshIDs, the corresponding meshes belongs to tracks, if so these tracks IDs are put in the m_VectorTrackIDs */ void UpdateVectorTrackIDsToExportInfo(); /** \brief check if for the tracks IDs found in the m_VectorTrackIDs, the corresponding tracks belongs to lineages, if so these lineages IDs are put in the m_VectorLineageIDs */ void UpdateVectorLineageIDsToExportInfo(); /** \brief fill the different vectors of traces IDs corresponding to the contours to export */ void UpdateAllVectorTracesIDsToExportContours(); /** \brief fill the different vectors of traces IDs corresponding to the meshes to export */ void UpdateAllVectorTracesIDsToExportMeshes(); /** \brief get the colors info from the database for the corresponding traces to export and write them in the output file */ void WriteTheColorsInfoFromDatabase(); /** \brief get the coordinates without doublon corresponding to the coordidmax and min of the traces to export from the database and write them in the output file */ void WriteCoordinatesInfoFromDatabase(); /** \brief put iName within brackets \param[in] iName \return iName within brackets */ std::string GetNameWithBrackets(std::string iName); /** \brief put iName into slash brackets \param[in] iName \return /iName within brackets */ std::string GetNameWithSlashBrackets(std::string iName); /** \brief write on the output file the info contained in the vector with the name of the entity they describe \param[in] iNameOfEntity name of the entity described \param[in] iInfoToWrite info to be written in the output file */ void WriteOnTheOutputFile(std::string iNameOfEntity, std::vector< std::pair< std::string, std::string > > iInfoToWrite); /** \brief write on the output file the number of entities that are exported \param[in] iNameOfEntity entity name \param[in] iNumber number of entities */ void WriteNumberOfEntities(std::string iNameOfEntity, size_t iNumber); /** \brief add 2 spaces to the output file for xml tabulation */ void AddTabulation(); /** \brief open a connection to the database. */ void OpenDBConnection(); /** \brief close and delete the connection to the database. */ void CloseDBConnection(); }; #endif GoFigure2-v0.9.0/Code/IO/vtkPolyDataMySQLContourReader.h0000644000175000017500000000564311667757442022563 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkPolyDataMySQLContourReader_h #define __vtkPolyDataMySQLContourReader_h #include "vtkObject.h" #include class vtkPolyData; #include "vtkSmartPointer.h" #include "QGoIOConfigure.h" /** \defgroup MySQLReader MySQLReader \defgroup Contour Contour \defgroup Mesh Mesh \defgroup Trace Trace */ /** \class vtkPolyDataMySQLContourReader \brief Reads a string and convert it into a contour polydata \ingroup MySQLReader Contour Trace */ class QGOIO_EXPORT vtkPolyDataMySQLContourReader:public vtkObject { public: /* * \brief Public constructor */ static vtkPolyDataMySQLContourReader * New(); vtkTypeRevisionMacro(vtkPolyDataMySQLContourReader, vtkObject); /* * \brief Generate a contour from a string * \param[in] iString base string to generate the polydata * \return pointer to the generated contour/mesh */ vtkSmartPointer GetPolyData(const std::string & iString); protected: vtkPolyDataMySQLContourReader(); virtual ~vtkPolyDataMySQLContourReader(); private: vtkPolyDataMySQLContourReader(const vtkPolyDataMySQLContourReader &); void operator=(const vtkPolyDataMySQLContourReader &); }; #endif GoFigure2-v0.9.0/Code/IO/VisualizePolydataHelper.h0000644000175000017500000001046611667757442021546 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __VisualizePolydataHelper_h #define __VisualizePolydataHelper_h #include "vtkSmartPointer.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkImageViewer2.h" #include "vtkExtractVOI.h" void ShowPolyData(vtkPolyData *iPolyData) { vtkSmartPointer< vtkPolyDataMapper > mapper = vtkSmartPointer< vtkPolyDataMapper >::New(); mapper->SetInput(iPolyData); vtkSmartPointer< vtkActor > actor = vtkSmartPointer< vtkActor >::New(); actor->SetMapper(mapper); vtkSmartPointer< vtkRenderer > renderer = vtkSmartPointer< vtkRenderer >::New(); renderer->AddActor(actor); vtkSmartPointer< vtkRenderWindow > renderWindow = vtkSmartPointer< vtkRenderWindow >::New(); renderWindow->AddRenderer(renderer); vtkSmartPointer< vtkRenderWindowInteractor > renderWindowInteractor = vtkSmartPointer< vtkRenderWindowInteractor >::New(); renderWindowInteractor->SetRenderWindow(renderWindow); renderWindowInteractor->Initialize(); renderWindow->Render(); renderWindowInteractor->Start(); } void ShowImage(vtkImageData *iData) { // Create the rendering window vtkSmartPointer< vtkRenderer > ren1 = vtkSmartPointer< vtkRenderer >::New(); vtkSmartPointer< vtkRenderWindow > renWin = vtkSmartPointer< vtkRenderWindow >::New(); vtkSmartPointer< vtkRenderWindowInteractor > iren = vtkSmartPointer< vtkRenderWindowInteractor >::New(); // Create the rendering window renWin->AddRenderer(ren1); iren->SetRenderWindow(renWin); vtkSmartPointer< vtkImageViewer2 > viewer = vtkSmartPointer< vtkImageViewer2 >::New(); /*vtkSmartPointer voi = vtkSmartPointer::New(); voi->SetInput(iData); voi->SetVOI(25, 75, 25, 75, 25, 75); voi->Update();*/ viewer->SetInput(iData); viewer->SetRenderWindow(renWin); viewer->SetRenderer(ren1); iren->Initialize(); viewer->Render(); iren->Start(); } void ShowActor(vtkActor *iActor) { vtkSmartPointer< vtkRenderer > renderer = vtkSmartPointer< vtkRenderer >::New(); renderer->AddActor(iActor); vtkSmartPointer< vtkRenderWindow > renderWindow = vtkSmartPointer< vtkRenderWindow >::New(); renderWindow->AddRenderer(renderer); vtkSmartPointer< vtkRenderWindowInteractor > renderWindowInteractor = vtkSmartPointer< vtkRenderWindowInteractor >::New(); renderWindowInteractor->SetRenderWindow(renderWindow); renderWindowInteractor->Initialize(); renderWindow->Render(); renderWindowInteractor->Start(); } #endif GoFigure2-v0.9.0/Code/IO/QueryBuilderHelper.h0000644000175000017500000003265711667757442020517 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QueryBuilderHelper_h #define __QueryBuilderHelper_h #include #include #include #include #include "QGoIOConfigure.h" #include "QGoIOConfigure.h" struct QGOIO_EXPORT FieldWithValue { std::string Field; std::string Value; std::string Operator; }; /** \brief SELECT iWhat FROM iWhere WHERE iConditions \param[in] iWhat list of attributes separated by commas \param[in] iWhere list of tables, included joined tables \param[in] iConditions list of conditions \return the string corresponding to the query part */ QGOIO_EXPORT std::string SelectGeneralQueryConditions( const std::string & iWhat, const std::string & iWhere, const std::string & iConditions); /** \brief SELECT iWhat FROM iWhere iOrderByQuery \param[in] iWhat list of attributes separated by commas \param[in] iWhere list of tables, included joined tables \param[in] iOrderByQuery part of the query to order by \return the string corresponding to the query part */ QGOIO_EXPORT std::string SelectGeneralQuery( const std::string & iWhat, const std::string & iWhere, std::string iOrderByQuery = ""); /** \brief DISTINCT iWhat \param[in] iWhat attributes \return part of the query to make iWhat distinct */ QGOIO_EXPORT std::string AddDistinctToWhat(const std::string & iWhat); /** \brief ORDER BY iAttributes iAscDesc \param[in] iAttribute attribute to be sorted \param[in] iAscDesc ascendent or descendent sorting \return the string corresponding to the query part */ QGOIO_EXPORT std::string AddOrderBy(const std::string & iAttribute, std::string iAscDesc = "ASC"); /** \brief iListAttributes[i], iListAttributes[i+1]... \param[in] iListAttributes list of the attributes to be selected \return the string corresponding to the query part */ QGOIO_EXPORT std::string GetSelectedAttributes(const std::vector & iListAttributes); /** \brief (iField = iListValues[i] iConditionConnector iField = iListValues[i+1]...) \param[in] iVectorValues list of all the values iAttribute can be equal to \param[in] iConditionConnector AND/OR \param[in] iField \tparam T \return the string corresponding to the query part */ template< typename T > std::string GetConditions(const std::string & iField, const std::vector & iVectorValues, std::string iConditionConnector = "AND") { std::stringstream oConditions; oConditions << ""; if (!iVectorValues.empty() ) { oConditions << "("; unsigned int i; for ( i = 0; i < iVectorValues.size() - 1; i++ ) { oConditions << iField; oConditions << " = '"; oConditions << iVectorValues[i]; oConditions << "' "; oConditions << iConditionConnector; oConditions << " "; } oConditions << iField; oConditions << " = '"; oConditions << iVectorValues[i]; oConditions << "')"; } return oConditions.str(); } QGOIO_EXPORT std::string GetConditions(const std::vector & iConditions, std::string iConditionConnector = "AND"); QGOIO_EXPORT std::string GetConditions(const std::string & iField, const std::string & iValue, std::string iOperator = "="); /** \brief (iFirstPartCondition AND (iField = iOrVectorValues1 OR iField = iOrVectorValues1...)) */ template< typename T > std::string GetAndORConditions( const FieldWithValue & iFirtsPartCondition, const std::string & iField, const std::vector< T > & iOrVectorValues) { std::string oConditions; std::vector VectorConditions(1); //FieldWithValue AndCondition = {fieldTwo,ValueFieldTwo, "="}; VectorConditions[0] = iFirtsPartCondition; oConditions = GetConditions( VectorConditions, "AND" ); if (!iOrVectorValues.empty() ) { oConditions = oConditions.substr(0, oConditions.size()-1); oConditions += " AND "; oConditions += GetConditions(iField,iOrVectorValues,"OR"); oConditions += ")"; } return oConditions; } //std::string GetConditions(std::vector iConditions, // std::string iConditionConnector = "AND"); //std::string GetConditions(std::string iField, std::string iValue,std::string iOperator = "="); /** \brief SELECT iColumn FROM iTable ORDER BY iOrderByColumnName iAscDesc; \param[in] iTable name of the database table \param[in] iColumn name of the attribute to select \param[in] iOrderByColumnName name of the column by which the results will be sorted, if empty, no sorting \param[in] iAscDesc order to sort the results, ascendent by default \return the string corresponding to the query part */ QGOIO_EXPORT std::string SelectQueryStream( const std::string & iTable, const std::string & iColumn, std::string iOrderByColumnName = "", std::string iAscDesc = "ASC"); /** \brief SELECT iColumn[i],iColumn[i=1]... FROM iTable ORDER BY iOrderByColumnName iAscDesc; \param[in] iTable name of the database table \param[in] iListAttributes name of the attributes to select \param[in] iOrderByColumnName name of the column by which the results will be sorted, if empty, no sorting \param[in] iAscDesc order to sort the results, ascendent by default \return the string corresponding to the query part */ QGOIO_EXPORT std::string SelectQueryStream( const std::string & iTable, const std::vector & iListAttributes, std::string iOrderByColumnName = "", std::string iAscDesc = "ASC"); /** \brief SELECT (Distinct) iColumn FROM iTable WHERE iConditions (ORDER BY irderByColumnName iAscDesc); \param[in] iTable name of the database table \param[in] iColumn name of the attribute to select \param[in] iOrderByColumnName name of the column by which the results will be sorted, if empty, no sorting \param[in] iAscDesc order to sort the results, ascendent by default \param[in] iConditions name of the columns separated by comma that are part of the 'where' \param[in] Distinct true if no doublon allowed \return the string corresponding to the query part */ QGOIO_EXPORT std::string SelectQueryStreamCondition( const std::string & iTable, const std::string & iColumn, const std::string & iConditions, bool Distinct = false, std::string iOrderByColumnName = "", std::string iAscDesc = "ASC"); /** \overload */ QGOIO_EXPORT std::string SelectQueryStreamCondition( const std::string & iTable, const std::string & iColumn, const std::string & iField, const std::string & iValue, std::string iOrderByColumnName = "", std::string iAscDesc = "ASC", bool Distinct = false); /** \overload */ QGOIO_EXPORT std::string SelectQueryStreamCondition( const std::string & iTable, const std::vector & iListAttributes, const std::string & iField, const std::string & iValue, std::string iOrderByColumnName = "", std::string iAscDesc = "ASC"); /** \brief SELECT (Distinct) iColumn FROM iTable WHERE iField = iValue Or/And... \param[in] iTable name of the database table \param[in] iColumn name of the attribute to select \param[in] iField name of the condition \param[in] iListValues values of the condition \param[in] Distinct if set to true no doublon allowed \param[in] iConditionConnector or/and \return the string corresponding to the query part */ QGOIO_EXPORT std::string SelectQueryStreamListConditions( const std::string & iTable, const std::string & iColumn, const std::string & iField, const std::vector< std::string > & iListValues, bool Distinct = false, std::string iConditionConnector = "OR"); /** \overload */ QGOIO_EXPORT std::string SelectQueryStreamListConditions( const std::string & iTable, const std::vector & iListAttributes, const std::string & iField, std::vector< std::string > & iListValues, bool Distinct = false, std::string iConditionConnector = "OR"); /** \overload */ QGOIO_EXPORT std::string SelectQueryStreamListConditions( const std::string & iTable, const std::vector & iListAttributes, const std::string & iField, const std::string & iValue, bool Distinct = false, std::string iConditionConnector = "OR"); /** \overload */ QGOIO_EXPORT std::string SelectQueryStreamListConditions( const std::string & iTable, const std::string & iColumn, const std::vector & iConditions, std::string iConditionConnector = "OR", bool Distinct = false); /** \overload */ QGOIO_EXPORT std::string SelectQueryStreamListConditions( const std::string & iTable, const std::vector & iListAttributes, const std::vector & iConditions, std::string iConditionConnector = "OR", bool Distinct = false, std::string iOrderByColumnName = ""); QGOIO_EXPORT std::vector< std::string > ListUnsgIntToVectorString(const std::list< unsigned int > & iList); QGOIO_EXPORT std::list< unsigned int > VectorStringToUnsgInt(const std::vector< std::string > & iVector); QGOIO_EXPORT std::vector< std::string > VectorUnsgIntToVectorString(const std::vector & iVector); /** \brief iTableOne LEFT JOIN iTableTwo ON iTableOne.iOnCondition/Field = iTableTwo.iOnCondition/Value \param[in] iTableOne table to be joined \param[in] iTableTwo table to be joined to \param[in] iOnCondition join on which condition \param[in] NonNULLRows if the connection is not found for 2 tables, there won't be a result \return the string corresponding to the query part */ QGOIO_EXPORT std::string GetLeftJoinTwoTables( const std::string & iTableOne, const std::string & iTableTwo, const FieldWithValue & iOnCondition, bool NonNULLRows = false); /** \brief (iTable LEFT JOIN iTableTwo ON iTable.iOnCondition/Field = iTableTwo.iOnCondition/Value) LEFT JOIN iTableThree ON iTable.iOnCondition/Field = iTableThree.iOnCondition/Value) \param[in] iTable table to be joined \param[in] iTableTwo table to be joined to the 1rst one \param[in] iTableThree table to be joined ot the 1rst one \param[in] iOnConditionOne join on which condition between table and tableTwo \param[in] iOnConditionTwo join on which condition between table and tableThree \return the string corresponding to the query part */ QGOIO_EXPORT std::string GetLeftJoinThreeTables( const std::string & iTable, const std::string & iTableTwo, const std::string & iTableThree, const FieldWithValue & iOnConditionOne, const FieldWithValue & iOnConditionTwo); QGOIO_EXPORT std::string GetGroupBy(const std::string & iColumn, unsigned int iNumberDoublons); /** \brief SELECT iSelectedAttributes[0], iSelectedAttributes[1]...FROM (iTableOne left join iTableTwo on iJoinConditionOne) left join tableThree on iJoinConditionTwo where (iFieldOne = iValueFieldOne) AND (IDFieldName = iListIDs[0] OR IDFieldName = iListIDs[1] OR....); \param[in] iSelectedAttributes vector of all the attributes to be fetched from the db \param[in] iTableOne main table involved (usually the table for the trace) \param[in] iTableTwo table attached to the main table \param[in] iTableThree table attached to the main table \param[in] iJoinConditionOne describes how the tabletwo is attached to the main table \param[in] iJoinConditionTwo describes how the tablethree is attached to the main table \param[in] iFieldOne first condition \param[in] iValueFieldOne value for the first condition \param[in] iIDFieldName field for the IDName where there is a condition \param[in] iListIDs values for the iIDFieldname \return the string corresponding to the query part */ QGOIO_EXPORT std::string SelectForTracesInfo( const std::vector & iSelectedAttributes, const std::string & iTableOne, const std::string & iTableTwo, const std::string & iTableThree, const FieldWithValue & iJoinConditionOne, const FieldWithValue & iJoinConditionTwo, const std::string & iFieldOne, unsigned int iValueFieldOne, const std::string & iIDFieldName, const std::list< unsigned int > & iListIDs); #endif GoFigure2-v0.9.0/Code/IO/CreateDataBaseHelper.h0000644000175000017500000001345111667757442020662 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __CreateDataBaseHelper_h #define __CreateDataBaseHelper_h #include #include #include "itkMacro.h" #include "vtkMySQLDatabase.h" #include "QGoIOConfigure.h" QGOIO_EXPORT bool IsDatabaseOfGoFigureType( vtkMySQLDatabase *DataBaseConnector); QGOIO_EXPORT bool DoesDatabaseExit(std::string ServerName, std::string login, std::string Password, std::string DBName); QGOIO_EXPORT void Query(vtkMySQLDatabase *DataBaseConnector, std::string queryScript); QGOIO_EXPORT bool CreateGoFigureDataBase( std::string ServerName, std::string login, std::string Password, std::string DBName); QGOIO_EXPORT bool CreateDataBase(vtkMySQLDatabase *DataBaseConnector, std::string DBName); QGOIO_EXPORT void CreateTables( vtkMySQLDatabase *DataBaseConnector); QGOIO_EXPORT void CreateForeignKeys( vtkMySQLDatabase *DataBaseConnector); QGOIO_EXPORT std::string CellTypeTable(); QGOIO_EXPORT std::string AuthorTable(); QGOIO_EXPORT std::string SubCellularTypeTable(); QGOIO_EXPORT std::string CoordinateTable(); QGOIO_EXPORT std::string ColorTableScript(); QGOIO_EXPORT std::string MicroscopeTable(); QGOIO_EXPORT std::string ProjectTable(); QGOIO_EXPORT std::string ImagingSessionTable(); QGOIO_EXPORT std::string TrackFamilyTable(); QGOIO_EXPORT std::string TrackTable(); QGOIO_EXPORT std::string MeshTable(); QGOIO_EXPORT std::string ContourTable(); QGOIO_EXPORT std::string ChannelTable(); QGOIO_EXPORT std::string ImageTable(); QGOIO_EXPORT std::string LineageTable(); QGOIO_EXPORT std::string BookmarkTable(); QGOIO_EXPORT std::string IntensityTable(); QGOIO_EXPORT std::string ValueTypeTable(); QGOIO_EXPORT std::string CalculatedValueTable(); QGOIO_EXPORT std::string ValuePerVectorCoordTable(); QGOIO_EXPORT std::string MeshValueTable(); QGOIO_EXPORT std::string TrackValueTable(); QGOIO_EXPORT std::string ImageValueTable(); QGOIO_EXPORT std::string ImagingSessionValueTable(); QGOIO_EXPORT std::string ContourValueTable(); QGOIO_EXPORT std::string LineageValueTable(); std::string ProjectFK(); std::string ImagingSessionFKMicroscopeName(); std::string ImagingSessionFKProjectName(); std::string ImagingSessionFKCoordIDMin(); std::string ImagingSessionFKCoordIDMax(); std::string TrackFamilyFKTrackIDDaughter1(); std::string TrackFamilyFKTrackIDDaughter2(); std::string TrackFamilyFKTrackIDMother(); std::string TrackFKColor(); std::string TrackFKLineage(); std::string TrackFKCoordIDMax(); std::string TrackFKCoordIDMin(); std::string TrackFKTrackFamily(); std::string TrackFKImagingSession(); std::string MeshFKImagingSession(); std::string MeshFKTrackID(); std::string MeshFKColor(); std::string MeshFKCoordIDMin(); std::string MeshFKCoordIDMax(); std::string MeshFKSubCellType(); std::string MeshFKCellType(); std::string ContourFKImagingSession(); std::string ContourFKCoordIDMin(); std::string ContourFKCoordIDMax(); std::string ContourFKMesh(); std::string ChannelFKColor(); std::string ChannelFKImagingSession(); std::string ImageFKChannel(); std::string ImageFKCoordIDMin(); std::string ImageFKImagingSession(); std::string LineageFKImagingSession(); std::string LineageFKTrackRoot(); std::string LineageFKColor(); std::string LineageFKCoordIDMin(); std::string LineageFKCoordIDMax(); std::string BookmarkFKCoord(); std::string BookmarkFKImagingSession(); std::string IntensityFKChannel(); std::string IntensityFKMesh(); std::string ValueperVectorCoordFKCalculatedValue(); std::string CalculatedValueFKValueType(); std::string MeshValueFKCalculatedValue(); std::string MeshValueFKMesh(); std::string TrackValueFKCalculatedValue(); std::string TrackValueFKTrack(); std::string ImageValueFKCalculatedValue(); std::string ImageValueFKImage(); std::string ImagingSessionValueFKCalculatedValue(); std::string ImagingSessionValueFKImagingSession(); std::string ContourValueFKCalculatedValue(); std::string ContourValueFKContour(); std::string LineageValueFKCalculatedValue(); std::string LineageValueFKLineage(); #endif GoFigure2-v0.9.0/Code/IO/VolumeBuilderHelper.h0000644000175000017500000000442011667757442020644 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __VolumeBuilderHelper_h #define __VolumeBuilderHelper_h #include class vtkImageData; class vtkImageAppend; template< class TReader > void AddToVolumeBuilder( const int & iId, const std::string & iFileName, vtkImageAppend *iBuilder) { typedef TReader ReaderType; ReaderType *reader = ReaderType::New(); reader->SetFileName( iFileName.c_str() ); reader->SetFileDimensionality(2); reader->Update(); iBuilder->SetInput( iId, reader->GetOutput() ); reader->Delete(); } #endif GoFigure2-v0.9.0/Code/IO/TrackStructure.h0000644000175000017500000001336211667757442017720 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __TrackStructure_h #define __TrackStructure_h #include "TraceStructure.h" #include "QGoIOConfigure.h" #include "TreeNodeStructure.h" #include "GoFigureTrackAttributes.h" #include "vtkActor.h" #include #ifndef DOXYGEN_SHOULD_SKIP_THIS #include "StructureHelper.h" #endif class vtkIntArray; /** \defgroup Track Track */ /** * \struct TrackStructure * \brief Structure which represent a track, and used for * interaction between Visualization and TableWidget * \ingroup Track Trace * \todo passe parameters by reference for performance */ class QGOIO_EXPORT TrackStructure : public TraceStructure { public: typedef TrackStructure Self; // contains pointers + actor TreeNodeStructure TreeNode; /** * Map containing all the polydata points ordered by time */ typedef std::map< unsigned int, double* > PointsMapType; typedef PointsMapType::iterator PointsMapIterator; typedef PointsMapType::const_iterator PointsMapConstIterator; PointsMapType PointsMap; /** Default Constructor */ TrackStructure(); /** Constructor by copy */ TrackStructure(const TrackStructure & iE); /** Destructor */ ~TrackStructure(); /** * \brief Insert a point at the current time point. * \param[in] iTime time point where we want to insert the point * \param[in] iPoint new point to be inserted * \return true is element has been inserted, false if not (i.e. there * is already a point associated to this time point). If you want to override * this point, call ReplaceElement(int iTime, double* iPoint) instead. */ bool InsertElement(const unsigned int& iTime, double* iPoint); /** * \brief Delete the point at the current time point. * \param[in] iTime time point where we want to delete the mesh * \return true is element has been deleted, false if there where no point at * the specified time point. */ bool DeleteElement(const unsigned int& iTime); void ReleaseData() const; /** Printing one element. std::cout << element << std::endl; */ friend std::ostream & operator<< (std::ostream & os, const TrackStructure & c) { os << "TraceID " << c.TraceID << std::endl; os << "ActorXY " << c.ActorXY << std::endl; os << "ActorXZ " << c.ActorXZ << std::endl; os << "ActorYZ " << c.ActorYZ << std::endl; os << "ActorXYZ " << c.ActorXYZ << std::endl; os << "Nodes " << c.Nodes << std::endl; os << "Average Volume " << c.m_AverageVolume << std::endl; os << "Map " << std::endl; std::map< unsigned int, double*>::const_iterator end = c.PointsMap.end(); std::map< unsigned int, double*>::const_iterator it = c.PointsMap.begin(); while( it != end ) { os << "Time: " << it->first << std::endl; os << " Coordinate X: " << (it->second)[0] << std::endl; os << " Coordinate Y: " << (it->second)[1] << std::endl; os << " Coordinate Z: " << (it->second)[2] << std::endl; ++it; } os << "Highlighted " << c.Highlighted << std::endl; os << "Visible " << c.Visible << std::endl; os << "RGBA [" << c.rgba[0] << ", " << c.rgba[1] << ", " << c.rgba[2] << ", " << c.rgba[3] << "]" << std::endl; return os; } void UpdateLineWidth( const double& iWidth ) const; void UpdateTracksRepresentation( const double& iRadius, const double& iRadius2 ) const; GoFigureTrackAttributes ComputeAttributes() const; void ModifyDivisionVisibility( const bool& iVisibility ); void ModifyDivisionHighlight( vtkProperty* iProperty, const bool& iHighlight ); void ModifyDivisionColorData( const double* iColor ); // for the highlight void ModifyDivisionColorActor( const double* iColor ); void AddDivisionArray( vtkIntArray* iArray ); void CreateDivisionNode( vtkPolyData* iNode); const bool IsRoot() const; const bool IsLeaf() const; // Add volume to a track // note that added volume can be < 0 void AddVolume(const double& iVolume); // to be moved double m_AverageVolume; }; #endif GoFigure2-v0.9.0/Code/IO/TrackStructure.cxx0000644000175000017500000003001211667757442020262 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "TrackStructure.h" #include #include "vtkPolyData.h" #include "vtkActor.h" #include "vtkDoubleArray.h" #include "vtkPointData.h" #include "vtkProperty.h" #include "vtkSphereSource.h" #include "vtkGlyph3D.h" #include "vtkTubeFilter.h" #include "vtkAppendPolyData.h" #include "vtkMath.h" //-------------------------------------------------------------------------- TrackStructure::TrackStructure() : TraceStructure(), m_AverageVolume(0) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- TrackStructure::TrackStructure(const TrackStructure & iE) : TraceStructure(iE), TreeNode(iE.TreeNode), PointsMap(iE.PointsMap), m_AverageVolume(iE.m_AverageVolume) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- TrackStructure:: ~TrackStructure() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool TrackStructure::InsertElement(const unsigned int & iTime, double *iPoint) { // if there is no point, insert it and return true DeleteElement(iTime); this->PointsMap.insert( std::pair< unsigned int, double * >(iTime, iPoint) ); return true; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool TrackStructure::DeleteElement(const unsigned int & iTime) { // check if there is something at the iTime time point PointsMapIterator pointsMapIterator = this->PointsMap.find(iTime); // if there is a point, delete it and return true if ( pointsMapIterator != this->PointsMap.end() ) { // free memory delete[] pointsMapIterator->second; // clear map this->PointsMap.erase(pointsMapIterator); return true; } // else do nothing and return false return false; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TrackStructure::ReleaseData() const { TraceStructure::ReleaseData(); PointsMapConstIterator begin = this->PointsMap.begin(); PointsMapConstIterator end = this->PointsMap.end(); while ( begin != end ) { delete[] begin->second; ++begin; } TrackStructure* structure = const_cast(this); structure->TreeNode.ReleaseData(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TrackStructure:: UpdateLineWidth(const double &iWidth) const { if( this->ActorXY ) { vtkProperty* property = this->ActorXY->GetProperty(); if( property ) { property->SetLineWidth( iWidth ); } } if( this->ActorXZ ) { vtkProperty* property = this->ActorXZ->GetProperty(); if( property ) { property->SetLineWidth( iWidth ); } } if( this->ActorYZ ) { vtkProperty* property = this->ActorYZ->GetProperty(); if( property ) { property->SetLineWidth( iWidth ); } } if( this->ActorXYZ ) { vtkProperty* property = this->ActorXYZ->GetProperty(); if( property ) { property->SetLineWidth( iWidth ); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TrackStructure:: UpdateTracksRepresentation(const double& iRadius, const double& iRadius2) const { vtkSmartPointer< vtkAppendPolyData > apd = vtkSmartPointer< vtkAppendPolyData >::New(); apd->AddInput(this->Nodes); if ( iRadius ) { vtkSmartPointer< vtkSphereSource > sphere = vtkSmartPointer< vtkSphereSource >::New(); sphere->SetThetaResolution(8); sphere->SetPhiResolution(8); sphere->SetRadius(iRadius); vtkSmartPointer< vtkGlyph3D > glyph = vtkSmartPointer< vtkGlyph3D >::New(); glyph->SetInput(this->Nodes); glyph->SetSource( sphere->GetOutput() ); glyph->Update(); apd->AddInput( glyph->GetOutput() ); } if ( iRadius2 ) { vtkSmartPointer< vtkTubeFilter > tube = vtkSmartPointer< vtkTubeFilter >::New(); tube->SetNumberOfSides(8); tube->SetInput(this->Nodes); tube->SetRadius(iRadius2); tube->Update(); apd->AddInput( tube->GetOutput() ); } apd->Update(); this->Nodes->DeepCopy( apd->GetOutput() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoFigureTrackAttributes TrackStructure::ComputeAttributes() const { GoFigureTrackAttributes oAttributes; // check if there are no points in the map if( PointsMap.empty() ) { return oAttributes; } PointsMapConstIterator it = this->PointsMap.begin(); unsigned int tmin = it->first; unsigned int t0 = tmin; unsigned int t1 = tmin; double *org = it->second; double *p = it->second; double *q = it->second; // if we only have one point in the map ++it; // reset the array vtkDoubleArray *newArray = dynamic_cast< vtkDoubleArray * >( this->Nodes->GetPointData()->GetArray("SpeedInformation") ); newArray->Reset(); newArray->InsertNextValue(0.0); while ( it != this->PointsMap.end() ) { t1 = it->first; q = it->second; oAttributes.distance = sqrt( vtkMath::Distance2BetweenPoints(p, q) ); oAttributes.total_length += oAttributes.distance; oAttributes.max_speed = std::max( oAttributes.max_speed, oAttributes.distance / ( static_cast< double >( t1 - t0 ) ) ); double speed = oAttributes.distance / ( static_cast< double >( t1 - t0 ) ); newArray->InsertNextValue(speed); p = q; t0 = t1; ++it; } if ( t1 == tmin ) { oAttributes.avg_speed = 0.; } else { oAttributes.avg_speed = oAttributes.total_length / static_cast< double >( t1 - tmin ); } oAttributes.distance = sqrt( vtkMath::Distance2BetweenPoints(org, q) ); if ( oAttributes.distance ) { oAttributes.theta = vtkMath::DegreesFromRadians( atan2( ( q[1] - org[1] ), ( q[0] - org[0] ) ) ); oAttributes.phi = vtkMath::DegreesFromRadians( acos( ( q[2] - org[2] ) / oAttributes.distance ) ); } oAttributes.number_meshes = static_cast< unsigned int >( PointsMap.size() ); oAttributes.temporal_extent = ( t1 - tmin ); oAttributes.avg_volume = this->m_AverageVolume/( static_cast< double >( PointsMap.size() ) ); return oAttributes; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TrackStructure:: ModifyDivisionVisibility( const bool& iVisibility ) { /* * \todo Nicolas- should we add/remove the actors from the view */ this->TreeNode.Visible = iVisibility; this->TreeNode.SetActorVisibility( iVisibility ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TrackStructure:: ModifyDivisionHighlight( vtkProperty* iProperty, const bool& iHighlight ) { this->TreeNode.SetActorProperties(iProperty); this->TreeNode.Highlighted = iHighlight; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TrackStructure:: ModifyDivisionColorData( const double* iColor ) { this->TreeNode.rgba[0] = iColor[0]; this->TreeNode.rgba[1] = iColor[1]; this->TreeNode.rgba[2] = iColor[2]; this->TreeNode.rgba[3] = iColor[3]; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TrackStructure:: ModifyDivisionColorActor( const double* iColor ) { if( this->TreeNode.ActorXY ) { this->TreeNode.ActorXY->GetProperty()->SetColor(const_cast(iColor)); } if( this->TreeNode.ActorXZ ) { this->TreeNode.ActorXZ->GetProperty()->SetColor(const_cast(iColor)); } if( this->TreeNode.ActorYZ ) { this->TreeNode.ActorYZ->GetProperty()->SetColor(const_cast(iColor)); } if( this->TreeNode.ActorXYZ ) { this->TreeNode.ActorXYZ->GetProperty()->SetColor(const_cast(iColor)); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TrackStructure:: AddDivisionArray( vtkIntArray* iArray ) { /* * \todo Nicolas-Shouldnt be necessary, missing IsLeaf update?? */ if(this->TreeNode.Nodes) { this->TreeNode.Nodes->GetPointData()->AddArray(iArray); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TrackStructure:: CreateDivisionNode( vtkPolyData* iNode) { if( !this->TreeNode.Nodes ) { this->TreeNode.Nodes = vtkPolyData::New(); } this->TreeNode.Nodes->DeepCopy( iNode ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- const bool TrackStructure:: IsRoot() const { return this->TreeNode.IsRoot(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- const bool TrackStructure:: IsLeaf() const { return this->TreeNode.IsLeaf(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void TrackStructure:: AddVolume(const double& iVolume) { m_AverageVolume += iVolume; // useful for the track editing widget... // temp solution? if(m_AverageVolume < 0) { m_AverageVolume = 0; } } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/IO/itkMegaCaptureImport.h0000644000175000017500000001174311667757442021034 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkMegaCaptureImport_h #define __itkMegaCaptureImport_h #include #include #include #include "itkLightProcessObject.h" #include #include "itkRegularExpressionSeriesFileNames.h" #include "GoFigureFileInfoMultiIndexContainerHelper.h" #include "QGoIOConfigure.h" // #include namespace itk { /**\class MegaCaptureImport \brief \bug If the filenames imported are of old megacapture format(v2) and that the text of the beginning of the filename (before the values to be stored in the database) contains more than 3 numerical groups, the files are considered as new megacapture...*/ class QGOIO_EXPORT MegaCaptureImport:public LightProcessObject { public: //typedef std::list IntListType; typedef std::vector< int > IntVectorType; typedef std::pair< IntVectorType, IntVectorType > PairIntVectorType; typedef std::vector< std::string > StringVectorType; /** Standard class typedefs. */ typedef MegaCaptureImport Self; typedef LightProcessObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro(MegaCaptureImport, LightProcessObject); /** Method for creation through the object factory. */ itkNewMacro(Self); void SetFileName(const std::string & iName); void SetTimeBased(const bool & iBool); void Glob(); void CreateOutput(); GoFigureFileInfoHelperMultiIndexContainer GetOutput(); void Update(); std::string GetHeaderFilename(); /** \brief return true if the filename is of new megacapture format, false if it is the old one*/ static bool IsNewMegaCapture(const std::string & iFilename); /** \brief return a modified cleaned filename */ static std::string CleanFileName(const std::string & iFilename); /** \brief return the list of the Index and the list of the length of all the numerical group present in the filename*/ static PairIntVectorType GetStartAndLengthOfNumericalGroupFilename( const std::string & iFilename); static bool AreTheseNumericalGroupNewMegaCapture( PairIntVectorType StartAndLengthNumericalGroup); protected: MegaCaptureImport(); ~MegaCaptureImport(); /** \brief Used for the database version1*/ void OldMegaCaptureFile(GoFigureFileInfoHelper & ioTempInfo, const std::vector< unsigned int > & iNumericalValues); /** \brief Used for the database version2*/ void NewMegaCaptureFile(GoFigureFileInfoHelper & ioTempInfo, const std::vector< unsigned int > & iNumericalValues); private: MegaCaptureImport (const Self &); //purposely not implemented void operator=(const Self &); //purposely not implemented PairIntVectorType m_StartAndLengthNumGroup; StringVectorType m_FileNameS; GoFigureFileInfoHelperMultiIndexContainer m_OutputFileList; std::string m_FileName; std::string m_fileNameModified; std::string m_HeaderFileName; int m_NbSignificantMegaCaptureNumGroup; }; } #endif GoFigure2-v0.9.0/Code/IO/CreateDataBaseHelper.cxx0000644000175000017500000014120211667757442021231 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "CreateDataBaseHelper.h" #include "QueryDataBaseHelper.h" #include "vtkSQLQuery.h" #include "vtkVariant.h" #include #include //------------------------------------------------------------------------------ bool IsDatabaseOfGoFigureType(vtkMySQLDatabase *DatabaseConnector) { return ( DoesTableExist(DatabaseConnector, "bookmark") && DoesTableExist(DatabaseConnector, "contour") && DoesTableExist(DatabaseConnector, "lineage") && DoesTableExist(DatabaseConnector, "mesh") && DoesTableExist(DatabaseConnector, "image") && DoesTableExist(DatabaseConnector, "track") ); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool DoesDatabaseExit(vtkMySQLDatabase *DataBaseConnector, std::string DBName) { vtkSQLQuery * query = DataBaseConnector->GetQueryInstance(); std::stringstream queryScript; queryScript << "SHOW DATABASES LIKE '"; queryScript << DBName; queryScript << "';"; query->SetQuery( queryScript.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "Does database already exist query failed." << query->GetLastErrorText() ); query->Delete(); return true; } if ( query->NextRow() ) { query->Delete(); return true; } query->Delete(); return false; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool CreateGoFigureDataBase( std::string ServerName, std::string login, std::string Password, std::string DBName) { std::pair< bool, vtkMySQLDatabase * > ConnectionServer = ConnectToServer( ServerName, login, Password); if ( !ConnectionServer.first ) { std::cout << "Can not connect to the server" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return false; } vtkMySQLDatabase *ServerConnector = ConnectionServer.second; if ( !DoesDatabaseExit(ServerConnector, DBName) ) { bool DatabaseCreated = CreateDataBase(ServerConnector, DBName); ServerConnector->Close(); ServerConnector->Delete(); if ( !DatabaseCreated ) { return false; } std::pair< bool, vtkMySQLDatabase * > Connection = ConnectToDatabase(ServerName, login, Password, DBName); if ( !Connection.first ) { return false; } vtkMySQLDatabase *DataBaseConnector = Connection.second; CreateTables(DataBaseConnector); //CreateForeignKeys(DataBaseConnector); DataBaseConnector->Close(); DataBaseConnector->Delete(); } else { ServerConnector->Close(); ServerConnector->Delete(); return true; } return true; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool CreateDataBase(vtkMySQLDatabase *DataBaseConnector, std::string DBName) { vtkSQLQuery * query = DataBaseConnector->GetQueryInstance(); std::stringstream insertQuery; insertQuery << "CREATE DATABASE " << DBName; query->SetQuery( insertQuery.str().c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "Create query failed" << query->GetLastErrorText() ); std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; query->Delete(); return false; } query->Delete(); return true; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void CreateTables(vtkMySQLDatabase *DataBaseConnector) { Query( DataBaseConnector, AuthorTable() ); Query( DataBaseConnector, BookmarkTable() ); Query( DataBaseConnector, CalculatedValueTable() ); Query( DataBaseConnector, CellTypeTable() ); Query( DataBaseConnector, ChannelTable() ); Query( DataBaseConnector, ColorTableScript() ); Query( DataBaseConnector, ContourTable() ); Query( DataBaseConnector, ContourValueTable() ); Query( DataBaseConnector, CoordinateTable() ); Query( DataBaseConnector, ImageTable() ); Query( DataBaseConnector, ImageValueTable() ); Query( DataBaseConnector, ImagingSessionTable() ); Query( DataBaseConnector, ImagingSessionValueTable() ); Query( DataBaseConnector, IntensityTable() ); Query( DataBaseConnector, LineageTable() ); Query( DataBaseConnector, LineageValueTable() ); Query( DataBaseConnector, MeshTable() ); Query( DataBaseConnector, MeshValueTable() ); Query( DataBaseConnector, MicroscopeTable() ); Query( DataBaseConnector, ProjectTable() ); Query( DataBaseConnector, SubCellularTypeTable() ); Query( DataBaseConnector, TrackFamilyTable() ); Query( DataBaseConnector, TrackTable() ); Query( DataBaseConnector, TrackValueTable() ); Query( DataBaseConnector, ValuePerVectorCoordTable() ); Query( DataBaseConnector, ValueTypeTable() ); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void CreateForeignKeys(vtkMySQLDatabase *DataBaseConnector) { Query( DataBaseConnector, ProjectFK() ); Query( DataBaseConnector, ImagingSessionFKMicroscopeName() ); Query( DataBaseConnector, ImagingSessionFKProjectName() ); // Query(DataBaseConnector,ImagingSessionFKCoordIDMin()); // Query(DataBaseConnector,ImagingSessionFKCoordIDMax()); Query( DataBaseConnector, TrackFamilyFKTrackIDDaughter1() ); Query( DataBaseConnector, TrackFamilyFKTrackIDDaughter2() ); Query( DataBaseConnector, TrackFamilyFKTrackIDMother() ); Query( DataBaseConnector, TrackFKColor() ); Query( DataBaseConnector, TrackFKLineage() ); Query( DataBaseConnector, TrackFKCoordIDMax() ); Query( DataBaseConnector, TrackFKCoordIDMin() ); Query( DataBaseConnector, TrackFKTrackFamily() ); Query( DataBaseConnector, MeshFKImagingSession() ); Query( DataBaseConnector, MeshFKTrackID() ); Query( DataBaseConnector, MeshFKColor() ); Query( DataBaseConnector, MeshFKCoordIDMin() ); Query( DataBaseConnector, MeshFKCoordIDMax() ); Query( DataBaseConnector, MeshFKSubCellType() ); Query( DataBaseConnector, MeshFKCellType() ); Query( DataBaseConnector, ContourFKImagingSession() ); Query( DataBaseConnector, ContourFKCoordIDMin() ); Query( DataBaseConnector, ContourFKCoordIDMax() ); Query( DataBaseConnector, ContourFKMesh() ); Query( DataBaseConnector, ChannelFKColor() ); Query( DataBaseConnector, ChannelFKImagingSession() ); Query( DataBaseConnector, ImageFKChannel() ); Query( DataBaseConnector, ImageFKCoordIDMin() ); Query( DataBaseConnector, ImageFKImagingSession() ); Query( DataBaseConnector, LineageFKImagingSession() ); Query( DataBaseConnector, LineageFKTrackRoot() ); Query( DataBaseConnector, LineageFKColor() ); Query( DataBaseConnector, LineageFKCoordIDMin() ); Query( DataBaseConnector, LineageFKCoordIDMax() ); Query( DataBaseConnector, BookmarkFKCoord() ); Query( DataBaseConnector, BookmarkFKImagingSession() ); Query( DataBaseConnector, IntensityFKChannel() ); Query( DataBaseConnector, IntensityFKMesh() ); Query( DataBaseConnector, ValueperVectorCoordFKCalculatedValue() ); Query( DataBaseConnector, CalculatedValueFKValueType() ); Query( DataBaseConnector, MeshValueFKCalculatedValue() ); Query( DataBaseConnector, MeshValueFKMesh() ); Query( DataBaseConnector, TrackValueFKCalculatedValue() ); Query( DataBaseConnector, TrackValueFKTrack() ); Query( DataBaseConnector, ImageValueFKCalculatedValue() ); Query( DataBaseConnector, ImageValueFKImage() ); Query( DataBaseConnector, ImagingSessionValueFKCalculatedValue() ); Query( DataBaseConnector, ImagingSessionValueFKImagingSession() ); Query( DataBaseConnector, ContourValueFKCalculatedValue() ); Query( DataBaseConnector, ContourValueFKContour() ); Query( DataBaseConnector, LineageValueFKCalculatedValue() ); Query( DataBaseConnector, LineageValueFKLineage() ); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void Query(vtkMySQLDatabase *DataBaseConnector, std::string queryScript) { vtkSQLQuery *query = DataBaseConnector->GetQueryInstance(); query->SetQuery( queryScript.c_str() ); if ( !query->Execute() ) { itkGenericExceptionMacro( << "Create query failed" << query->GetLastErrorText() ); std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; query->Delete(); return; } query->Delete(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string CellTypeTable() { return "CREATE TABLE IF NOT EXISTS `celltype`(\ `CellTypeID` INT NOT NULL AUTO_INCREMENT ,\ `Name` TEXT NOT NULL ,\ `Description` VARCHAR(1000) NULL ,\ PRIMARY KEY (`CellTypeID`)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string AuthorTable() { return "CREATE TABLE IF NOT EXISTS `author` (\ `AuthorID` INT NOT NULL AUTO_INCREMENT ,\ `LastName` VARCHAR(45) NOT NULL ,\ `FirstName` VARCHAR(45) NOT NULL ,\ `MiddleName` VARCHAR(45) NOT NULL DEFAULT '' ,\ UNIQUE INDEX UniqueAuthor (`LastName`,`FirstName`,`MiddleName`),\ PRIMARY KEY (`authorID`)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string SubCellularTypeTable() { return "CREATE TABLE IF NOT EXISTS `subcellulartype` (\ `SubCellularID` INT NOT NULL AUTO_INCREMENT ,\ `Name` VARCHAR(45) NOT NULL ,\ `Description` VARCHAR(1000) NULL ,\ PRIMARY KEY (`SubCellularID`)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string CoordinateTable() { return "CREATE TABLE IF NOT EXISTS `coordinate` (\ `CoordID` INT NOT NULL AUTO_INCREMENT ,\ `PCoord` TINYINT UNSIGNED NOT NULL DEFAULT 0,\ `RCoord` TINYINT UNSIGNED NOT NULL DEFAULT 0,\ `CCoord` TINYINT UNSIGNED NOT NULL DEFAULT 0,\ `XTileCoord` SMALLINT UNSIGNED NOT NULL DEFAULT 0,\ `YTileCoord` SMALLINT UNSIGNED NOT NULL DEFAULT 0,\ `ZTileCoord` SMALLINT UNSIGNED NOT NULL DEFAULT 0,\ `XCoord` FLOAT UNSIGNED NOT NULL DEFAULT 0,\ `YCoord` FLOAT UNSIGNED NOT NULL DEFAULT 0,\ `ZCoord` FLOAT UNSIGNED NOT NULL DEFAULT 0,\ `TCoord` FLOAT UNSIGNED NOT NULL DEFAULT 0,\ PRIMARY KEY (`CoordID`)\ );"; } //if needed: // UNIQUE INDEX UniqueCoordinate (`PCoord`,`RCoord`,`CCoord`,`XTileCoord`, // `YTileCoord`,`ZTileCoord`,`XCoord`,`YCoord`,`ZCoord`,`TCoord`), //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ColorTableScript() { return "CREATE TABLE IF NOT EXISTS `color` (\ `ColorID` INT NOT NULL AUTO_INCREMENT ,\ `Name` VARCHAR(45) NULL ,\ `Red` TINYINT UNSIGNED NOT NULL ,\ `Green` TINYINT UNSIGNED NOT NULL ,\ `Blue` TINYINT UNSIGNED NOT NULL ,\ `Alpha` TINYINT UNSIGNED NOT NULL ,\ `Description` VARCHAR(1000) NULL ,\ UNIQUE INDEX UniqueColor (`Red`,`Green`,`Blue`,`Alpha`,`Name`),\ PRIMARY KEY (`ColorID`)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MicroscopeTable() { return "CREATE TABLE IF NOT EXISTS `microscope` (\ `Name` VARCHAR(255) NOT NULL ,\ PRIMARY KEY (`Name`)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ProjectTable() { return "CREATE TABLE IF NOT EXISTS `project` (\ `Name` VARCHAR(255) NOT NULL ,\ `Description` VARCHAR(1000) NULL ,\ `AuthorID` INT NOT NULL ,\ `CreationDate` DATE NOT NULL ,\ `DatabaseVersion` VARCHAR(45) NOT NULL ,\ PRIMARY KEY (`Name`) ,\ INDEX `FK_Project_AuthorID` (`AuthorID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImagingSessionTable() { return "CREATE TABLE IF NOT EXISTS `imagingsession` (\ `ImagingSessionID` INT NOT NULL AUTO_INCREMENT ,\ `CoordIDMax` INT NOT NULL DEFAULT 0 ,\ `CoordIDMin` INT NOT NULL DEFAULT 0,\ `Name` VARCHAR(255) NOT NULL ,\ `Description` VARCHAR(1000) NULL ,\ `ImagesTimeInterval` FLOAT UNSIGNED NULL ,\ `RealPixelDepth` FLOAT UNSIGNED NULL ,\ `RealPixelHeight` FLOAT UNSIGNED NULL ,\ `RealPixelWidth` FLOAT UNSIGNED NULL ,\ `ProjectName` VARCHAR(255) NOT NULL ,\ `MicroscopeName` VARCHAR(255) NOT NULL ,\ `CreationDate` DATETIME NOT NULL ,\ `XImageSize` INT NOT NULL,\ `YImageSize` INT NOT NULL,\ `XTileOverlap` FLOAT UNSIGNED DEFAULT 0,\ `YTileOverlap` FLOAT UNSIGNED DEFAULT 0,\ `ZTileOverlap` FLOAT UNSIGNED DEFAULT 0,\ UNIQUE INDEX UniqueImagingSession (`MicroscopeName`,`CreationDate`),\ PRIMARY KEY (`ImagingSessionID`) ,\ INDEX `FK_ImagingSession_CoordIDMax` (`CoordIDMax` ASC) ,\ INDEX `FK_ImagingSession_CoordIDMin` (`CoordIDMin` ASC) ,\ INDEX `FK_ImagingSession_ProjectName` (`ProjectName` ASC) ,\ INDEX `FK_ImagingSession_MicroscopeName` (`MicroscopeName` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackFamilyTable() { return "CREATE TABLE IF NOT EXISTS `trackfamily` (\ `TrackFamilyID` INT NOT NULL AUTO_INCREMENT ,\ `TrackIDMother` INT NOT NULL ,\ `TrackIDDaughter1` INT NOT NULL ,\ `TrackIDDaughter2` INT NOT NULL ,\ PRIMARY KEY (`TrackFamilyID`) ,\ INDEX `FK_TrackFamily_TrackIDMother` (`TrackIDMother` ASC) ,\ INDEX `FK_TrackFamily_TrackIDDaughter1` (`TrackIDDaughter1` ASC) ,\ INDEX `FK_TrackFamily_TrackIDDaughter2` (`TrackIDDaughter2` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackTable() { return "CREATE TABLE IF NOT EXISTS `track` (\ `TrackID` INT NOT NULL AUTO_INCREMENT ,\ `LineageID` INT NULL ,\ `ColorID` INT NOT NULL DEFAULT '2',\ `CoordIDMax` INT NOT NULL ,\ `CoordIDMin` INT NOT NULL ,\ `TrackFamilyID` INT NULL ,\ `Points` LONGTEXT NULL ,\ `ImagingSessionID` INT NOT NULL ,\ PRIMARY KEY (`TrackID`) ,\ INDEX `FK_Track_ColorID` (`ColorID` ASC) ,\ INDEX `FK_Track_LineageID` (`LineageID` ASC) ,\ INDEX `FK_Track_CoordIDMax` (`CoordIDMax` ASC) ,\ INDEX `FK_Track_CoordIDMin` (`CoordIDMin` ASC) ,\ INDEX `FK_Track_TrackFamilyID` (`TrackFamilyID` ASC) ,\ INDEX `FK_Track_ImagingSessionID` (`ImagingSessionID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MeshTable() { return "CREATE TABLE IF NOT EXISTS `mesh` (\ `MeshID` INT NULL AUTO_INCREMENT ,\ `CellTypeID` INT NOT NULL DEFAULT '1',\ `SubCellularID` INT NOT NULL DEFAULT '1',\ `CoordIDMax` INT NOT NULL ,\ `CoordIDMin` INT NOT NULL ,\ `ColorID` INT NOT NULL DEFAULT '1',\ `TrackID` INT NULL ,\ `ImagingSessionID` INT NOT NULL ,\ `Points` LONGTEXT NULL ,\ PRIMARY KEY (`MeshID`) ,\ INDEX `FK_Mesh_CellTypeID` (`CellTypeID` ASC) ,\ INDEX `FK_Mesh_CoordIDMax` (`CoordIDMax` ASC) ,\ INDEX `FK_Mesh_CoordIDMin` (`CoordIDMin` ASC) ,\ INDEX `FK_Mesh_ColorID` (`ColorID` ASC) ,\ INDEX `FK_Mesh_TrackID` (`TrackID` ASC) ,\ INDEX `FK_Mesh_ImagingSessionID` (`ImagingSessionID` ASC) ,\ INDEX `FK_Mesh_SubCellularID` (`SubCellularID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ContourTable() { return "CREATE TABLE IF NOT EXISTS `contour` (\ `ContourID` INT NOT NULL AUTO_INCREMENT ,\ `MeshID` INT NULL ,\ `ImagingSessionID` INT NULL ,\ `ColorID` INT NULL ,\ `CoordIDMax` INT NOT NULL ,\ `CoordIDMin` INT NOT NULL ,\ `Points` LONGTEXT NOT NULL ,\ PRIMARY KEY (`ContourID`) ,\ INDEX `FK_Contour_MeshID` (`MeshID` ASC) ,\ INDEX `FK_Contour_CoordIDMax` (`CoordIDMax` ASC) ,\ INDEX `FK_Contour_CoordIDMin` (`CoordIDMin` ASC) ,\ INDEX `FK_Contour_ImagingSessionID` (`ImagingSessionID` ASC) \ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ChannelTable() { return "CREATE TABLE IF NOT EXISTS `channel` (\ `ChannelID` INT NOT NULL AUTO_INCREMENT ,\ `Name` VARCHAR(45) NULL ,\ `ImagingSessionID` INT NOT NULL,\ `ColorID` INT NOT NULL ,\ `ChannelNumber` INT NOT NULL ,\ `NumberOfBits` TINYINT UNSIGNED NOT NULL ,\ UNIQUE INDEX UniqueChannel (`ImagingSessionID`,`ChannelNumber`),\ PRIMARY KEY (`ChannelID`) ,\ INDEX `FK_Channel_ColorID` (`ColorID` ASC), \ INDEX `FK_Channel_ImagingSessionID`(`ImagingSessionID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImageTable() { return "CREATE TABLE IF NOT EXISTS `image` (\ `ImageID` INT NOT NULL AUTO_INCREMENT ,\ `ImagingSessionID` INT NOT NULL ,\ `CoordIDMin` INT NOT NULL ,\ `Filename` TEXT NOT NULL ,\ `ChannelID` INT NOT NULL ,\ PRIMARY KEY (`ImageID`) ,\ INDEX `FK_Image_ImagingSessionID` (`ImagingSessionID` ASC) ,\ INDEX `FK_Image_CoordIDMin` (`CoordIDMin` ASC) ,\ INDEX `FK_Image_ChannelID` (`ChannelID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string LineageTable() { return "CREATE TABLE IF NOT EXISTS `lineage` (\ `LineageID` INT NOT NULL AUTO_INCREMENT ,\ `CoordIDMax` INT NOT NULL ,\ `CoordIDMin` INT NOT NULL ,\ `ColorID` INT NOT NULL DEFAULT '3',\ `Points` LONGTEXT NOT NULL ,\ `TrackIDRoot` INT NOT NULL ,\ `ImagingSessionID` INT NOT NULL ,\ PRIMARY KEY (`LineageID`) ,\ INDEX `FK_Lineage_CoordIDMax` (`CoordIDMax` ASC) ,\ INDEX `FK_Lineage_CoordIDMin` (`CoordIDMin` ASC) ,\ INDEX `FK_Lineage_ColorID` (`ColorID` ASC) ,\ INDEX `FK_Lineage_TrackIDRoot` (`TrackIDRoot` ASC) ,\ INDEX `FK_Lineage_ImagingSessionID` (`ImagingSessionID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string BookmarkTable() { return "CREATE TABLE IF NOT EXISTS `bookmark` (\ `BookmarkID` INT NOT NULL AUTO_INCREMENT ,\ `ImagingSessionID` INT NOT NULL ,\ `CoordID` INT NOT NULL ,\ `Name` VARCHAR(45) NULL ,\ `Description` VARCHAR(1000) NULL ,\ `CreationDate` DATETIME NOT NULL,\ PRIMARY KEY (`BookmarkID`) ,\ INDEX `FK_Bookmark_ImagingSessionID` (`ImagingSessionID` ASC) ,\ INDEX `FK_Bookmark_CoordID` (`CoordID` ASC) \ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string IntensityTable() { return "CREATE TABLE IF NOT EXISTS `intensity` (\ `IntensityID` INT NOT NULL AUTO_INCREMENT ,\ `Value` INT NOT NULL ,\ `MeshID` INT NOT NULL ,\ `ChannelID` INT NOT NULL ,\ PRIMARY KEY (`IntensityID`) ,\ INDEX `FK_Intensity_MeshID` (`MeshID` ASC) ,\ INDEX `FK_Intensity_ChannelID` (`ChannelID` ASC) \ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ValueTypeTable() { return "CREATE TABLE IF NOT EXISTS `valuetype` (\ `ValueTypeID` INT NOT NULL AUTO_INCREMENT ,\ `Name` VARCHAR(45) NOT NULL ,\ `Description` VARCHAR(1000) NULL ,\ PRIMARY KEY (`ValueTypeID`) \ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string CalculatedValueTable() { return "CREATE TABLE IF NOT EXISTS `calculatedvalue` (\ `CalculatedValueID` INT NOT NULL AUTO_INCREMENT ,\ `ValueTypeID` INT NOT NULL ,\ PRIMARY KEY (`CalculatedValueID`) ,\ INDEX `FK_CalculatedValue_ValueTypeID` (`ValueTypeID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ValuePerVectorCoordTable() { return "CREATE TABLE IF NOT EXISTS `valuepervectorcoord` (\ `ValuePerVectorCoordID` INT NOT NULL AUTO_INCREMENT ,\ `Name` VARCHAR(45) NULL ,\ `VectorCoordNumber` INT NOT NULL ,\ `Value` DECIMAL(3) NOT NULL ,\ `CalculatedValueID` INT NOT NULL ,\ PRIMARY KEY (`ValuePerVectorCoordID`) ,\ INDEX `FK_ValuePerVectorCoord_CalculatedValueID` (`CalculatedValueID` ASC) \ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MeshValueTable() { return "CREATE TABLE IF NOT EXISTS `meshvalue` (\ `CalculatedValueID` INT NOT NULL ,\ `MeshID` INT NOT NULL ,\ PRIMARY KEY (`CalculatedValueID`, `MeshID`),\ INDEX `FK_MeshValue_MeshID` (`MeshID` ASC) ,\ INDEX `FK_MeshValue_CalculatedValueID` (`CalculatedValueID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackValueTable() { return "CREATE TABLE IF NOT EXISTS `trackvalue` (\ `TrackID` INT NOT NULL ,\ `CalculatedValueID` INT NOT NULL ,\ PRIMARY KEY (`TrackID`, `CalculatedValueID`) ,\ INDEX `FK_TrackValue_TrackID` (`TrackID` ASC) ,\ INDEX `CalculatedValueID` (`CalculatedValueID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImageValueTable() { return "CREATE TABLE IF NOT EXISTS `imagevalue` (\ `ImageID` INT NOT NULL ,\ `CalculatedValueID` INT NOT NULL ,\ PRIMARY KEY (`ImageID`, `CalculatedValueID`),\ INDEX `FK_ImageValue_ImageID` (`ImageID` ASC) ,\ INDEX `FK_ImageValue_CalculatedValueID` (`CalculatedValueID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImagingSessionValueTable() { return "CREATE TABLE IF NOT EXISTS `imagingsessionvalue` (\ `ImagingSessionID` INT NOT NULL ,\ `CalculatedValueID` INT NOT NULL ,\ PRIMARY KEY (`ImagingSessionID`, `CalculatedValueID`) ,\ INDEX `ImagingSessionID` (`ImagingSessionID` ASC) ,\ INDEX `CalculatedValueID` (`CalculatedValueID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ContourValueTable() { return "CREATE TABLE IF NOT EXISTS `contourvalue` (\ `ContourID` INT NOT NULL ,\ `CalculatedValueID` INT NOT NULL ,\ PRIMARY KEY (`ContourID`, `CalculatedValueID`),\ INDEX `FK_ContourValue_ContourID` (`ContourID` ASC) ,\ INDEX `FK_ContourValue_CalculatedValueID` (`CalculatedValueID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string LineageValueTable() { return "CREATE TABLE IF NOT EXISTS `lineagevalue` (\ `LineageID` INT NOT NULL ,\ `CalculatedValueID` INT NOT NULL ,\ PRIMARY KEY (`LineageID`, `CalculatedValueID`),\ INDEX `FK_LineageValue_LineageID` (`LineageID` ASC) ,\ INDEX `FK_LineageValue_CalculatedValueID` (`CalculatedValueID` ASC)\ );"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ProjectFK() { return "ALTER TABLE `project` ADD\ CONSTRAINT `FK_Project_AuthorID`\ FOREIGN KEY (`AuthorID`)\ REFERENCES `author`(`AuthorID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImagingSessionFKCoordIDMax() { return "ALTER TABLE `imagingsession` ADD\ CONSTRAINT `FK_ImagingSession_CoordIDMax`\ FOREIGN KEY (`CoordIDMax`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImagingSessionFKCoordIDMin() { return "ALTER TABLE `imagingsession` ADD\ CONSTRAINT `FK_ImagingSession_CoordIDMin`\ FOREIGN KEY (`CoordIDMin`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImagingSessionFKProjectName() { return "ALTER TABLE `imagingsession` ADD\ CONSTRAINT `FK_ImagingSession_ProjectName`\ FOREIGN KEY (`ProjectName`)\ REFERENCES `project`(`Name`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImagingSessionFKMicroscopeName() { return "ALTER TABLE `imagingsession` ADD\ CONSTRAINT `FK_ImagingSession_MicroscopeName`\ FOREIGN KEY (`MicroscopeName`)\ REFERENCES `microscope`(`Name`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackFamilyFKTrackIDMother() { return "ALTER TABLE `trackfamily` ADD\ CONSTRAINT `FK_TrackFamily_TrackIDMother`\ FOREIGN KEY (`TrackIDMother`)\ REFERENCES `track`(`TrackID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackFamilyFKTrackIDDaughter1() { return "ALTER TABLE `trackfamily` ADD\ CONSTRAINT `FK_TrackFamily_TrackIDDaughter1`\ FOREIGN KEY (`TrackIDDaughter1`)\ REFERENCES `track`(`TrackID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackFamilyFKTrackIDDaughter2() { return "ALTER TABLE `trackfamily` ADD\ CONSTRAINT `FK_TrackFamily_TrackIDDaughter2`\ FOREIGN KEY (`TrackIDDaughter2`)\ REFERENCES `track`(`TrackID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackFKColor() { return "ALTER TABLE `track` ADD\ CONSTRAINT `FK_Track_ColorID`\ FOREIGN KEY (`ColorID`)\ REFERENCES `color`(`ColorID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackFKLineage() { return "ALTER TABLE `track` ADD\ CONSTRAINT `FK_Track_LineageID`\ FOREIGN KEY (`LineageID`)\ REFERENCES `lineage`(`LineageID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackFKCoordIDMax() { return "ALTER TABLE `track` ADD\ CONSTRAINT `FK_Track_CoordIDMax`\ FOREIGN KEY (`CoordIDMax`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackFKCoordIDMin() { return "ALTER TABLE `track` ADD\ CONSTRAINT `FK_Track_CoordIDMin`\ FOREIGN KEY (`CoordIDMin`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackFKTrackFamily() { return "ALTER TABLE `track` ADD\ CONSTRAINT `FK_Track_TrackFamilyID`\ FOREIGN KEY (`TrackFamilyID`)\ REFERENCES `trackfamily`(`TrackFamilyID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackFKImagingSession() { return "ALTER TABLE `track` ADD\ CONSTRAINT `FK_Track_ImagingSessionID`\ FOREIGN KEY (`ImagingSessionID`)\ REFERENCES `imagingsession`(`ImagingSessionID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MeshFKCellType() { return "ALTER TABLE `mesh` ADD\ CONSTRAINT `FK_Mesh_CellTypeID`\ FOREIGN KEY (`CellTypeID`)\ REFERENCES `celltype`(`CellTypeID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MeshFKSubCellType() { return "ALTER TABLE `mesh` ADD\ CONSTRAINT `FK_Mesh_SubCellularID`\ FOREIGN KEY (`SubCellularID`)\ REFERENCES `subcellulartype`(`SubCellularID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MeshFKCoordIDMax() { return "ALTER TABLE `mesh` ADD\ CONSTRAINT `FK_Mesh_CoordIDMax`\ FOREIGN KEY (`CoordIDMax`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MeshFKCoordIDMin() { return "ALTER TABLE `mesh` ADD\ CONSTRAINT `FK_Mesh_CoordIDMin`\ FOREIGN KEY (`CoordIDMin`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MeshFKColor() { return "ALTER TABLE `mesh` ADD\ CONSTRAINT `FK_Mesh_ColorID`\ FOREIGN KEY (`ColorID`)\ REFERENCES `color`(`ColorID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MeshFKTrackID() { return "ALTER TABLE `mesh` ADD\ CONSTRAINT `FK_Mesh_TrackID`\ FOREIGN KEY (`TrackID`)\ REFERENCES `track`(`TrackID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MeshFKImagingSession() { return "ALTER TABLE `mesh` ADD\ CONSTRAINT `FK_Mesh_ImagingSessionID`\ FOREIGN KEY (`ImagingSessionID`)\ REFERENCES `imagingSession`(`ImagingSessionID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ContourFKMesh() { return "ALTER TABLE `contour` ADD\ CONSTRAINT `FK_Contour_MeshID`\ FOREIGN KEY (`MeshID`)\ REFERENCES `mesh`(`MeshID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ContourFKCoordIDMax() { return "ALTER TABLE `contour` ADD\ CONSTRAINT `FK_Contour_CoordIDMax`\ FOREIGN KEY (`CoordIDMax`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ContourFKCoordIDMin() { return "ALTER TABLE `contour` ADD\ CONSTRAINT `FK_Contour_CoordIDMin`\ FOREIGN KEY (`CoordIDMin`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ContourFKImagingSession() { return "ALTER TABLE `contour` ADD\ CONSTRAINT `FK_Contour_ImagingSessionID`\ FOREIGN KEY (`ImagingSessionID`)\ REFERENCES `imagingsession`(`ImagingSessionID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ChannelFKColor() { return "ALTER TABLE `channel` ADD\ CONSTRAINT `FK_Channel_ColorID`\ FOREIGN KEY (`ColorID`)\ REFERENCES `color`(`ColorID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ChannelFKImagingSession() { return "ALTER TABLE `channel` ADD\ CONSTRAINT `FK_Channel_ImagingSessionID`\ FOREIGN KEY (`ImagingSessionID`)\ REFERENCES `imagingsession`(`ImagingSessionID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImageFKImagingSession() { return "ALTER TABLE `image` ADD\ CONSTRAINT `FK_Image_ImagingSessionID`\ FOREIGN KEY (`ImagingSessionID`)\ REFERENCES `imagingsession`(`ImagingSessionID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImageFKCoordIDMin() { return "ALTER TABLE `image` ADD\ CONSTRAINT `FK_Image_CoordIDMin`\ FOREIGN KEY (`CoordIDMin`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImageFKChannel() { return "ALTER TABLE `image` ADD\ CONSTRAINT `FK_Image_ChannelID`\ FOREIGN KEY (`ChannelID`)\ REFERENCES `channel`(`ChannelID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string LineageFKCoordIDMax() { return "ALTER TABLE `lineage` ADD\ CONSTRAINT `FK_Lineage_CoordIDMax`\ FOREIGN KEY (`CoordIDMax`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string LineageFKCoordIDMin() { return "ALTER TABLE `lineage` ADD\ CONSTRAINT `FK_Lineage_CoordIDMin`\ FOREIGN KEY (`CoordIDMin`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string LineageFKColor() { return "ALTER TABLE `lineage` ADD\ CONSTRAINT `FK_Lineage_ColorID`\ FOREIGN KEY (`ColorID`)\ REFERENCES `color`(`ColorID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string LineageFKTrackRoot() { return "ALTER TABLE `lineage` ADD\ CONSTRAINT `FK_Lineage_TrackIDRoot`\ FOREIGN KEY (`TrackIDRoot`)\ REFERENCES `track`(`TrackID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string LineageFKImagingSession() { return "ALTER TABLE `lineage` ADD\ CONSTRAINT `FK_Lineage_ImagingSessionID`\ FOREIGN KEY (`ImagingSessionID`)\ REFERENCES `imagingsession`(`ImagingSessionID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string BookmarkFKImagingSession() { return "ALTER TABLE `bookmark` ADD\ CONSTRAINT `FK_Bookmark_ImagingSessionID`\ FOREIGN KEY (`ImagingSessionID`)\ REFERENCES `imagingsession`(`ImagingSessionID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string BookmarkFKCoord() { return "ALTER TABLE `bookmark` ADD\ CONSTRAINT `FK_Bookmark_CoordID`\ FOREIGN KEY (`CoordID`)\ REFERENCES `coordinate`(`CoordID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string IntensityFKMesh() { return "ALTER TABLE `intensity` ADD\ CONSTRAINT `FK_Intensity_MeshID`\ FOREIGN KEY (`MeshID`)\ REFERENCES `mesh`(`MeshID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string IntensityFKChannel() { return "ALTER TABLE `intensity` ADD\ CONSTRAINT `FK_Intensity_ChannelID`\ FOREIGN KEY (`ChannelID`)\ REFERENCES `channel`(`ChannelID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string CalculatedValueFKValueType() { return "ALTER TABLE `calculatedvalue` ADD\ CONSTRAINT `FK_CalculatedValue_ValueTypeID`\ FOREIGN KEY (`ValueTypeID`)\ REFERENCES `valuetype`(`ValueTypeID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ValueperVectorCoordFKCalculatedValue() { return "ALTER TABLE `valuepervectorcoord` ADD\ CONSTRAINT `FK_ValuePerVectorCoord_CalculatedValueID`\ FOREIGN KEY (`CalculatedValueID`)\ REFERENCES `calculatedvalue`(`CalculatedValueID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MeshValueFKMesh() { return "ALTER TABLE `meshvalue` ADD\ CONSTRAINT `FK_MeshValue_MeshID`\ FOREIGN KEY (`MeshID`)\ REFERENCES `mesh`(`MeshID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string MeshValueFKCalculatedValue() { return "ALTER TABLE `meshvalue` ADD\ CONSTRAINT `FK_MeshValue_CalculatedValueID`\ FOREIGN KEY (`CalculatedValueID`)\ REFERENCES `calculatedvalue`(`CalculatedValueID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackValueFKTrack() { return "ALTER TABLE `trackvalue` ADD\ CONSTRAINT `FK_TrackValue_TrackID`\ FOREIGN KEY (`TrackID`)\ REFERENCES `track`(`TrackID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string TrackValueFKCalculatedValue() { return "ALTER TABLE `trackvalue` ADD\ CONSTRAINT `FK_TrackValue_CalculatedValueID`\ FOREIGN KEY (`CalculatedValueID`)\ REFERENCES `calculatedvalue`(`CalculatedValueID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImageValueFKImage() { return "ALTER TABLE `imagevalue` ADD\ CONSTRAINT `FK_ImageValue_ImageID`\ FOREIGN KEY (`ImageID`)\ REFERENCES `image`(`ImageID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImageValueFKCalculatedValue() { return "ALTER TABLE `imagevalue` ADD\ CONSTRAINT `FK_ImageValue_CalculatedValueID`\ FOREIGN KEY (`CalculatedValueID`)\ REFERENCES `calculatedvalue`(`CalculatedValueID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImagingSessionValueFKImagingSession() { return "ALTER TABLE `imagingsessionvalue` ADD\ CONSTRAINT `FK_ImagingSessionValue_ImagingSessionID`\ FOREIGN KEY (`ImagingSessionID`)\ REFERENCES `imagingsession`(`ImagingSessionID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ImagingSessionValueFKCalculatedValue() { return "ALTER TABLE `imagingsessionvalue` ADD\ CONSTRAINT `FK_ImagingSessionValue_CalculatedValueID`\ FOREIGN KEY (`CalculatedValueID`)\ REFERENCES `calculatedvalue`(`CalculatedValueID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ContourValueFKContour() { return "ALTER TABLE `contourvalue` ADD\ CONSTRAINT `FK_ContourValue_ContourID`\ FOREIGN KEY (`ContourID`)\ REFERENCES `contour`(`ContourID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string ContourValueFKCalculatedValue() { return "ALTER TABLE `contourvalue` ADD\ CONSTRAINT `FK_ContourValue_CalculatedValueID`\ FOREIGN KEY (`CalculatedValueID`)\ REFERENCES `calculatedvalue`(`CalculatedValueID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string LineageValueFKLineage() { return "ALTER TABLE `lineagevalue` ADD\ CONSTRAINT `FK_LineageValue_LineageID`\ FOREIGN KEY (`LineageID`)\ REFERENCES `lineage`(`LineageID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::string LineageValueFKCalculatedValue() { return "ALTER TABLE `lineagevalue` ADD\ CONSTRAINT `FK_LineageValue_CalculatedValueID`\ FOREIGN KEY (`CalculatedValueID`)\ REFERENCES `calculatedvalue`(`CalculatedValueID`)\ ON DELETE NO ACTION\ ON UPDATE NO ACTION\ ;"; }GoFigure2-v0.9.0/Code/IO/GoDBTWContainerForContourMesh.cxx0000644000175000017500000001401011667757442023024 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBTWContainerForContourMesh.h" GoDBTWContainerForContourMesh::GoDBTWContainerForContourMesh( std::string iTraceName, std::string iCollectionName, int iImgSessionID) : GoDBTableWidgetContainer(iTraceName, iCollectionName, iImgSessionID) { m_ColumnsInfos = GetColumnsInfoForTraceTable(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBTWContainerForContourMesh::~GoDBTWContainerForContourMesh() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForContourMesh::SetCommonInfoForTwoTracesTable() { GoDBTraceInfoForTableWidget temp; std::pair< GoDBTraceInfoForTableWidget, std::vector< std::string > > PairTemp; //Get the info for the Time Point: temp.InfoName = "TimePoint"; temp.ColumnNameDatabase = "TCoord"; temp.ColumnNameTableWidget = "TimePoint"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); this->SetInfoForColumnIsVisible(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForContourMesh::FillRowContainerWithDBValues( vtkMySQLDatabase *iDatabaseConnector, std::string iRestrictionName, std::string iRestrictionValue) { GoDBTableWidgetContainer::FillRowContainerWithDBValues(iDatabaseConnector, iRestrictionName, iRestrictionValue); this->FillColumnShowHide(iDatabaseConnector); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForContourMesh::FillColumnShowHide(vtkMySQLDatabase *iDatabaseConnector) { //get the current timepoint which is also the min timepoint for the // imagingsession: //std::vector SelectedFields; //SelectedFields.push_back("TCoord"); //std::string JoinCondition = "imagingsession.CoordIDMin = // coordinate.CoordID"; //std::vector Conditions(2); //Conditions[0]="imagingsessionID"; //Conditions[1] = ConvertToString(this->m_ImgSessionID); //std::list VectorMinTimePoint = // GetAllSelectedValuesFromTwoTables( // iDatabaseConnector, "imagingsession", "coordinate",SelectedFields, // JoinCondition,Conditions); FieldWithValue JoinCondition = { "CoordIDMin", "CoordID", "=" }; std::vector< FieldWithValue > Condition (1); FieldWithValue ImgSession = { "ImagingsessionID", ConvertToString< int >(this->m_ImgSessionID), "=" }; Condition[0] = ImgSession; std::list< unsigned int > VectorMinTimePoint = GetAllSelectedValuesFromTwoTables( iDatabaseConnector, "imagingsession", "coordinate", "TCoord", JoinCondition, Condition); std::string MinTimePoint = ConvertToString< unsigned int >( VectorMinTimePoint.front() ); std::vector< std::vector< std::string > > Values; std::vector< std::string > ShowHideValue; int IndexTimePoint = this->GetIndexInsideRowContainer("TimePoint"); std::vector< std::string >::iterator iter = this->m_RowContainer.at(IndexTimePoint).second.begin(); while ( iter != this->m_RowContainer.at(IndexTimePoint).second.end() ) { if ( *iter == MinTimePoint ) { ShowHideValue.push_back("true"); } else { ShowHideValue.push_back("false"); } Values.push_back(ShowHideValue); ShowHideValue.clear(); ++iter; } std::vector< std::string > Fields; Fields.push_back("Show"); if ( !Values.empty() ) { this->FillRowContainer(Values, Fields, "ColumnNameTableWidget"); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int GoDBTWContainerForContourMesh::GetIndexShowColumn() { return this->GetIndexInsideRowContainer("Show"); } GoFigure2-v0.9.0/Code/IO/vtkPolyDataMySQLTrackReader.cxx0000644000175000017500000001304511667757442022544 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkPolyDataMySQLTrackReader.h" #include "vtkObjectFactory.h" #include "vtkPolyLine.h" #include "vtkCellArray.h" #include "vtkPolyData.h" #include "vtkIntArray.h" #include "vtkDoubleArray.h" #include "vtkPointData.h" #include vtkCxxRevisionMacro(vtkPolyDataMySQLTrackReader, "$Revision$"); vtkStandardNewMacro(vtkPolyDataMySQLTrackReader); //-------------------------------------------------------------------------- vtkPolyDataMySQLTrackReader::vtkPolyDataMySQLTrackReader() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyDataMySQLTrackReader:: ~vtkPolyDataMySQLTrackReader() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer< vtkPolyData > vtkPolyDataMySQLTrackReader::GetPolyData(const std::string & iString) { std::stringstream str(iString); // Might not be useful vtkIdType N; str >> N; if ( N != 0 ) { std::map< unsigned int, double * > orderedPoints = GetMap(iString); vtkSmartPointer< vtkIntArray > temporalArray = vtkSmartPointer< vtkIntArray >::New(); temporalArray->SetNumberOfComponents(1); temporalArray->SetName("TemporalInformation"); // read map and fill points vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New(); std::map< unsigned int, double * >::iterator it = orderedPoints.begin(); while ( it != orderedPoints.end() ) { temporalArray->InsertNextValue(it->first); points->InsertNextPoint(it->second); ++it; } // Clean the map it = orderedPoints.begin(); while ( it != orderedPoints.end() ) { delete[] it->second; ++it; } orderedPoints.clear(); // Create a line from points vtkSmartPointer< vtkPolyLine > polyLine = vtkSmartPointer< vtkPolyLine >::New(); polyLine->GetPointIds()->SetNumberOfIds( points->GetNumberOfPoints() ); for ( vtkIdType i = 0; i < points->GetNumberOfPoints(); i++ ) { polyLine->GetPointIds()->SetId(i, i); } //Create a cell array to store the lines in and add the lines to it vtkSmartPointer< vtkCellArray > cells = vtkSmartPointer< vtkCellArray >::New(); cells->InsertNextCell(polyLine); //Create a polydata to store everything in vtkSmartPointer< vtkPolyData > polyData = vtkSmartPointer< vtkPolyData >::New(); //add the points to the dataset polyData->SetPoints(points); //add the lines to the dataset polyData->SetLines(cells); //add the temporal information polyData->GetPointData()->AddArray(temporalArray); vtkSmartPointer< vtkDoubleArray > speedArray = vtkSmartPointer< vtkDoubleArray >::New(); speedArray->SetNumberOfComponents(1); speedArray->SetName("SpeedInformation"); polyData->GetPointData()->AddArray(speedArray); return polyData; } return NULL; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::map< unsigned int, double * > vtkPolyDataMySQLTrackReader::GetMap(const std::string & iString) { std::stringstream str(iString); std::map< unsigned int, double * > orderedPoints; // Might not be useful vtkIdType N; str >> N; if ( N != 0 ) { double * pt = NULL; unsigned int time = 0; // fill a map so the points will be ordered automatically for ( vtkIdType i = 0; i < N; i++ ) { pt = new double[3]; str >> pt[0] >> pt[1] >> pt[2]; str >> time; orderedPoints.insert( std::pair< unsigned int, double * >(time, pt) ); } } return orderedPoints; } GoFigure2-v0.9.0/Code/IO/GoDBTWContainerForTrack.cxx0000644000175000017500000001704111667757442021631 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "GoDBTWContainerForTrack.h" GoDBTWContainerForTrack::GoDBTWContainerForTrack(int iImgSessionID) : GoDBTWContainerForTrackLineage("track", "lineage", iImgSessionID), m_TrackAttributes(NULL) { this->SetSpecificInfoForTrackTable(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBTWContainerForTrack::~GoDBTWContainerForTrack() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForTrack::SetSpecificInfoForTrackTable() { GoDBTraceInfoForTableWidget temp; std::pair< GoDBTraceInfoForTableWidget, std::vector< std::string > > PairTemp; //Get the info for the Deplacement: temp.InfoName = "Deplacement"; temp.ColumnNameTableWidget = "Deplacement"; temp.ToolTip = "micron"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Distance: temp.InfoName = "Distance"; temp.ColumnNameTableWidget = "Distance"; temp.ToolTip = "micron"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for theta: temp.InfoName = "Theta"; temp.ColumnNameTableWidget = "Theta"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for phi: temp.InfoName = "Phi"; temp.ColumnNameTableWidget = "Phi"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for AvgSpeed: temp.InfoName = "AvgSpeed"; temp.ColumnNameTableWidget = "AvgSpeed"; temp.ToolTip = "micron/s"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for MaxSpeed: temp.InfoName = "MaxSpeed"; temp.ColumnNameTableWidget = "MaxSpeed"; temp.ToolTip = "micron/s"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for MaxSpeed: temp.InfoName = "AvgVolume"; temp.ColumnNameTableWidget = "AvgVolume"; temp.ToolTip = "micron cube"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); //Get the info for Number of meshes: temp.InfoName = "NumberOfMeshes"; temp.ColumnNameTableWidget = "NumberOfMeshes"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); //Get the info for Tmax - Tmin: temp.InfoName = "Tmax - Tmin"; temp.ColumnNameTableWidget = "Tmax - Tmin"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForTrack::SetTrackAttributes(GoFigureTrackAttributes *iTrackAttributes) { this->m_TrackAttributes = iTrackAttributes; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBTableWidgetContainer::TWContainerType GoDBTWContainerForTrack::GetContainerForOneSpecificTrace( vtkMySQLDatabase *iDatabaseConnector, int iTraceID) { GoDBTableWidgetContainer::GetContainerForOneSpecificTrace(iDatabaseConnector, iTraceID); this->FillRowContainerForTrackComputedValues(); return this->m_RowContainer; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForTrack::FillRowContainerForTrackComputedValues() { std::vector< std::string > VectorNames; std::vector< std::vector< std::string > > VectorValues; this->GetValuesAndNamesForTrackComputedValues(this->m_TrackAttributes, VectorValues, VectorNames); this->FillRowContainer(VectorValues, VectorNames, "ColumnNameTableWidget"); this->m_TrackAttributes = 0; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForTrack::GetValuesAndNamesForTrackComputedValues( GoFigureTrackAttributes *iTrackAttributes, std::vector< std::vector< std::string > > & ioValues, std::vector< std::string > & ioNames) { if ( iTrackAttributes != 0 ) { std::vector< std::string > temp; ioNames.push_back("Deplacement"); temp.push_back( ConvertToString< double >(iTrackAttributes->total_length) ); ioNames.push_back("Distance"); temp.push_back( ConvertToString< double >(iTrackAttributes->distance) ); ioNames.push_back("Theta"); temp.push_back( ConvertToString< double >(iTrackAttributes->theta) ); ioNames.push_back("Phi"); temp.push_back( ConvertToString< double >(iTrackAttributes->phi) ); ioNames.push_back("AvgSpeed"); temp.push_back( ConvertToString< double >(iTrackAttributes->avg_speed) ); ioNames.push_back("MaxSpeed"); temp.push_back( ConvertToString< double >(iTrackAttributes->max_speed) ); ioNames.push_back("AvgVolume"); temp.push_back( ConvertToString< double >(iTrackAttributes->avg_volume) ); ioNames.push_back("NumberOfMeshes"); temp.push_back( ConvertToString< unsigned int >(iTrackAttributes->number_meshes) ); ioNames.push_back("Tmax - Tmin"); temp.push_back( ConvertToString< unsigned int >(iTrackAttributes->temporal_extent) ); ioValues.push_back(temp); } } GoFigure2-v0.9.0/Code/IO/GoDBTraceInfoForTableWidget.h0000644000175000017500000000721611667757442022065 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBTraceInfoForTableWidget_h #define __GoDBTraceInfoForTableWidget_h #include /**\brief structure to pass the column information between the Table Widget and the Database*/ struct GoDBTraceInfoForTableWidget { std::string InfoName; std::string ColumnNameTableWidget; //Name of the column in the Table Widget std::string ToolTip; //ToolTip to be displayed on the columnName in the Table Widget std::string ColumnNameDatabase; //Name of the field in the database std::string TableNameDatabase; //name of the table in the database bool SameFieldForDifferentValues; /*set to true if the same table.field is called several times and corresponds to different values: expl coordinate.TCoord for both CoordIDMin and CoordIDMax*/ std::string TableKeyDatabase; //Name of the primary key of the table // "TableNameDatabase" std::string TableForeignKeyDatabase; //Name of the foreign key corresponding // in the trace table std::string AccessFromTraceTableThroughWhichTable; std::string TypeName; //double, string... GoDBTraceInfoForTableWidget() { InfoName = "None"; ColumnNameTableWidget = "None"; ToolTip = "None"; ColumnNameDatabase = "None"; TableNameDatabase = "None"; TableKeyDatabase = "None"; TableForeignKeyDatabase = "None"; SameFieldForDifferentValues = false; AccessFromTraceTableThroughWhichTable = "None"; TypeName = "double"; } void Clear() { InfoName = "None"; ColumnNameTableWidget = "None"; ToolTip = "None"; ColumnNameDatabase = "None"; TableNameDatabase = "None"; TableKeyDatabase = "None"; TableForeignKeyDatabase = "None"; SameFieldForDifferentValues = false; AccessFromTraceTableThroughWhichTable = "None"; } }; #endif GoFigure2-v0.9.0/Code/IO/vtkPolyDataMySQLMeshWriter.h0000644000175000017500000000554311667757442022077 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkPolyDataMySQLMeshWriter_h #define __vtkPolyDataMySQLMeshWriter_h #include #include #include "vtkPolyData.h" #include "vtkMath.h" #include "vtkIdList.h" #include "QGoIOConfigure.h" /** \defgroup MySQLWriter MySQLWriter \defgroup Mesh Mesh \defgroup Trace Trace */ /** \class vtkPolyDataMySQLMeshWriter \brief Reads a string and convert it into a mesh polydata \ingroup MySQLWriter Mesh Trace */ class QGOIO_EXPORT vtkPolyDataMySQLMeshWriter:public vtkObject { public: /* * \brief Public constructor */ static vtkPolyDataMySQLMeshWriter * New(); vtkTypeRevisionMacro(vtkPolyDataMySQLMeshWriter, vtkObject); /* * \brief Generate a string from a mesh plolydata * \param[in] iPolyData Polydata to generate the string * \return string containing the mesh polydata information */ std::string GetMySQLText(vtkPolyData *iPolyData); protected: vtkPolyDataMySQLMeshWriter(); ~vtkPolyDataMySQLMeshWriter(); private: vtkPolyDataMySQLMeshWriter(const vtkPolyDataMySQLMeshWriter &); void operator=(const vtkPolyDataMySQLMeshWriter &); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBTWContainerForLineage.cxx0000644000175000017500000001452011667757442022130 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBTWContainerForLineage.h" GoDBTWContainerForLineage::GoDBTWContainerForLineage(int iImgSessionID) : GoDBTWContainerForTrackLineage("lineage", "None", iImgSessionID) { this->SetSpecificInfoForLineageTable(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBTWContainerForLineage::~GoDBTWContainerForLineage() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForLineage::SetSpecificInfoForLineageTable() { GoDBTraceInfoForTableWidget temp; std::pair< GoDBTraceInfoForTableWidget, std::vector< std::string > > PairTemp; //Get the info for the TrackIDRoot: temp.InfoName = "TrackIDRoot"; temp.ColumnNameDatabase = "TrackIDRoot"; temp.TableNameDatabase = "lineage"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Max Depth: temp.InfoName = "MaxDepth"; temp.ColumnNameTableWidget = "MaxDepth"; temp.ToolTip = "TBD"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Min Depth: temp.InfoName = "MinDepth"; temp.ColumnNameTableWidget = "MinDepth"; temp.ToolTip = "TBD"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the number of divisions: temp.InfoName = "NbDivisions"; temp.ColumnNameTableWidget = "NbDivisions"; temp.ToolTip = "Number of divisions"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the number of leaves: temp.InfoName = "NbLeaves"; temp.ColumnNameTableWidget = "NbLeaves"; temp.ToolTip = "Number of leaves"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForLineage::SetLineageAttributes(GoFigureLineageAttributes iLineageAttributes) { this->m_LineageAttributes = iLineageAttributes; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForLineage::FillRowContainerForLineageComputedValues() { std::vector< std::string > VectorNames; std::vector< std::vector< std::string > > VectorValues; this->GetValuesAndNamesForLineageComputedValues(this->m_LineageAttributes, VectorValues, VectorNames); this->FillRowContainer(VectorValues, VectorNames, "ColumnNameTableWidget"); this->m_LineageAttributes.clear(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBTableWidgetContainer::TWContainerType GoDBTWContainerForLineage::GetContainerForOneSpecificTrace( vtkMySQLDatabase *iDatabaseConnector, int iTraceID) { GoDBTableWidgetContainer::GetContainerForOneSpecificTrace(iDatabaseConnector, iTraceID); this->FillRowContainerForLineageComputedValues(); return this->m_RowContainer; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForLineage::GetValuesAndNamesForLineageComputedValues( GoFigureLineageAttributes iLineageAttributes, std::vector< std::vector< std::string > > & ioValues, std::vector< std::string > & ioNames) { std::vector< std::string > temp; ioNames.push_back("MaxDepth"); temp.push_back( ConvertToString< unsigned int >(iLineageAttributes.MaxDepth) ); ioNames.push_back("MinDepth"); temp.push_back( ConvertToString< unsigned int >(iLineageAttributes.MinDepth) ); ioNames.push_back("NbDivisions"); temp.push_back( ConvertToString< unsigned int >(iLineageAttributes.NumberOfDivisions) ); ioNames.push_back("NbLeaves"); temp.push_back( ConvertToString< unsigned int >(iLineageAttributes.NumberOfLeaves) ); ioValues.push_back(temp); } //-------------------------------------------------------------------------- //--------------------------------------------------------------------------GoFigure2-v0.9.0/Code/IO/GoDBTWContainerForMesh.h0000755000175000017500000001541411667757442021113 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoDBTWContainerForMesh_h #define __GoDBTWContainerForMesh_h #include "GoDBTWContainerForContourMesh.h" #include "QGoIOConfigure.h" #include "GoFigureMeshAttributes.h" /** \class GoDBTWContainerForMesh \brief This class describes the specificities of the GoDBTWContainerForContourMesh for mesh \ingroup DB */ class QGOIO_EXPORT GoDBTWContainerForMesh:public GoDBTWContainerForContourMesh { public: GoDBTWContainerForMesh(int iImgSessionID); ~GoDBTWContainerForMesh(); //from mother class virtual TWContainerType GetContainerLoadedWithAllFromDB( vtkMySQLDatabase *iDatabaseConnector, std::list iListTPs = std::list()); //from mother class virtual TWContainerType GetContainerForOneSpecificTrace( vtkMySQLDatabase *iDatabaseConnector, int iTraceID); /** \brief set m_MeshAttributes to iMeshAttributes, needs to be called before displaying the volume, area values \param[in] iMeshAttributes attributes for the mesh computed from visu */ void SetMeshAttributes(GoFigureMeshAttributes *iMeshAttributes); protected: std::vector< std::vector< std::string > > m_ChannelsInfo; GoFigureMeshAttributes * m_MeshAttributes; /** \brief add the specific info for a trace to the columns description */ void SetSpecificInfoForMeshTable(); /** \brief add as many columns with their description as there is Channels */ void SetColumnsInfoBasedOnChannelsInfo(); /** \brief get the info for the channels from the database and set the corresponding columns for the intensities values \param[in] iDatabaseConnector connection to the database */ void SetChannelsInfo(vtkMySQLDatabase *iDatabaseConnector); /** \brief fill the row container with intensities values only if there is more than one mesh in the iVectmeshIDs and that m_MeshAttributes = 0, (expl: when all meshes are loaded from the database) if not, fill the container with values for volume and area also (expl: when a mesh is created from the visu)but the method SetMeshAttributes has to be called before. \param[in] iDatabaseConnector connection to the database \param[in] iVectMeshIDs vector of the meshIDs */ void FillRowContainerForMeshValues( vtkMySQLDatabase *iDatabaseConnector, std::vector< std::string > iVectMeshIDs); /** \overload */ void FillRowContainerForMeshValues( vtkMySQLDatabase *iDatabaseConnector, int iMeshID); /** \brief extract the volume and area values from the m_MeshAttributes,put them in ioValuesToFill and put the corresponding columns names in ioSelectFields \param[in,out] ioValuesToFill vector of the values where volume and area values will be pushed \param[in,out] ioSelectFields vector of the selected fields where the volume and area columns names in the TW will be pushed */ void GetValuesForSurfaceVolume( std::vector< std::vector< std::string > > & ioValuesToFill, std::vector< std::string > & ioSelectFields); /** \brief get the intensities values from the database,put them in ioValuesToFill, and put the corresponding columns names in ioSelectFields (from m_ChannelsInfo) \param[in] iDatabaseConnector connection to the database \param[in] iVectMeshIDs vector of the meshIDs for which the intensities are needed \param[in,out] ioValuesToFill vector of the values where the intensities values will be pushed \param[in,out] ioSelectFields vector of the selected fields where the intensities columns names in the TW will be pushed */ void GetValuesForIntensities( vtkMySQLDatabase *iDatabaseConnector, std::vector< std::string > iVectMeshIDs, std::vector< std::vector< std::string > > & ioValuesToFill, std::vector< std::string > & ioSelectFields); /** \brief get the intensities values from the database,and put them in ioValuesToFill for only one mesh \param[in] iMeshID meshID for the mesh the intensity values are needed \param[in,out] ioValuesToFill vector of the values where the intensities values will be pushed \param[in] iDatabaseConnector connection to the database */ void GetIntensityValuesForOneMesh(std::string iMeshID, std::vector< std::vector< std::string > > & ioValuesToFill, vtkMySQLDatabase *iDatabaseConnector); /** \brief sort the values in iResultQuery to fill ioValuesToFill \param[in] iResultQuery vector with all the data from the database \param[in] iVectMeshIDs vector of all the meshIDs \param[in] ioValuesToFill vector of the values where the intensities values will be pushed */ void GetValuesToFillForIntensityFromQueryResults( std::vector< std::string > iResultQuery, std::vector< std::string > iVectMeshIDs, std::vector< std::vector< std::string > > & ioValuesToFill); /** \brief set the columns and their description for the specific columns for mesh except the ones related to channels as a connection to the database is needed to know the number of channels */ void SetSpecificColumnsInfoForMesh(); }; #endif GoFigure2-v0.9.0/Code/IO/GoDBTWContainerForTrackLineage.cxx0000644000175000017500000000674011667757442023122 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBTWContainerForTrackLineage.h" GoDBTWContainerForTrackLineage::GoDBTWContainerForTrackLineage( std::string iTraceName, std::string iCollectionName, int iImgSessionID) : GoDBTableWidgetContainer(iTraceName, iCollectionName, iImgSessionID) { m_ColumnsInfos = GetColumnsInfoForTraceTable(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBTWContainerForTrackLineage::~GoDBTWContainerForTrackLineage() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void GoDBTWContainerForTrackLineage::SetCommonInfoForTwoTracesTable() { GoDBTraceInfoForTableWidget temp; std::pair< GoDBTraceInfoForTableWidget, std::vector< std::string > > PairTemp; //Get the info for the Time Point Min: temp.InfoName = "TimePointMin"; temp.ColumnNameDatabase = "TCoord"; temp.ColumnNameTableWidget = "TimePointMin"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMin"; temp.TableKeyDatabase = "CoordID"; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); temp.Clear(); //Get the info for the Time Point Max: temp.InfoName = "TimePointMax"; temp.ColumnNameDatabase = "TCoord"; temp.ColumnNameTableWidget = "TimePointMax"; temp.TableNameDatabase = "coordinate"; temp.TableForeignKeyDatabase = "CoordIDMax"; temp.TableKeyDatabase = "CoordID"; temp.SameFieldForDifferentValues = true; m_ColumnsInfos.push_back(temp); PairTemp.first = temp; m_RowContainer.push_back(PairTemp); this->SetInfoForColumnIsVisible(); }GoFigure2-v0.9.0/Code/Filters/0000755000175000017500000000000011667757442015656 5ustar mathieumathieuGoFigure2-v0.9.0/Code/Filters/itkGaussianProfileMatchingImageFilter.h0000644000175000017500000001577411667757442025434 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkGaussianProfileMatchingImageFilter_h #define __itkGaussianProfileMatchingImageFilter_h #if defined( _MSC_VER ) #pragma warning ( disable : 4786 ) #endif #ifdef __BORLANDC__ #define ITK_LEAN_AND_MEAN #endif #include "itkImageToImageFilter.h" #include "itkCastImageFilter.h" #include "itkMedianImageFilter.h" #include "itkRecursiveGaussianImageFilter.h" #include "itkRegionOfInterestImageFilter.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkRescaleIntensityImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkImageRegionIterator.h" #include "itkImageRegion.h" #include "itkRegion.h" #include "itkIndex.h" #include "itkSize.h" namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > class GaussianProfileMatchingImageFilter:public ImageToImageFilter< TFeatureImage, TInputImage > { public: typedef GaussianProfileMatchingImageFilter Self; typedef ImageToImageFilter< TFeatureImage, TInputImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkStaticConstMacro (ImageDimension, unsigned int, TFeatureImage::ImageDimension); /** Method for creation through object factory */ itkNewMacro (Self); /** Run-time type information */ itkTypeMacro (GaussianProfileMatchingImageFilter, ImageToImageFilter); /** Display */ void PrintSelf(std::ostream & os, Indent indent) const; typedef TFeatureImage FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef typename FeatureImageType::ConstPointer FeatureImageConstPointer; typedef typename FeatureImageType::PixelType FeatureImagePixelType; typedef typename FeatureImageType::RegionType FeatureImageRegionType; typedef typename FeatureImageType::SizeType FeatureImageSizeType; typedef typename FeatureImageSizeType::SizeValueType FeatureImageSizeValueType; typedef typename FeatureImageType::SpacingType FeatureImageSpacingType; typedef typename FeatureImageType::IndexType FeatureImageIndexType; typedef typename FeatureImageType::PointType FeatureImagePointType; typedef TInputImage ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::PixelType ImagePixelType; typedef typename ImageType::RegionType ImageRegionType; typedef typename ImageType::SizeType ImageSizeType; typedef typename ImageSizeType::SizeValueType ImageSizeValueType; typedef typename ImageType::SpacingType ImageSpacingType; typedef typename ImageType::IndexType ImageIndexType; typedef typename ImageType::PointType ImagePointType; typedef TSegmentImage SegmentImageType; typedef typename SegmentImageType::Pointer SegmentImagePointer; typedef typename SegmentImageType::ConstPointer SegmentImageConstPointer; typedef typename SegmentImageType::IndexType SegmentImageIndexType; typedef typename SegmentImageType::PixelType SegmentImagePixelType; typedef RegionOfInterestImageFilter< FeatureImageType, FeatureImageType > ROIFilterType; typedef typename ROIFilterType::Pointer ROIFilterPointer; typedef CastImageFilter< FeatureImageType, FeatureImageType > CastFilterType; typedef typename CastFilterType::Pointer CastFilterPointer; typedef ImageRegionConstIterator< FeatureImageType > FeatureConstIteratorType; typedef ImageRegionConstIteratorWithIndex< FeatureImageType > FeatureIndexConstIteratorType; typedef ImageRegionIterator< ImageType > IteratorType; typedef ImageRegionIteratorWithIndex< ImageType > IndexIteratorType; itkGetConstMacro (SigmaForm, double); itkSetMacro (SigmaForm, double); itkGetConstMacro (LargestCellRadius, double); itkSetMacro (LargestCellRadius, double); protected: GaussianProfileMatchingImageFilter(); ~GaussianProfileMatchingImageFilter() {} ImagePointer GaussianCorrelation(FeatureImagePointer rawImg); inline ImagePixelType PearsonCorrelation(ImageRegionType & region); ImagePointer InitializeBlob(FeatureImageSpacingType spacing, FeatureImageSizeType size); /** Method for evaluating the implicit function over the image. */ virtual void BeforeThreadedGenerateData(); virtual void AfterThreadedGenerateData(); virtual void ThreadedGenerateData(const ImageRegionType & windowRegion, #ifdef ITKv4 ThreadIdType threadId ); #else int threadId); #endif void GenerateInputRequestedRegion(); void EnlargeOutputRequestedRegion( DataObject *itkNotUsed(output) ); double m_SigmaForm; double m_LargestCellRadius; FeatureImageSizeType m_CellExtent; FeatureImageRegionType m_ImageRegion; ImagePointer m_Blob; private: GaussianProfileMatchingImageFilter (Self &); // intentionally not implemented void operator=(const Self &); // intentionally not implemented }; } /* namespace itk */ #include "itkGaussianProfileMatchingImageFilter.txx" #endif GoFigure2-v0.9.0/Code/Filters/itkGradientWeightedIntensityImageFilter.txx0000644000175000017500000001224611667757442026376 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkGradientWeightedIntensityImageFilter_txx #define __itkGradientWeightedIntensityImageFilter_txx #include "itkGradientWeightedIntensityImageFilter.h" namespace itk { // Software Guide : BeginCodeSnippet template< class TFeatureImage, class TInputImage, class TSegmentImage > GradientWeightedIntensityImageFilter< TFeatureImage, TInputImage, TSegmentImage > ::GradientWeightedIntensityImageFilter() { m_LargestCellRadius = 5.0; m_NucleiSigma = 0.4; m_Alpha = 1.0; m_Beta = 3.0; m_Gamma = 2.0; m_Blob = 0; this->Superclass::SetNumberOfRequiredInputs (1); this->Superclass::SetNumberOfRequiredOutputs (1); this->Superclass::SetNthOutput ( 0, TInputImage::New() ); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void GradientWeightedIntensityImageFilter< TFeatureImage, TInputImage, TSegmentImage >::GenerateData() { ImagePointer outputImg = ImageType::New(); outputImg->CopyInformation( this->GetInput() ); outputImg->SetRegions( this->GetInput()->GetLargestPossibleRegion() ); outputImg->Allocate(); outputImg->FillBuffer(1.0); IteratorType oIt( outputImg, outputImg->GetLargestPossibleRegion() ); double q; if ( m_Beta > 0 ) { FIteratorType lIt( m_Blob, m_Blob->GetLargestPossibleRegion() ); oIt.GoToBegin(); lIt.GoToBegin(); while ( !oIt.IsAtEnd() ) { q = vcl_exp(m_Beta * static_cast< double >( lIt.Get() ) / 255); oIt.Set( q * oIt.Get() ); ++oIt; ++lIt; } } if ( m_Gamma > 0 ) { IteratorType lIt( m_Form, m_Form->GetLargestPossibleRegion() ); oIt.GoToBegin(); lIt.GoToBegin(); while ( !oIt.IsAtEnd() ) { q = vcl_exp( -m_Gamma * static_cast< double >( lIt.Get() ) ); oIt.Set( q * oIt.Get() ); ++oIt; ++lIt; } } // Compute the gradient magnitude if ( m_Alpha > 0 ) { GradientFilterPointer m_gradientMagnitude = GradientFilterType::New(); m_gradientMagnitude->SetInput ( this->GetInput () ); m_gradientMagnitude->SetSigma (m_NucleiSigma); m_gradientMagnitude->Update(); RescaleFilterPointer rescale = RescaleFilterType::New(); rescale->SetInput( m_gradientMagnitude->GetOutput() ); rescale->SetOutputMinimum(0); rescale->SetOutputMaximum(1); rescale->Update(); IteratorType gIt( rescale->GetOutput(), rescale->GetOutput()->GetLargestPossibleRegion() ); oIt.GoToBegin(); gIt.GoToBegin(); while ( !oIt.IsAtEnd() ) { q = vcl_exp( m_Alpha * static_cast< double >( gIt.Get() ) ); oIt.Set( q * oIt.Get() ); ++oIt; ++gIt; } } ConstIteratorType dIt( this->GetInput(), this->GetInput()->GetLargestPossibleRegion() ); ImagePixelType p; oIt.GoToBegin(); dIt.GoToBegin(); while ( !oIt.IsAtEnd() ) { p = ( 255 - dIt.Get() ) * oIt.Get(); p = p > 255 ? 255 : p; oIt.Set (p); ++oIt; ++dIt; } this->GraftOutput (outputImg); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void GradientWeightedIntensityImageFilter< TFeatureImage, TInputImage, TSegmentImage >::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf (os, indent); os << indent << "Class Name: " << this->GetNameOfClass() << std::endl; } } /* end namespace itk */ #endifGoFigure2-v0.9.0/Code/Filters/itkCellForegroundExtraction.h0000644000175000017500000002120011667757442023505 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkCellForegroundExtraction_h #define __itkCellForegroundExtraction_h #if defined( _MSC_VER ) #pragma warning ( disable : 4786 ) #endif #ifdef __BORLANDC__ #define ITK_LEAN_AND_MEAN #endif #include "itkAffineTransform.h" #include "itkImageToImageFilter.h" #include "itkCastImageFilter.h" #include "itkMedianImageFilter.h" #include "itkAffineTransform.h" #include "itkGrayscaleFillholeImageFilter.h" #include "itkRecursiveGaussianImageFilter.h" #include "itkRegionOfInterestImageFilter.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkRescaleIntensityImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkResampleImageFilter.h" #include "itkLinearInterpolateImageFunction.h" #include "itkGaussianProfileMatchingImageFilter.h" #include "itkImageRegionIterator.h" #include "itkImageRegion.h" #include "itkRegion.h" #include "itkIndex.h" #include "itkSize.h" namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > class CellForegroundExtraction:public ImageToImageFilter< TFeatureImage, TSegmentImage > { public: typedef CellForegroundExtraction Self; typedef ImageToImageFilter< TFeatureImage, TSegmentImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkStaticConstMacro (ImageDimension, unsigned int, TFeatureImage::ImageDimension); /** Method for creation through object factory */ itkNewMacro (Self); /** Run-time type information */ itkTypeMacro (CellForegroundExtraction, ImageToImageFilter); /** Display */ void PrintSelf(std::ostream & os, Indent indent) const; typedef TFeatureImage FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef typename FeatureImageType::ConstPointer FeatureImageConstPointer; typedef typename FeatureImageType::PixelType FeatureImagePixelType; typedef typename FeatureImageType::RegionType FeatureImageRegionType; typedef typename FeatureImageType::SizeType FeatureImageSizeType; typedef typename FeatureImageSizeType::SizeValueType FeatureImageSizeValueType; typedef typename FeatureImageType::SpacingType FeatureImageSpacingType; typedef typename FeatureImageType::IndexType FeatureImageIndexType; typedef typename FeatureImageType::PointType FeatureImagePointType; typedef TInputImage ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::PixelType ImagePixelType; typedef typename ImageType::RegionType ImageRegionType; typedef typename ImageType::SizeType ImageSizeType; typedef typename ImageSizeType::SizeValueType ImageSizeValueType; typedef typename ImageType::SpacingType ImageSpacingType; typedef typename ImageType::IndexType ImageIndexType; typedef typename ImageType::PointType ImagePointType; typedef TSegmentImage SegmentImageType; typedef typename SegmentImageType::Pointer SegmentImagePointer; typedef typename SegmentImageType::ConstPointer SegmentImageConstPointer; typedef typename SegmentImageType::IndexType SegmentImageIndexType; typedef typename SegmentImageType::PixelType SegmentImagePixelType; typedef RegionOfInterestImageFilter< FeatureImageType, FeatureImageType > ROIFilterType; typedef typename ROIFilterType::Pointer ROIFilterPointer; typedef CastImageFilter< FeatureImageType, FeatureImageType > CastFilterType; typedef typename CastFilterType::Pointer CastFilterPointer; typedef ResampleImageFilter< FeatureImageType, FeatureImageType > ResampleFeatureFilterType; typedef typename ResampleFeatureFilterType::Pointer ResampleFeatureFilterPointer; typedef LinearInterpolateImageFunction< FeatureImageType > InterpolatorFeatureType; typedef typename InterpolatorFeatureType::Pointer InterpolatorFeaturePointer; typedef ResampleImageFilter< ImageType, ImageType > ResampleFilterType; typedef typename ResampleFilterType::Pointer ResampleFilterPointer; typedef LinearInterpolateImageFunction< ImageType > InterpolatorType; typedef typename InterpolatorType::Pointer InterpolatorPointer; typedef AffineTransform< double, ImageDimension > TransformType; typedef typename TransformType::Pointer TransformPointer; typedef RescaleIntensityImageFilter< ImageType, ImageType > RescaleFilterType; typedef typename RescaleFilterType::Pointer RescaleFilterPointer; typedef GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage > GaussProfileFilterType; typedef typename GaussProfileFilterType::Pointer GaussProfileFilterPointer; typedef ImageRegionConstIterator< FeatureImageType > FeatureConstIteratorType; typedef ImageRegionIteratorWithIndex< FeatureImageType > FeatureIndexIteratorType; typedef ImageRegionIterator< ImageType > IteratorType; typedef ImageRegionIterator< SegmentImageType > SegmentIteratorType; typedef ImageRegionIteratorWithIndex< ImageType > IndexIteratorType; itkGetConstMacro (SigmaForm, double); itkSetMacro (SigmaForm, double); itkGetConstMacro (ThresholdCellmin, double); itkSetMacro (ThresholdCellmin, double); itkGetConstMacro (ThresholdCellmax, double); itkSetMacro (ThresholdCellmax, double); itkGetConstMacro (ThresholdMembrane, double); itkSetMacro (ThresholdMembrane, double); itkGetConstMacro (ThresholdForm, double); itkSetMacro (ThresholdForm, double); itkGetConstMacro (LargestCellRadius, double); itkSetMacro (LargestCellRadius, double); void SetSampling(float *sampling) { m_Sampling = sampling; } ImagePointer GetGaussCorrImage(void) const { return gauss; } protected: CellForegroundExtraction(); ~CellForegroundExtraction() {} FeatureImagePointer ResampleInput(FeatureImageConstPointer input, FeatureImageSpacingType spacing, FeatureImageSizeType size, FeatureImagePointType origin); ImagePointer Resample(ImagePointer input, FeatureImageSpacingType spacing, FeatureImageSizeType size, FeatureImagePointType origin); void GenerateData(); double m_SigmaForm; double m_ThresholdCellmin; double m_ThresholdCellmax; double m_ThresholdMembrane; // Change to size threshold double m_ThresholdForm; double m_LargestCellRadius; float *m_Sampling; ImagePointer gauss; private: CellForegroundExtraction (Self &); // intentionally not implemented void operator=(const Self &); // intentionally not implemented }; } /* namespace itk */ #include "itkCellForegroundExtraction.txx" #endif GoFigure2-v0.9.0/Code/Filters/itkMorphologicalWatershedImageFilter2.h0000644000175000017500000001603711667757442025407 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkMorphologicalWatershedImageFilter2.h,v $ Language: C++ Date: $Date: 2009-04-23 03:43:42 $ Version: $Revision: 1.3 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkMorphologicalWatershedImageFilter2_h #define __itkMorphologicalWatershedImageFilter2_h #include "itkImageToImageFilter.h" namespace itk { /** \class MorphologicalWatershedImageFilter2 * \brief * * \todo (Kishore) write a brief documentation! * * Watershed pixel are labeled 0. * TOutputImage should be an integer type. * Labels of output image are in no particular order. You can reorder the * labels such that object labels are consecutive and sorted based on object * size by passing the output of this filter to a RelabelComponentImageFilter. * * The morphological watershed transform algorithm is described in * Chapter 9.2 of Pierre Soille's book "Morphological Image Analysis: * Principles and Applications", Second Edition, Springer, 2003. * * \author Gaetan Lehmann. Biologie du Developpement et de la Reproduction, INRA de Jouy-en-Josas, France. * * \sa WatershedImageFilter, MorphologicalWatershedFromMarkersImageFilter * \ingroup ImageEnhancement MathematicalMorphologyImageFilters */ template< class TInputImage, class TOutputImage > class MorphologicalWatershedImageFilter2: public ImageToImageFilter< TInputImage, TOutputImage > { public: /** Standard class typedefs. */ typedef MorphologicalWatershedImageFilter2 Self; typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Some convenient typedefs. */ typedef TInputImage InputImageType; typedef TOutputImage OutputImageType; typedef typename InputImageType::Pointer InputImagePointer; typedef typename InputImageType::ConstPointer InputImageConstPointer; typedef typename InputImageType::RegionType InputImageRegionType; typedef typename InputImageType::PixelType InputImagePixelType; typedef typename OutputImageType::Pointer OutputImagePointer; typedef typename OutputImageType::ConstPointer OutputImageConstPointer; typedef typename OutputImageType::RegionType OutputImageRegionType; typedef typename OutputImageType::PixelType OutputImagePixelType; /** ImageDimension constants */ itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension); itkStaticConstMacro(OutputImageDimension, unsigned int, TOutputImage::ImageDimension); /** Standard New method. */ itkNewMacro(Self); /** Runtime information support. */ itkTypeMacro(MorphologicalWatershedImageFilter2, ImageToImageFilter); /** * Set/Get whether the connected components are defined strictly by * face connectivity or by face+edge+vertex connectivity. Default is * FullyConnectedOff. For objects that are 1 pixel wide, use * FullyConnectedOn. */ itkSetMacro(FullyConnected, bool); itkGetConstReferenceMacro(FullyConnected, bool); itkBooleanMacro(FullyConnected); /** * Set/Get whether the watershed pixel must be marked or not. Default * is true. Set it to false do not only avoid writing watershed pixels, * it also decrease algorithm complexity. */ itkSetMacro(MarkWatershedLine, bool); itkGetConstReferenceMacro(MarkWatershedLine, bool); itkBooleanMacro(MarkWatershedLine); /** */ itkSetMacro(Level, InputImagePixelType); itkGetConstMacro(Level, InputImagePixelType); /** Set the marker image */ void SetForegroundImage(TOutputImage *fg) { m_ForegroundImg = fg; } protected: MorphologicalWatershedImageFilter2(); ~MorphologicalWatershedImageFilter2() {} void PrintSelf(std::ostream & os, Indent indent) const; /** MorphologicalWatershedImageFilter2 needs the entire input be * available. Thus, it needs to provide an implementation of * GenerateInputRequestedRegion(). */ void GenerateInputRequestedRegion(); /** MorphologicalWatershedImageFilter2 will produce the entire output. */ void EnlargeOutputRequestedRegion( DataObject *itkNotUsed(output) ); /** Single-threaded version of GenerateData. This filter delegates * to GrayscaleGeodesicErodeImageFilter. */ void GenerateData(); OutputImagePointer m_ForegroundImg; private: MorphologicalWatershedImageFilter2(const Self &); //purposely not implemented void operator=(const Self &); //purposely not implemented bool m_FullyConnected; bool m_MarkWatershedLine; InputImagePixelType m_Level; }; // end of class } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkMorphologicalWatershedImageFilter2.txx" #endif #endif GoFigure2-v0.9.0/Code/Filters/itkViscousWatershedTransform.h0000644000175000017500000001462211667757442023742 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkViscousWatershedTransform_h #define __itkViscousWatershedTransform_h #if defined( _MSC_VER ) #pragma warning ( disable : 4786 ) #endif #ifdef __BORLANDC__ #define ITK_LEAN_AND_MEAN #endif #include "itkImageToImageFilter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkBinaryBallStructuringElement.h" #include "itkBinaryMorphologicalClosingImageFilter.h" #include "itkImageRegionIterator.h" namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > class ViscousWatershedTransform:public ImageToImageFilter< TFeatureImage, TFeatureImage > { public: typedef ViscousWatershedTransform Self; typedef ImageToImageFilter< TFeatureImage, TFeatureImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkStaticConstMacro (ImageDimension, unsigned int, TFeatureImage::ImageDimension); /** Method for creation through object factory */ itkNewMacro (Self); /** Run-time type information */ itkTypeMacro (ViscousWatershedTransform, ImageToImageFilter); /** Display */ void PrintSelf(std::ostream & os, Indent indent) const; typedef TFeatureImage FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef typename FeatureImageType::ConstPointer FeatureImageConstPointer; typedef typename FeatureImageType::PixelType FeatureImagePixelType; typedef typename FeatureImageType::RegionType FeatureImageRegionType; typedef typename FeatureImageType::SizeType FeatureImageSizeType; typedef typename FeatureImageSizeType::SizeValueType FeatureImageSizeValueType; typedef typename FeatureImageType::SpacingType FeatureImageSpacingType; typedef typename FeatureImageType::IndexType FeatureImageIndexType; typedef typename FeatureImageType::PointType FeatureImagePointType; typedef TInputImage ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::PixelType ImagePixelType; typedef typename ImageType::RegionType ImageRegionType; typedef typename ImageType::SizeType ImageSizeType; typedef typename ImageSizeType::SizeValueType ImageSizeValueType; typedef typename ImageType::SpacingType ImageSpacingType; typedef typename ImageType::IndexType ImageIndexType; typedef typename ImageType::PointType ImagePointType; typedef TSegmentImage SegmentImageType; typedef typename SegmentImageType::Pointer SegmentImagePointer; typedef typename SegmentImageType::ConstPointer SegmentImageConstPointer; typedef typename SegmentImageType::IndexType SegmentImageIndexType; typedef typename SegmentImageType::PixelType SegmentImagePixelType; typedef BinaryThresholdImageFilter< FeatureImageType, FeatureImageType > ThresholdFilterType; typedef typename ThresholdFilterType::Pointer ThresholdFilterPointer; typedef BinaryBallStructuringElement< int, ImageDimension > StructuringElementType; typedef BinaryMorphologicalClosingImageFilter< FeatureImageType, FeatureImageType, StructuringElementType > ClosingFilterType; typedef typename ClosingFilterType::Pointer ClosingFilterPointer; typedef ImageRegionIterator< FeatureImageType > FeatureIteratorType; itkSetMacro (InitialLevel, unsigned int); itkGetConstMacro (InitialLevel, unsigned int); itkSetMacro (FinalLevel, unsigned int); itkGetConstMacro (FinalLevel, unsigned int); itkSetMacro (Increment, unsigned int); itkGetConstMacro (Increment, unsigned int); itkSetMacro (LargestRadius, unsigned int); itkGetConstMacro (LargestRadius, unsigned int); itkSetMacro (Slope, unsigned int); itkGetConstMacro (Slope, unsigned int); protected: ViscousWatershedTransform(); ~ViscousWatershedTransform() {} void GenerateData(); unsigned int m_InitialLevel; unsigned int m_FinalLevel; unsigned int m_Increment; unsigned int m_LargestRadius; unsigned int m_Slope; private: ViscousWatershedTransform (Self &); // intentionally not implemented void operator=(const Self &); // intentionally not implemented }; } /* namespace itk */ #include "itkViscousWatershedTransform.txx" #endif GoFigure2-v0.9.0/Code/Filters/itkCellFeatureGenerator.h0000644000175000017500000001733411667757442022611 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkCellFeatureGenerator_h #define __itkCellFeatureGenerator_h #if defined( _MSC_VER ) #pragma warning ( disable : 4786 ) #endif #ifdef __BORLANDC__ #define ITK_LEAN_AND_MEAN #endif #include "itkImageToImageFilter.h" #include "itkGradientMagnitudeRecursiveGaussianImageFilter.h" #include "itkSigmoidImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkSignedMaurerDistanceMapImageFilter.h" #include "itkAbsImageFilter.h" #include "itkThresholdImageFilter.h" #include "itkMinimumMaximumImageCalculator.h" #include "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" #include "itkImageRegion.h" #include "itkRegion.h" #include "itkIndex.h" #include "itkSize.h" #include "itkImageFileWriter.h" namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > class CellFeatureGenerator: public ImageToImageFilter< TFeatureImage, TInputImage > { public: typedef CellFeatureGenerator Self; typedef ImageToImageFilter< TFeatureImage, TInputImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkStaticConstMacro (ImageDimension, unsigned int, TFeatureImage::ImageDimension); /** Method for creation through object factory */ itkNewMacro (Self); /** Run-time type information */ itkTypeMacro (CellFeatureGenerator, ImageToImageFilter); /** Display */ void PrintSelf(std::ostream & os, Indent indent) const; typedef TFeatureImage FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef typename FeatureImageType::ConstPointer FeatureImageConstPointer; typedef typename FeatureImageType::PixelType FeatureImagePixelType; typedef typename FeatureImageType::RegionType FeatureImageRegionType; typedef typename FeatureImageType::SizeType FeatureImageSizeType; typedef typename FeatureImageSizeType::SizeValueType FeatureImageSizeValueType; typedef typename FeatureImageType::SpacingType FeatureImageSpacingType; typedef typename FeatureImageType::IndexType FeatureImageIndexType; typedef typename FeatureImageType::PointType FeatureImagePointType; typedef TInputImage ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::PixelType ImagePixelType; typedef typename ImageType::RegionType ImageRegionType; typedef typename ImageType::SizeType ImageSizeType; typedef typename ImageSizeType::SizeValueType ImageSizeValueType; typedef typename ImageType::SpacingType ImageSpacingType; typedef typename ImageType::IndexType ImageIndexType; typedef typename ImageType::PointType ImagePointType; typedef TSegmentImage SegmentImageType; typedef typename SegmentImageType::Pointer SegmentImagePointer; typedef typename SegmentImageType::ConstPointer SegmentImageConstPointer; typedef typename SegmentImageType::IndexType SegmentImageIndexType; typedef typename SegmentImageType::PixelType SegmentImagePixelType; typedef GradientMagnitudeRecursiveGaussianImageFilter< FeatureImageType, ImageType > GradientFilterType; typedef typename GradientFilterType::Pointer GradientFilterPointer; typedef SigmoidImageFilter< ImageType, ImageType > SigmoidFilterType; typedef typename SigmoidFilterType::Pointer SigmoidFilterPointer; typedef AbsImageFilter< ImageType, ImageType > AbsFilterType; typedef typename AbsFilterType::Pointer AbsFilterPointer; typedef ThresholdImageFilter< ImageType > ThreshFilterType; typedef typename ThreshFilterType::Pointer ThreshFilterPointer; typedef ImageRegionConstIterator< FeatureImageType > ConstIteratorType; typedef ImageRegionIterator< ImageType > IteratorType; typedef ImageRegionIteratorWithIndex< ImageType > IndexIteratorType; typedef SignedMaurerDistanceMapImageFilter< SegmentImageType, ImageType > MaurerType; typedef typename MaurerType::Pointer MaurerPointer; typedef MinimumMaximumImageCalculator< ImageType > MinMaxCalculatorType; typedef typename MinMaxCalculatorType::Pointer MinMaxCalculatorPointer; typedef MinimumMaximumImageCalculator< FeatureImageType > FeatureMinMaxCalculatorType; typedef typename FeatureMinMaxCalculatorType::Pointer FeatureMinMaxCalculatorPointer; itkGetConstMacro (NucleiSigma, double); itkSetMacro (NucleiSigma, double); itkGetConstMacro (MembraneSigma, double); itkSetMacro (MembraneSigma, double); itkGetConstMacro (LargestCellRadius, double); itkSetMacro (LargestCellRadius, double); itkGetConstMacro (DistanceMapWeight, double); itkSetMacro (DistanceMapWeight, double); itkGetConstMacro (NucleiGradientWeight, double); itkSetMacro (NucleiGradientWeight, double); itkGetConstMacro (MembraneWeight, double); itkSetMacro (MembraneWeight, double); void SetForeground(SegmentImagePointer fg) { m_ForegroundMap = fg; } ImagePointer GetDistanceMap() { return m_DistanceMap; } ImagePointer GetGradient() { return m_Gradient; } protected: CellFeatureGenerator(); ~CellFeatureGenerator() {} void DistanceMap(); void Gradient(); void Normalize(); void GenerateData(); double m_NucleiSigma; double m_MembraneSigma; double m_LargestCellRadius; double m_DistanceMapWeight; double m_NucleiGradientWeight; double m_MembraneWeight; SegmentImagePointer m_ForegroundMap; ImagePointer m_DistanceMap; ImagePointer m_Gradient; private: CellFeatureGenerator (Self &); // intentionally not implemented void operator=(const Self &); // intentionally not implemented }; } /* namespace itk */ #include "itkCellFeatureGenerator.txx" #endif GoFigure2-v0.9.0/Code/Filters/itkWatershedBasedCellSegmentation.h0000644000175000017500000001752411667757442024613 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkWatershedBasedCellSegmentation_h #define __itkWatershedBasedCellSegmentation_h #if defined( _MSC_VER ) #pragma warning ( disable : 4786 ) #endif #ifdef __BORLANDC__ #define ITK_LEAN_AND_MEAN #endif #include "itkImageToImageFilter.h" #include "itkPreprocessImageFilter.h" #include "itkCellForegroundExtraction.h" #include "itkGradientWeightedDistanceImageFilter.h" #include "itkInvertIntensityImageFilter.h" #include "itkMorphologicalWatershedImageFilter2.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkMinimumMaximumImageCalculator.h" #include "itkAntiAliasBinaryImageFilter.h" namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > class WatershedBasedCellSegmentation:public ImageToImageFilter< TFeatureImage, TSegmentImage > { public: typedef WatershedBasedCellSegmentation Self; typedef ImageToImageFilter< TFeatureImage, TSegmentImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkStaticConstMacro (ImageDimension, unsigned int, TFeatureImage::ImageDimension); /** Method for creation through object factory */ itkNewMacro (Self); /** Run-time type information */ itkTypeMacro (WatershedBasedCellSegmentation, ImageToImageFilter); /** Display */ void PrintSelf(std::ostream & os, Indent indent) const; typedef TFeatureImage FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef typename FeatureImageType::ConstPointer FeatureImageConstPointer; typedef typename FeatureImageType::PixelType FeatureImagePixelType; typedef typename FeatureImageType::RegionType FeatureImageRegionType; typedef typename FeatureImageType::SizeType FeatureImageSizeType; typedef typename FeatureImageSizeType::SizeValueType FeatureImageSizeValueType; typedef typename FeatureImageType::SpacingType FeatureImageSpacingType; typedef typename FeatureImageType::IndexType FeatureImageIndexType; typedef typename FeatureImageType::PointType FeatureImagePointType; typedef TInputImage InputImageType; typedef typename InputImageType::Pointer InputImagePointer; typedef typename InputImageType::ConstPointer InputImageConstPointer; typedef typename InputImageType::PixelType InputImagePixelType; typedef typename InputImageType::RegionType InputImageRegionType; typedef typename InputImageType::SizeType InputImageSizeType; typedef typename InputImageSizeType::SizeValueType InputImageSizeValueType; typedef typename InputImageType::SpacingType InputImageSpacingType; typedef typename InputImageType::IndexType InputImageIndexType; typedef typename InputImageType::PointType InputImagePointType; typedef TSegmentImage SegmentImageType; typedef typename SegmentImageType::Pointer SegmentImagePointer; typedef typename SegmentImageType::ConstPointer SegmentImageConstPointer; typedef typename SegmentImageType::IndexType SegmentImageIndexType; typedef typename SegmentImageType::PixelType SegmentImagePixelType; typedef typename SegmentImageType::SizeType SegmentImageSizeType; typedef typename SegmentImageIndexType::IndexValueType SegmentImageIndexValueType; typedef typename SegmentImageType::RegionType SegmentImageRegionType; typedef PreprocessImageFilter< FeatureImageType, FeatureImageType > PreprocessFilterType; typedef typename PreprocessFilterType::Pointer PreprocessFilterPointer; typedef CellForegroundExtraction< FeatureImageType, InputImageType, SegmentImageType > ForegroundFilterType; typedef typename ForegroundFilterType::Pointer ForegroundFilterPointer; typedef GradientWeightedDistanceImageFilter< FeatureImageType, InputImageType, SegmentImageType > DistanceFilterType; typedef typename DistanceFilterType::Pointer DistanceFilterPointer; typedef InvertIntensityImageFilter< InputImageType, InputImageType > RInvertType; typedef typename RInvertType::Pointer RInvertPointer; typedef MorphologicalWatershedImageFilter2< InputImageType, SegmentImageType > WatershedFilterType; typedef typename WatershedFilterType::Pointer WatershedFilterPointer; typedef MinimumMaximumImageCalculator< InputImageType > MinMaxCalculatorType; typedef ImageRegionIterator< FeatureImageType > FeatureIteratorType; typedef ImageRegionIterator< InputImageType > InputIteratorType; typedef ImageRegionIteratorWithIndex< SegmentImageType > SegmentIteratorType; typedef AntiAliasBinaryImageFilter< SegmentImageType, InputImageType > AntiAliasFilterType; typedef typename AntiAliasFilterType::Pointer AntiAliasFilterPointer; itkGetConstMacro (NucleusRadius, double); itkSetMacro (NucleusRadius, double); itkGetConstMacro (CorrelationKernelSigma, double); itkSetMacro (CorrelationKernelSigma, double); itkGetConstMacro (NucleusThresholdMin, double); itkSetMacro (NucleusThresholdMin, double); itkGetConstMacro (NucleusThresholdMax, double); itkSetMacro (NucleusThresholdMax, double); itkGetConstMacro (CorrelationThreshold1, double); itkSetMacro (CorrelationThreshold1, double); itkGetConstMacro (MembraneThreshold, double); itkSetMacro (MembraneThreshold, double); itkGetConstMacro (Alpha, float); itkSetMacro (Alpha, float); itkGetConstMacro (Beta, float); itkSetMacro (Beta, float); protected: WatershedBasedCellSegmentation(); ~WatershedBasedCellSegmentation() {} void GenerateData(); double m_NucleusRadius; double m_CorrelationKernelSigma; int m_NucleusThresholdMin; int m_NucleusThresholdMax; double m_CorrelationThreshold1; int m_MembraneThreshold; float m_Alpha; float m_Beta; private: WatershedBasedCellSegmentation (Self &); // intentionally not implemented void operator=(const Self &); // intentionally not implemented }; } /* namespace itk */ #include "itkWatershedBasedCellSegmentation.txx" #endif GoFigure2-v0.9.0/Code/Filters/itkCellFeatureGenerator.txx0000644000175000017500000001755411667757442023211 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkCellFeatureGenerator_txx #define __itkCellFeatureGenerator_txx #include "itkCellFeatureGenerator.h" namespace itk { // Software Guide : BeginCodeSnippet template< class TFeatureImage, class TInputImage, class TSegmentImage > CellFeatureGenerator< TFeatureImage, TInputImage, TSegmentImage > ::CellFeatureGenerator() { m_NucleiSigma = 0.2; m_MembraneSigma = 0.2; m_LargestCellRadius = 4.0; m_DistanceMapWeight = 1.0; m_NucleiGradientWeight = 0.0; m_MembraneWeight = 0.0; m_ForegroundMap = NULL; m_DistanceMap = NULL; m_Gradient = NULL; this->Superclass::SetNumberOfRequiredInputs (2); this->Superclass::SetNumberOfRequiredOutputs (1); this->Superclass::SetNthOutput ( 0, TInputImage::New() ); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void CellFeatureGenerator< TFeatureImage, TInputImage, TSegmentImage > ::DistanceMap() { MaurerPointer m_Maurer = MaurerType::New(); m_Maurer->SetInput (m_ForegroundMap); m_Maurer->SetSquaredDistance (0); m_Maurer->SetUseImageSpacing (1); m_Maurer->SetInsideIsPositive (0); m_Maurer->Update(); AbsFilterPointer m_absFilter = AbsFilterType::New(); m_absFilter->SetInput ( m_Maurer->GetOutput() ); m_absFilter->Update(); ThreshFilterPointer m_thresh = ThreshFilterType::New(); m_thresh->SetInput ( m_absFilter->GetOutput() ); m_thresh->ThresholdAbove (m_LargestCellRadius); m_thresh->SetOutsideValue (m_LargestCellRadius); m_thresh->Update(); m_DistanceMap = m_thresh->GetOutput(); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void CellFeatureGenerator< TFeatureImage, TInputImage, TSegmentImage > ::Gradient() { // Compute the gradient magnitude GradientFilterPointer m_gradientMagnitude = GradientFilterType::New(); m_gradientMagnitude->SetInput ( this->GetInput (0) ); m_gradientMagnitude->SetSigma (m_NucleiSigma); m_gradientMagnitude->Update(); IteratorType distIt( m_DistanceMap, m_DistanceMap->GetLargestPossibleRegion() ); IteratorType gradientIt( m_gradientMagnitude->GetOutput(), m_gradientMagnitude->GetOutput()->GetLargestPossibleRegion() ); double alpha = -1, beta = 0; float k1 = 0, k2 = 0; int n1 = 0, n2 = 0; for ( distIt.GoToBegin(), gradientIt.GoToBegin(); !distIt.IsAtEnd(); ++distIt, ++gradientIt ) { if ( distIt.Get() < m_LargestCellRadius / 4 ) { k1 += gradientIt.Get(); ++n1; } else { k2 += gradientIt.Get(); ++n2; } } if ( ( n1 > 0 ) && ( n2 > 0 ) ) { k1 /= static_cast< float >(n1); k2 /= static_cast< float >(n2); alpha = ( k2 - k1 ) / 2; beta = ( k2 + k1 ) / 2; } // std::cout << k1 << ' ' << k2 << std::endl; // std::cout << "Estimating Alpha and Beta complete..." << std::endl; // std::cout << alpha << ' ' << beta << std::endl; SigmoidFilterPointer m_sigmoid = SigmoidFilterType::New(); m_sigmoid->SetInput ( m_gradientMagnitude->GetOutput() ); m_sigmoid->SetOutputMinimum (0.0); m_sigmoid->SetOutputMaximum (1); m_sigmoid->SetAlpha (alpha); m_sigmoid->SetBeta (beta); m_sigmoid->Update(); m_Gradient = m_sigmoid->GetOutput(); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void CellFeatureGenerator< TFeatureImage, TInputImage, TSegmentImage >::GenerateData() { ImagePointer outputImg = ImageType::New(); outputImg->SetRegions ( this->GetInput(0)->GetLargestPossibleRegion() ); outputImg->SetSpacing ( this->GetInput(0)->GetSpacing() ); outputImg->SetOrigin ( this->GetInput(0)->GetOrigin() ); outputImg->Allocate(); outputImg->FillBuffer (0); if ( m_DistanceMapWeight > 0 ) { DistanceMap(); } m_ForegroundMap = 0; if ( m_NucleiGradientWeight > 0 ) { Gradient(); m_Gradient->SetSpacing ( m_DistanceMap->GetSpacing() ); } else { m_Gradient = outputImg; } FeatureMinMaxCalculatorPointer minMax1 = FeatureMinMaxCalculatorType::New(); minMax1->SetImage( this->GetInput(1) ); minMax1->ComputeMaximum(); double mmax = static_cast< double >( minMax1->GetMaximum() ); MinMaxCalculatorPointer minMax2 = MinMaxCalculatorType::New(); minMax2->SetImage(m_DistanceMap); minMax2->ComputeMaximum(); double dmax = static_cast< double >( minMax2->GetMaximum() ); double weight = m_DistanceMapWeight + m_NucleiGradientWeight + m_MembraneWeight; IteratorType It( outputImg, outputImg->GetLargestPossibleRegion() ); IteratorType dIt( m_DistanceMap, m_DistanceMap->GetLargestPossibleRegion() ); IteratorType gIt( m_Gradient, m_Gradient->GetLargestPossibleRegion() ); ConstIteratorType mIt( this->GetInput(1), this->GetInput(1)->GetLargestPossibleRegion() ); double dterm, gterm, mterm; mIt.GoToBegin(); gIt.GoToBegin(); dIt.GoToBegin(); It.GoToBegin(); while ( !mIt.IsAtEnd() ) { dterm = ( dIt.Get() / dmax ) * m_DistanceMapWeight; gterm = gIt.Get() * m_NucleiGradientWeight; mterm = ( 1 - mIt.Get() / mmax ) * m_MembraneWeight; It.Set ( static_cast< ImagePixelType >( ( dterm + gterm + mterm ) / weight) ); ++mIt; ++gIt; ++dIt; ++It; } this->GraftOutput (outputImg); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void CellFeatureGenerator< TFeatureImage, TInputImage, TSegmentImage >::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf (os, indent); os << indent << "Class Name: " << this->GetNameOfClass() << std::endl; os << indent << "Nuclei Sigma: " << this->GetNucleiSigma() << std::endl; os << indent << "Membrane Sigma: " << this->GetMembraneSigma() << std::endl; os << indent << "Largest Cell Radius: " << this->GetLargestCellRadius() << std::endl; os << indent << "DistanceMapWeight: " << this->GetDistanceMapWeight() << std::endl; os << indent << "NucleiGradientWeight: " << this->GetNucleiGradientWeight() << std::endl; os << indent << "MembraneWeight: " << this->GetMembraneWeight() << std::endl; } } /* end namespace itk */ #endifGoFigure2-v0.9.0/Code/Filters/itkMorphologicalWatershedFromMarkersImageFilter2.h0000644000175000017500000002227211667757442027556 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkMorphologicalWatershedFromMarkersImageFilter2.h,v $ Language: C++ Date: $Date: 2009-01-28 18:14:36 $ Version: $Revision: 1.4 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkMorphologicalWatershedFromMarkersImageFilter2_h #define __itkMorphologicalWatershedFromMarkersImageFilter2_h #include "itkImageToImageFilter.h" namespace itk { /** \class MorphologicalWatershedFromMarkersImageFilter2 * \brief Morphological watershed transform from markers * * The watershed transform is a tool for image segmentation that is fast * and flexible and potentially fairly parameter free. It was originally * derived from a geophysical model of rain falling on a terrain and a variety * of more formal definitions have been devised to allow development of * practical algorithms. If an image is considered as a terrain and divided * into catchment basins then the hope is that each catchment basin would * contain an object of interest. * * The output is a label image. A label image, sometimes referred to as a * categorical image, has unique values for each region. For example, if a * watershed produces 2 regions, all pixels belonging to one region would have * value A, and all belonging to the other might have value B. Unassigned * pixels, such as watershed lines, might have the background value (0 by * convention). * * The simplest way of using the watershed is to preprocess the image we * want to segment so that the boundaries of our objects are bright (e.g * apply an edge detector) and compute the watershed transform of the * edge image. Watershed lines will correspond to the boundaries and our * problem will be solved. This is rarely useful in practice because * there are always more regional minima than there are objects, either * due to noise or natural variations in the object surfaces. Therefore, * while many watershed lines do lie on significant boundaries, there are * many that don't. * Various methods can be used to reduce the number of minima in the image, * like thresholding the smallest values, filtering the minima and/or * smoothing the image. * * This filter use another approach to avoid the problem of over segmentation: * it let the user provide a marker image which mark the minima in the input * image and give them a label. The minima are imposed in the input image by * the markers. The labels of the output image are the label of the marker * image. * * The morphological watershed transform algorithm is described in * Chapter 9.2 of Pierre Soille's book "Morphological Image Analysis: * Principles and Applications", Second Edition, Springer, 2003. * * \author Gaetan Lehmann. Biologie du Developpement et de la Reproduction, INRA de Jouy-en-Josas, France. * \author Richard Beare. Department of Medicine, Monash University, Melbourne, Australia. * * \sa WatershedImageFilter, MorphologicalWatershedImageFilter * \ingroup ImageEnhancement MathematicalMorphologyImageFilters */ template< class TInputImage, class TLabelImage > class MorphologicalWatershedFromMarkersImageFilter2: public ImageToImageFilter< TInputImage, TLabelImage > { public: /** Standard class typedefs. */ typedef MorphologicalWatershedFromMarkersImageFilter2 Self; typedef ImageToImageFilter< TInputImage, TLabelImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Some convenient typedefs. */ typedef TInputImage InputImageType; typedef TLabelImage LabelImageType; typedef typename InputImageType::Pointer InputImagePointer; typedef typename InputImageType::ConstPointer InputImageConstPointer; typedef typename InputImageType::RegionType InputImageRegionType; typedef typename InputImageType::PixelType InputImagePixelType; typedef typename LabelImageType::Pointer LabelImagePointer; typedef typename LabelImageType::ConstPointer LabelImageConstPointer; typedef typename LabelImageType::RegionType LabelImageRegionType; typedef typename LabelImageType::PixelType LabelImagePixelType; typedef typename LabelImageType::IndexType IndexType; /** ImageDimension constants */ itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); /** Standard New method. */ itkNewMacro(Self); /** Runtime information support. */ itkTypeMacro(MorphologicalWatershedFromMarkersImageFilter2, ImageToImageFilter); /** Set the marker image */ void SetMarkerImage(const TLabelImage *input) { // Process object is not const-correct so the const casting is required. this->SetNthInput( 1, const_cast< TLabelImage * >( input ) ); } /** Get the marker image */ const LabelImageType * GetMarkerImage() const { return static_cast< LabelImageType * >( const_cast< DataObject * >( this->ProcessObject::GetInput(1) ) ); } /** Set the input image */ void SetInput1(const TInputImage *input) { this->SetInput(input); } /** Set the marker image */ void SetInput2(const TLabelImage *input) { this->SetMarkerImage(input); } /** Set the marker image */ void SetForegroundImage(TLabelImage *fg) { m_ForegroundImg = fg; } /** * Set/Get whether the connected components are defined strictly by * face connectivity or by face+edge+vertex connectivity. Default is * FullyConnectedOff. For objects that are 1 pixel wide, use * FullyConnectedOn. */ itkSetMacro(FullyConnected, bool); itkGetConstReferenceMacro(FullyConnected, bool); itkBooleanMacro(FullyConnected); /** * Set/Get whether the watershed pixel must be marked or not. Default * is true. Set it to false do not only avoid writing watershed pixels, * it also decrease algorithm complexity. */ itkSetMacro(MarkWatershedLine, bool); itkGetConstReferenceMacro(MarkWatershedLine, bool); itkBooleanMacro(MarkWatershedLine); protected: MorphologicalWatershedFromMarkersImageFilter2(); ~MorphologicalWatershedFromMarkersImageFilter2() {} void PrintSelf(std::ostream & os, Indent indent) const; /** MorphologicalWatershedFromMarkersImageFilter2 needs to request the * entire input images. */ void GenerateInputRequestedRegion(); /** This filter will enlarge the output requested region to produce * all of the output. * \sa ProcessObject::EnlargeOutputRequestedRegion() */ void EnlargeOutputRequestedRegion( DataObject *itkNotUsed(output) ); /** The filter is single threaded. */ void GenerateData(); LabelImagePointer m_ForegroundImg; private: //purposely not implemented MorphologicalWatershedFromMarkersImageFilter2(const Self &); void operator=(const Self &); //purposely not implemented bool m_FullyConnected; bool m_MarkWatershedLine; }; // end of class } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkMorphologicalWatershedFromMarkersImageFilter2.txx" #endif #endif GoFigure2-v0.9.0/Code/Filters/itkWatershedBasedCellSegmentation.txx0000644000175000017500000001623611667757442025206 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkWatershedBasedCellSegmentation_txx #define __itkWatershedBasedCellSegmentation_txx #include "itkWatershedBasedCellSegmentation.h" namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > WatershedBasedCellSegmentation< TFeatureImage, TInputImage, TSegmentImage > ::WatershedBasedCellSegmentation() { m_NucleusRadius = 4.0; m_CorrelationKernelSigma = 4.0; m_NucleusThresholdMin = 10; m_NucleusThresholdMax = 30; m_CorrelationThreshold1 = 0.50; m_MembraneThreshold = 256; m_Alpha = 1.5; m_Beta = 3.0; this->Superclass::SetNumberOfRequiredInputs (1); this->Superclass::SetNumberOfRequiredOutputs (1); this->Superclass::SetNthOutput ( 0, TSegmentImage::New() ); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void WatershedBasedCellSegmentation< TFeatureImage, TInputImage, TSegmentImage >::GenerateData() { PreprocessFilterPointer preprocess = PreprocessFilterType::New(); preprocess->SetInput( this->GetInput() ); preprocess->SetLargestCellRadius (m_NucleusRadius); preprocess->Update(); FeatureImageConstPointer m_NucleiImg = preprocess->GetOutput(); FeatureImageConstPointer m_MembraneImg = m_NucleiImg; SegmentImagePointer m_ForegroundImg; { // Apply Foreground filter ForegroundFilterPointer fgFilter = ForegroundFilterType::New(); fgFilter->SetInput (0, m_NucleiImg); fgFilter->SetInput (1, m_MembraneImg); fgFilter->SetSigmaForm (m_CorrelationKernelSigma); // in real coordinates fgFilter->SetThresholdCellmin (m_NucleusThresholdMin); fgFilter->SetThresholdCellmax (m_NucleusThresholdMax); fgFilter->SetThresholdMembrane (m_MembraneThreshold); fgFilter->SetThresholdForm (m_CorrelationThreshold1); fgFilter->SetLargestCellRadius (m_NucleusRadius); // in real coordinates fgFilter->SetNumberOfThreads( this->GetNumberOfThreads() ); fgFilter->Update(); // std::cout << "Computed foreground" << std::endl; m_ForegroundImg = fgFilter->GetOutput(); m_ForegroundImg->DisconnectPipeline(); } // Gradient weighted distance -- Todo: extend with blob instead of laplace DistanceFilterPointer distFilter = DistanceFilterType::New(); distFilter->SetInput (m_NucleiImg); distFilter->SetUseLevelSet(true); distFilter->SetForeground (m_ForegroundImg); distFilter->SetLargestCellRadius(m_NucleusRadius); distFilter->SetNucleiSigma (0.5); distFilter->SetAlpha(m_Alpha); distFilter->SetBeta(m_Beta); distFilter->Update(); //std::cout << "Computed distance map" << std::endl; typename MinMaxCalculatorType::Pointer minMax = MinMaxCalculatorType::New(); minMax->SetImage( distFilter->GetOutput() ); minMax->ComputeMaximum(); double max = static_cast< double >( minMax->GetMaximum() ); RInvertPointer idistance = RInvertType::New(); idistance->SetInput( distFilter->GetOutput() ); idistance->SetMaximum(max); idistance->Update(); // std::cout << "Inverted distance map" << std::endl; WatershedFilterPointer wshed = WatershedFilterType::New(); wshed->SetInput( idistance->GetOutput() ); wshed->SetMarkWatershedLine(false); wshed->SetLevel(1.0); wshed->FullyConnectedOn(); wshed->SetNumberOfThreads( this->GetNumberOfThreads() ); wshed->SetForegroundImage(m_ForegroundImg); wshed->Update(); SegmentImagePointer output = wshed->GetOutput(); output->DisconnectPipeline(); SegmentImageSizeType size = output->GetLargestPossibleRegion().GetSize(); SegmentImageIndexType index, index2; SegmentImageSizeType size2; for ( unsigned int i = 0; i < ImageDimension; i++ ) { index[i] = static_cast< SegmentImageIndexValueType >(size[i] / 2); index2[i] = 1; size2[i] = size[i] - 2; } SegmentImagePixelType label = output->GetPixel(index); SegmentImageRegionType region; region.SetIndex(index2); region.SetSize(size2); // std::cout << "label: " << label << std::endl; SegmentIteratorType It( output, output->GetLargestPossibleRegion() ); It.GoToBegin(); if ( label > 0 ) { while ( !It.IsAtEnd() ) { index = It.GetIndex(); if ( ( It.Get() == label ) && ( region.IsInside(index) ) ) { It.Set(1); } else { It.Set(0); } ++It; } } // std::cout << "Computed watershed segmentation" << std::endl; // InputImagePointer smooth; // { // AntiAliasFilterPointer antialiaser = AntiAliasFilterType::New(); // antialiaser->SetInput( output );// // antialiaser->SetMaximumRMSError( 1.0 ); // antialiaser->SetNumberOfIterations( 100 ); // antialiaser->SetInterpolateSurfaceLocation( true ); // antialiaser->UseImageSpacingOn(); // antialiaser->Update(); // smooth = antialiaser->GetOutput(); // smooth->DisconnectPipeline(); // } // // InputIteratorType iIt( smooth, smooth->GetLargestPossibleRegion() ); // for( iIt.GoToBegin(), It.GoToBegin(); !It.IsAtEnd(); ++iIt, ++It ) // { // if ( iIt.Get() > 0 ) // { // It.Set( 1 ); // } // else // { // It.Set( 0 ); // } // } this->GraftOutput(output); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void WatershedBasedCellSegmentation< TFeatureImage, TInputImage, TSegmentImage >::PrintSelf(std::ostream & os, Indent indent) const { (void)os; (void)indent; } } /* end namespace itk */ #endif GoFigure2-v0.9.0/Code/Filters/itkMultiScaleLoGDistanceImageFilter.txx0000644000175000017500000002032311667757442025363 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkMultiScaleLoGDistanceImageFilter.txx,v $ Language: C++ Date: $Date: 2007/06/20 16:03:23 $ Version: $Revision: 1.13 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkMultiScaleLoGDistanceImageFilter_txx #define __itkMultiScaleLoGDistanceImageFilter_txx #include "itkMultiScaleLoGDistanceImageFilter.h" #include "vnl/vnl_math.h" #define EPSILON 1e-03 namespace itk { /** * Constructor */ template< class InputImageType, class DistanceMapImageType, class OutputImageType > MultiScaleLoGDistanceImageFilter < InputImageType, DistanceMapImageType, OutputImageType > ::MultiScaleLoGDistanceImageFilter() { // default sigma min-max in world coordinate? m_SigmaMin = 0.2; m_SigmaMax = 2.0; m_NumberOfSigmaSteps = 4; m_ComputeOutsideForeground = false; // we create the laplacian filter m_LoGFilter = LoGFilterType::New(); this->Superclass::SetNumberOfRequiredInputs (1); this->Superclass::SetNumberOfRequiredOutputs (1); this->Superclass::SetNthOutput ( 0, OutputImageType::New() ); } /** * compute LoG at several sigma and give outputs to UpdateMaximumResponse */ template< class InputImageType, class DistanceMapImageType, class OutputImageType > void MultiScaleLoGDistanceImageFilter < InputImageType, DistanceMapImageType, OutputImageType > ::GenerateData() { // Allocate the output, and fill it with zeros OutputImagePointer outputImage = this->GetOutput(); // Zero the output outputImage->SetBufferedRegion( outputImage->GetRequestedRegion() ); outputImage->Allocate(); outputImage->FillBuffer (0); //NumericTraits::Zero ); InputImageConstPointer inputImage = this->GetInput(); // we set the laplacian filter's input as the input image m_LoGFilter->SetInput(inputImage); // true for multiscale analysis : // one doesn't want the image to fade away with high scale parameters m_LoGFilter->SetNormalizeAcrossScale(true); // multiscale analysis : double sigma = m_SigmaMin; // we start at sigma min int scaleLevel = 1; // sigma min corresponds to scale 1 (first // blurring) while ( sigma <= m_SigmaMax ) { m_LoGFilter->SetSigma(sigma); m_LoGFilter->Update(); this->UpdateMaximumResponse(scaleLevel); sigma = this->ComputeSigmaValue(scaleLevel); // compute sigma according to // the scale level scaleLevel++; // next scale level } } /** * Select maximal output of LoG accross cales, * depending on the Signed Distance Map. */ template< class InputImageType, class DistanceMapImageType, class OutputImageType > void MultiScaleLoGDistanceImageFilter < InputImageType, DistanceMapImageType, OutputImageType > ::UpdateMaximumResponse(const int & scaleLevel) { /** define iterators : */ // over the output OutputIteratorType oit( this->GetOutput(), this->GetOutput()->GetLargestPossibleRegion() ); oit.GoToBegin(); // over the Laplacian of Gaussian output ConstLoGIteratorType it( m_LoGFilter->GetOutput(), m_LoGFilter->GetOutput()->GetLargestPossibleRegion() ); it.GoToBegin(); // over the SDF map ConstDistanceMapIteratorType sdfit( m_DistanceMap, m_DistanceMap->GetLargestPossibleRegion() ); sdfit.GoToBegin(); double m_SigmaSquare = m_Sigma * m_Sigma; /** main loop */ if ( m_ComputeOutsideForeground ) // if we allow computation in positive sdf // area // (outside foreground) { while ( !oit.IsAtEnd() ) { // if the current sigma is bellow 2*distancemap (<=>Sigma^2 < // 4*distmap^2), // or if it is the first sigma : if ( ( m_SigmaSquare <= 4 * vcl_abs( sdfit.Value() ) ) || ( scaleLevel == 1 ) ) { // we take the LoG // if the output at this scale is larger than the previous value stored // Note: the LoG of a bright blob is a negative value if ( ( oit.Value() < -( it.Value() ) ) || ( scaleLevel == 1 ) ) { oit.Value() = -it.Value(); } } // next voxel ++oit; ++it; ++sdfit; } } else // if we don't allow computation in positive sdf areas { while ( !oit.IsAtEnd() ) { if ( sdfit.Value() <= 0 ) { // if the current sigma is bellow 2*distancemap (<=>Sigma^2 < // 4*distmap^2), // or if it is the first sigma : if ( ( m_SigmaSquare <= -4 * sdfit.Value() ) || ( scaleLevel == 1 ) ) { // we take the LoG // if the output at this scale is bigger (negative) than the previous // output if ( ( oit.Value() < -( it.Value() ) ) || ( scaleLevel == 1 ) ) { oit.Value() = -( it.Value() ); } } // next voxel } ++oit; ++it; ++sdfit; } } } template< class InputImageType, class DistanceMapImageType, class OutputImageType > double MultiScaleLoGDistanceImageFilter < InputImageType, DistanceMapImageType, OutputImageType > ::ComputeSigmaValue(int ScaleLevel) { double stepSize = ( vcl_log(m_SigmaMax) - vcl_log(m_SigmaMin) ) / m_NumberOfSigmaSteps; if ( stepSize <= 1e-10 ) { stepSize = 1e-10; } return ( vcl_exp(vcl_log (m_SigmaMin) + stepSize * ScaleLevel) ); } template< class InputImageType, class DistanceMapImageType, class OutputImageType > void MultiScaleLoGDistanceImageFilter < InputImageType, DistanceMapImageType, OutputImageType > ::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "SigmaMin: " << m_SigmaMin << std::endl; os << indent << "SigmaMax: " << m_SigmaMax << std::endl; os << indent << "NumberOfSigmaSteps: " << m_NumberOfSigmaSteps << std::endl; os << indent << "ComputeOutsideForeground: " << m_ComputeOutsideForeground << std::endl; } } // end namespace itk #endif GoFigure2-v0.9.0/Code/Filters/itkMorphologicalWatershedImageFilter2.txx0000644000175000017500000001630711667757442026003 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkMorphologicalWatershedImageFilter2.txx,v $ Language: C++ Date: $Date: 2007-01-26 15:01:47 $ Version: $Revision: 1.1 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkMorphologicalWatershedImageFilter2_txx #define __itkMorphologicalWatershedImageFilter2_txx #include "itkMorphologicalWatershedImageFilter2.h" #include "itkRegionalMinimaImageFilter.h" #include "itkHMinimaImageFilter.h" #include "itkConnectedComponentImageFilter.h" #include "itkMorphologicalWatershedFromMarkersImageFilter2.h" #include "itkNumericTraits.h" namespace itk { template< class TInputImage, class TOutputImage > MorphologicalWatershedImageFilter2< TInputImage, TOutputImage > ::MorphologicalWatershedImageFilter2() { m_FullyConnected = false; m_MarkWatershedLine = true; m_Level = NumericTraits< InputImagePixelType >::Zero; m_ForegroundImg = 0; } template< class TInputImage, class TOutputImage > void MorphologicalWatershedImageFilter2< TInputImage, TOutputImage > ::GenerateInputRequestedRegion() { // call the superclass' implementation of this method Superclass::GenerateInputRequestedRegion(); // We need all the input. InputImagePointer input = const_cast< InputImageType * >( this->GetInput() ); if ( !input ) { return; } input->SetRequestedRegion( input->GetLargestPossibleRegion() ); } template< class TInputImage, class TOutputImage > void MorphologicalWatershedImageFilter2< TInputImage, TOutputImage > ::EnlargeOutputRequestedRegion(DataObject *) { this->GetOutput() ->SetRequestedRegion( this->GetOutput()->GetLargestPossibleRegion() ); } template< class TInputImage, class TOutputImage > void MorphologicalWatershedImageFilter2< TInputImage, TOutputImage > ::GenerateData() { // Create a process accumulator for tracking the progress of this minipipeline ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); progress->SetMiniPipelineFilter(this); // Allocate the output this->AllocateOutputs(); // h-minima filter to remove the smallest minima typedef HMinimaImageFilter< TInputImage, TInputImage > HMinimaType; typename HMinimaType::Pointer hmin; // Delegate to a R-Min filter to find the regional minima typedef RegionalMinimaImageFilter< TInputImage, TOutputImage > RMinType; typename RMinType::Pointer rmin = RMinType::New(); rmin->SetInput( this->GetInput() ); rmin->SetFullyConnected(m_FullyConnected); rmin->SetBackgroundValue(NumericTraits< OutputImagePixelType >::Zero); rmin->SetForegroundValue( NumericTraits< OutputImagePixelType >::max() ); // label the components typedef ConnectedComponentImageFilter< TOutputImage, TOutputImage > ConnectedCompType; typename ConnectedCompType::Pointer label = ConnectedCompType::New(); label->SetFullyConnected(m_FullyConnected); label->SetInput( rmin->GetOutput() ); // the watershed typedef MorphologicalWatershedFromMarkersImageFilter2< TInputImage, TOutputImage > WatershedType; typename WatershedType::Pointer wshed = WatershedType::New(); wshed->SetInput( this->GetInput() ); wshed->SetMarkerImage( label->GetOutput() ); wshed->SetFullyConnected(m_FullyConnected); wshed->SetMarkWatershedLine(m_MarkWatershedLine); if ( m_ForegroundImg ) { wshed->SetForegroundImage (m_ForegroundImg); } if ( m_Level != NumericTraits< InputImagePixelType >::Zero ) { // insert a h-minima filter to remove the smallest minima // hmin = HMinimaType::New(); hmin->SetInput( this->GetInput() ); hmin->SetHeight(m_Level); hmin->SetFullyConnected(m_FullyConnected); // replace the input of the r-min filter rmin->SetInput( hmin->GetOutput() ); progress->RegisterInternalFilter(hmin, 0.4f); progress->RegisterInternalFilter(rmin, 0.1f); progress->RegisterInternalFilter(label, .2f); progress->RegisterInternalFilter(wshed, .3f); } else { // don't insert the h-minima to save some ressources progress->RegisterInternalFilter(rmin, 0.167f); progress->RegisterInternalFilter(label, .333f); progress->RegisterInternalFilter(wshed, .5f); } // run the algorithm // graft our output to the watershed filter to force the proper regions // to be generated wshed->GraftOutput( this->GetOutput() ); wshed->Update(); // graft the output of the watershed filter back onto this filter's // output. this is needed to get the appropriate regions passed // back. this->GraftOutput( wshed->GetOutput() ); } template< class TInputImage, class TOutputImage > void MorphologicalWatershedImageFilter2< TInputImage, TOutputImage > ::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "FullyConnected: " << m_FullyConnected << std::endl; os << indent << "MarkWatershedLine: " << m_MarkWatershedLine << std::endl; os << indent << "Level: " << static_cast< typename NumericTraits< InputImagePixelType >::PrintType >(m_Level) << std::endl; } } // end namespace itk #endifGoFigure2-v0.9.0/Code/Filters/CMakeLists.txt0000644000175000017500000000262111667757442020417 0ustar mathieumathieu# for the installation FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE( GLOB __source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/*.txx" ) FILE( GLOB __contour_source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/Contour/*.h" ) FILE( GLOB __contour_source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/Contour/*.txx" ) FILE( GLOB __mesh_source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/*.h" ) FILE( GLOB __mesh_source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/*.txx" ) FILE( GLOB __mesh_att_source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/Attributes/*.h" ) FILE( GLOB __mesh_att_source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/Attributes/*.txx" ) FILE( GLOB __mesh_split_source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/Split/*.h" ) FILE( GLOB __mesh_split_source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/Split/*.txx" ) FILE( GLOB __mesh_merge_source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/Merge/*.h" ) FILE( GLOB __mesh_merge_source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/Merge/*.txx" ) INSTALL( FILES ${__source_file_h} ${__source_file_txx} ${__contour_source_file_h} ${__contour_source_file_txx} ${__mesh_source_file_h} ${__mesh_source_file_txx} ${__mesh_att_source_file_h} ${__mesh_att_source_file_txx} ${__mesh_split_source_file_h} ${__mesh_split_source_file_txx} ${__mesh_merge_source_file_h} ${__mesh_merge_source_file_txx} DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Code/Filters/itkPreprocessImageFilter.h0000644000175000017500000001172711667757442023005 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkPreprocessImageFilter_h #define __itkPreprocessImageFilter_h #if defined( _MSC_VER ) #pragma warning ( disable : 4786 ) #endif #ifdef __BORLANDC__ #define ITK_LEAN_AND_MEAN #endif #include "itkImageToImageFilter.h" #include "itkCastImageFilter.h" #include "itkMedianImageFilter.h" #include "itkGrayscaleFillholeImageFilter.h" #include "itkRecursiveGaussianImageFilter.h" namespace itk { /** \class PreprocessImageFilter * \brief Denoise images - remove median noise and perform morphological * reconstruction. Makes it easier to segment and prevents formation of holes * in the segmentation. */ template< class TInputImage, class TOutputImage = TInputImage > class PreprocessImageFilter:public ImageToImageFilter< TInputImage, TOutputImage > { public: typedef PreprocessImageFilter Self; typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkStaticConstMacro (ImageDimension, unsigned int, TInputImage::ImageDimension); /** Method for creation through object factory */ itkNewMacro (Self); /** Run-time type information */ itkTypeMacro (PreprocessImageFilter, ImageToImageFilter); /** Display */ void PrintSelf(std::ostream & os, Indent indent) const; typedef Image< float, ImageDimension > ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::PixelType ImagePixelType; typedef typename ImageType::RegionType ImageRegionType; typedef typename ImageType::SizeType ImageSizeType; typedef typename ImageSizeType::SizeValueType ImageSizeValueType; typedef typename ImageType::SpacingType ImageSpacingType; typedef typename ImageType::IndexType ImageIndexType; typedef typename ImageType::PointType ImagePointType; typedef CastImageFilter< TInputImage, ImageType > InputCastType; typedef typename InputCastType::Pointer InputCastPointer; typedef MedianImageFilter< ImageType, ImageType > MedianFilterType; typedef typename MedianFilterType::Pointer MedianFilterPointer; typedef RecursiveGaussianImageFilter< ImageType, ImageType > SmoothingFilterType; typedef typename SmoothingFilterType::Pointer SmoothingFilterPointer; typedef GrayscaleFillholeImageFilter< ImageType, ImageType > GrayscaleFillholeFilterType; typedef typename GrayscaleFillholeFilterType::Pointer GrayscaleFillholePointer; typedef CastImageFilter< ImageType, TOutputImage > OutputCastType; typedef typename OutputCastType::Pointer OutputCastPointer; itkGetConstMacro (LargestCellRadius, double); itkSetMacro (LargestCellRadius, double); protected: PreprocessImageFilter(); ~PreprocessImageFilter() {} void GenerateData(); double m_LargestCellRadius; private: PreprocessImageFilter (Self &); // intentionally not implemented void operator=(const Self &); // intentionally not implemented }; } /* namespace itk */ #include "itkPreprocessImageFilter.txx" #endif GoFigure2-v0.9.0/Code/Filters/itkGradientWeightedDistanceImageFilter.txx0000644000175000017500000001513711667757442026144 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkGradientWeightedDistanceImageFilter_txx #define __itkGradientWeightedDistanceImageFilter_txx #include "itkGradientWeightedDistanceImageFilter.h" namespace itk { // Software Guide : BeginCodeSnippet template< class TFeatureImage, class TInputImage, class TSegmentImage > GradientWeightedDistanceImageFilter< TFeatureImage, TInputImage, TSegmentImage > ::GradientWeightedDistanceImageFilter() { m_UseLevelSet = true; m_LargestCellRadius = 5.0; m_NucleiSigma = 0.4; m_Alpha = 1; m_Beta = 3; m_ForegroundMap = NULL; m_DistanceMap = NULL; m_Gradient = NULL; this->Superclass::SetNumberOfRequiredInputs (1); this->Superclass::SetNumberOfRequiredOutputs (1); this->Superclass::SetNthOutput ( 0, TInputImage::New() ); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void GradientWeightedDistanceImageFilter< TFeatureImage, TInputImage, TSegmentImage > ::DistanceMap() { MaurerPointer m_Maurer = MaurerType::New(); m_Maurer->SetInput (m_ForegroundMap); m_Maurer->SetSquaredDistance (0); m_Maurer->SetUseImageSpacing (1); m_Maurer->SetInsideIsPositive (0); m_Maurer->Update(); ImagePointer image; if ( m_UseLevelSet ) { AbsFilterPointer m_absFilter = AbsFilterType::New(); m_absFilter->SetInput ( m_Maurer->GetOutput() ); m_absFilter->Update(); image = m_absFilter->GetOutput(); image->DisconnectPipeline(); } else { image = m_Maurer->GetOutput(); image->DisconnectPipeline(); } IteratorType It( image, image->GetLargestPossibleRegion() ); It.GoToBegin(); while ( !It.IsAtEnd() ) { if ( ( !m_UseLevelSet ) && ( It.Get() < 0 ) ) { It.Set(0); } if ( vcl_abs( It.Get() ) > m_LargestCellRadius ) { It.Set(m_LargestCellRadius); } ++It; } m_DistanceMap = image; } template< class TFeatureImage, class TInputImage, class TSegmentImage > void GradientWeightedDistanceImageFilter< TFeatureImage, TInputImage, TSegmentImage >::GenerateData() { DistanceMap(); ImagePointer outputImg; if ( m_Beta > 0 ) { MultiScaleLoGFilterPointer log = MultiScaleLoGFilterType::New(); log->SetInput( this->GetInput () ); log->SetSigmaMin(0.4); log->SetSigmaMax(2.0); log->SetNumberOfSigmaSteps(5); log->Update(); RescaleFilterPointer rescale = RescaleFilterType::New(); rescale->SetInput( log->GetOutput() ); rescale->SetOutputMinimum(0); rescale->SetOutputMaximum(1); rescale->Update(); outputImg = rescale->GetOutput(); outputImg->DisconnectPipeline(); } else { outputImg = ImageType::New(); outputImg->CopyInformation( this->GetInput() ); outputImg->SetRegions( this->GetInput()->GetLargestPossibleRegion() ); outputImg->Allocate(); outputImg->FillBuffer(1.0); } double gmax, gmin; // Compute the gradient magnitude if ( m_Alpha > 0 ) { GradientFilterPointer m_gradientMagnitude = GradientFilterType::New(); m_gradientMagnitude->SetInput ( this->GetInput () ); m_gradientMagnitude->SetSigma (m_NucleiSigma); m_gradientMagnitude->Update(); m_Gradient = m_gradientMagnitude->GetOutput(); m_Gradient->DisconnectPipeline(); MinMaxCalculatorPointer minMax3 = MinMaxCalculatorType::New(); minMax3->SetImage(m_Gradient); minMax3->ComputeMaximum(); gmax = static_cast< double >( minMax3->GetMaximum() ); MinMaxCalculatorPointer minMax4 = MinMaxCalculatorType::New(); minMax4->SetImage(m_Gradient); minMax4->ComputeMinimum(); gmin = static_cast< double >( minMax4->GetMinimum() ); } else { m_Gradient = outputImg; gmax = 1; gmin = 0; } std::cout << gmax << ' ' << gmin << std::endl; IteratorType It( outputImg, outputImg->GetLargestPossibleRegion() ); IteratorType dIt( m_DistanceMap, m_DistanceMap->GetLargestPossibleRegion() ); IteratorType gIt( m_Gradient, m_Gradient->GetLargestPossibleRegion() ); double p, q; gIt.GoToBegin(); dIt.GoToBegin(); It.GoToBegin(); while ( !It.IsAtEnd() ) { p = vcl_exp( m_Alpha * ( gmax - static_cast< double >( gIt.Get() ) ) / ( gmax - gmin ) ); q = vcl_exp( -m_Beta * static_cast< double >( It.Get() ) ); It.Set (dIt.Get() * p * q); ++gIt; ++dIt; ++It; } this->GraftOutput (outputImg); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void GradientWeightedDistanceImageFilter< TFeatureImage, TInputImage, TSegmentImage >::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf (os, indent); os << indent << "Class Name: " << this->GetNameOfClass() << std::endl; os << indent << "Use LevelSet: " << m_UseLevelSet << std::endl; } } /* end namespace itk */ #endifGoFigure2-v0.9.0/Code/Filters/Contour/0000755000175000017500000000000011667757442017307 5ustar mathieumathieuGoFigure2-v0.9.0/Code/Filters/Contour/ContourToMeshFilter.h0000644000175000017500000000545511667757442023410 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __ContourToMeshFilter_h #define __ContourToMeshFilter_h #include "itkLightObject.h" #include "itkObjectFactory.h" namespace itk { /** * \class ContourToMeshFilter * \brief */ template< class TContainer > class ContourToMeshFilter:public LightObject { public: typedef ContourToMeshFilter Self; typedef LightObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Method for creation through object factory */ itkNewMacro(Self); /** Run-time type information */ itkTypeMacro(ContourToMeshFilter, LightObject); typedef TContainer ContainerType; typedef typename ContainerType::const_iterator ContainerConstIterator; void ProcessContours(const ContainerType & iContainer); vtkPolyData * GetOutput(); protected: ContourToMeshFilter(); ~ContourToMeshFilter(); vtkPolyData *m_Output; vtkIdType m_ThresholdNumberOfPoints; int m_TargetNumberOfPoints; }; } #include "ContourToMeshFilter.txx" #endif GoFigure2-v0.9.0/Code/Filters/Contour/ContourToMeshFilter.txx0000644000175000017500000001240211667757442023772 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __ContourToMeshFilter_txx #define __ContourToMeshFilter_txx #include "vtkAppendPolyData.h" #include "vtkMath.h" #include "vtkSmartPointer.h" #include "vtkFloatArray.h" #include "vtkPointData.h" #include "vtkNormalEstimationFilter.h" #include "vtkPoissonReconstruction.h" #include "vtkPolyDataWriter.h" #include "vtkFillHolesFilter.h" #include "vtkPolylineDecimation.h" #include "vtkFeatureEdges.h" #include namespace itk { /** * \class ContourToMeshFilter * \brief */ template< class TContainer > ContourToMeshFilter< TContainer >::ContourToMeshFilter() : m_Output(NULL), m_ThresholdNumberOfPoints(20), m_TargetNumberOfPoints(20) { } template< class TContainer > ContourToMeshFilter< TContainer >::~ContourToMeshFilter() { } template< class TContainer > void ContourToMeshFilter< TContainer >::ProcessContours(const ContainerType & iContainer) { if ( iContainer.empty() ) { std::cerr << "error, no contours!" << std::endl; return; } else { vtkSmartPointer< vtkAppendPolyData > append = vtkSmartPointer< vtkAppendPolyData >::New(); // compute center of mass ContainerConstIterator it = iContainer.begin(); std::vector< vtkSmartPointer< vtkPolylineDecimation > > decimate( iContainer.size() ); size_t i = 0; while ( it != iContainer.end() ) { if ( ( *it ) ) { if ( ( *it )->GetNumberOfPoints() > m_ThresholdNumberOfPoints ) { decimate[i] = vtkSmartPointer< vtkPolylineDecimation >::New(); decimate[i]->SetInput(*it); decimate[i]->SetTargetReduction( 1. - static_cast< double >(m_TargetNumberOfPoints) / static_cast< double >( ( *it )->GetNumberOfPoints() ) ); decimate[i]->Update(); append->AddInputConnection( decimate[i]->GetOutputPort() ); } else { append->AddInput(*it); } } ++it; ++i; } vtkSmartPointer< vtkNormalEstimationFilter > normal_filter = vtkSmartPointer< vtkNormalEstimationFilter >::New(); normal_filter->SetInputConnection( append->GetOutputPort() ); normal_filter->Update(); // run the Poisson Reconstruction vtkSmartPointer< vtkPoissonReconstruction > poissonFilter = vtkSmartPointer< vtkPoissonReconstruction >::New(); poissonFilter->SetInputConnection( normal_filter->GetOutputPort() ); poissonFilter->SetDepth(12); poissonFilter->SetSolverDivide(12); poissonFilter->SetIsoDivide(12); poissonFilter->Update(); vtkSmartPointer< vtkFeatureEdges > feature = vtkSmartPointer< vtkFeatureEdges >::New(); feature->SetInputConnection( poissonFilter->GetOutputPort() ); feature->BoundaryEdgesOn(); feature->FeatureEdgesOff(); feature->NonManifoldEdgesOff(); feature->ManifoldEdgesOff(); feature->Update(); vtkSmartPointer< vtkFillHolesFilter > fillFilter = vtkSmartPointer< vtkFillHolesFilter >::New(); if ( !m_Output ) { m_Output = vtkPolyData::New(); } if ( feature->GetOutput()->GetNumberOfCells() > 0 ) { fillFilter->SetInputConnection( poissonFilter->GetOutputPort() ); fillFilter->Update(); m_Output->DeepCopy( fillFilter->GetOutput() ); } else { m_Output->DeepCopy( poissonFilter->GetOutput() ); } } } template< class TContainer > vtkPolyData * ContourToMeshFilter< TContainer >::GetOutput() { return m_Output; } } #endif GoFigure2-v0.9.0/Code/Filters/itkMorphologicalWatershedFromMarkersImageFilter2.txx0000644000175000017500000004547311667757442030162 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkMorphologicalWatershedFromMarkersImageFilter2.txx,v $ Language: C++ Date: $Date: 2008-02-07 15:07:57 $ Version: $Revision: 1.2 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkMorphologicalWatershedFromMarkersImageFilter2_txx #define __itkMorphologicalWatershedFromMarkersImageFilter2_txx #include #include #include #include "itkMorphologicalWatershedFromMarkersImageFilter2.h" #include "itkProgressReporter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkShapedNeighborhoodIterator.h" #include "itkConstShapedNeighborhoodIterator.h" #include "itkConstantBoundaryCondition.h" #include "itkSize.h" #include "itkConnectedComponentAlgorithm.h" // #include "itkFillSides.h" namespace itk { template< class TInputImage, class TLabelImage > MorphologicalWatershedFromMarkersImageFilter2< TInputImage, TLabelImage > ::MorphologicalWatershedFromMarkersImageFilter2() { this->SetNumberOfRequiredInputs(2); m_FullyConnected = false; m_MarkWatershedLine = true; m_ForegroundImg = 0; } template< class TInputImage, class TLabelImage > void MorphologicalWatershedFromMarkersImageFilter2< TInputImage, TLabelImage > ::GenerateInputRequestedRegion() { // call the superclass' implementation of this method Superclass::GenerateInputRequestedRegion(); // get pointers to the inputs LabelImagePointer markerPtr = const_cast< LabelImageType * >( this->GetMarkerImage() ); InputImagePointer inputPtr = const_cast< InputImageType * >( this->GetInput() ); if ( !markerPtr || !inputPtr ) { return; } // We need to // configure the inputs such that all the data is available. // markerPtr->SetRequestedRegion( markerPtr->GetLargestPossibleRegion() ); inputPtr->SetRequestedRegion( inputPtr->GetLargestPossibleRegion() ); } template< class TInputImage, class TLabelImage > void MorphologicalWatershedFromMarkersImageFilter2< TInputImage, TLabelImage > ::EnlargeOutputRequestedRegion(DataObject *) { this->GetOutput()->SetRequestedRegion( this->GetOutput()->GetLargestPossibleRegion() ); } template< class TInputImage, class TLabelImage > void MorphologicalWatershedFromMarkersImageFilter2< TInputImage, TLabelImage > ::GenerateData() { // there is 2 possible cases: with or without watershed lines. // the algorithm with watershed lines is from Meyer // the algorithm without watershed lines is from beucher // The 2 algorithms are very similar and so are integrated in the same filter. //--------------------------------------------------------------------------- // declare the vars common to the 2 algorithms: constants, iterators, // hierarchical queue, progress reporter, and status image // also allocate output images and verify preconditions //--------------------------------------------------------------------------- // the label used to find background in the marker image static const LabelImagePixelType bgLabel = NumericTraits< LabelImagePixelType >::Zero; // the label used to mark the watershed line in the output image static const LabelImagePixelType wsLabel = NumericTraits< LabelImagePixelType >::Zero; this->AllocateOutputs(); if ( !m_ForegroundImg ) { m_ForegroundImg = LabelImageType::New(); m_ForegroundImg->CopyInformation( this->GetOutput() ); m_ForegroundImg->SetRegions( this->GetOutput()->GetLargestPossibleRegion() ); m_ForegroundImg->Allocate(); m_ForegroundImg->FillBuffer(1); } LabelImageConstPointer markerImage = this->GetMarkerImage(); InputImageConstPointer inputImage = this->GetInput(); LabelImagePointer outputImage = this->GetOutput(); // Set up the progress reporter // we can't found the exact number of pixel to process in the 2nd pass, so we // use the maximum number possible. ProgressReporter progress(this, 0, markerImage->GetRequestedRegion().GetNumberOfPixels() *2); // mask and marker must have the same size if ( markerImage->GetRequestedRegion().GetSize() != inputImage->GetRequestedRegion().GetSize() ) { itkExceptionMacro(<< "Marker and input must have the same size."); } // FAH (in french: File d'Attente Hierarchique) typedef std::queue< IndexType > QueueType; typedef std::map< InputImagePixelType, QueueType > MapType; MapType fah; // the radius which will be used for all the shaped iterators Size< ImageDimension > radius; radius.Fill(1); // iterator for the marker image typedef ConstShapedNeighborhoodIterator< LabelImageType > MarkerIteratorType; typename MarkerIteratorType::ConstIterator nmIt; MarkerIteratorType markerIt( radius, markerImage, markerImage->GetRequestedRegion() ); typedef ShapedNeighborhoodIterator< LabelImageType > ForegroundIteratorType; typename ForegroundIteratorType::Iterator fgIt; ForegroundIteratorType foregroundIt( radius, m_ForegroundImg, m_ForegroundImg->GetRequestedRegion() ); // add a boundary constant to avoid adding pixels on the border in the fah ConstantBoundaryCondition< LabelImageType > lcbc; lcbc.SetConstant( NumericTraits< LabelImagePixelType >::max() ); markerIt.OverrideBoundaryCondition(&lcbc); setConnectivity(&markerIt, m_FullyConnected); foregroundIt.OverrideBoundaryCondition(&lcbc); setConnectivity(&foregroundIt, m_FullyConnected); // iterator for the input image typedef ConstShapedNeighborhoodIterator< InputImageType > InputIteratorType; InputIteratorType inputIt( radius, inputImage, inputImage->GetRequestedRegion() ); typename InputIteratorType::ConstIterator niIt; setConnectivity(&inputIt, m_FullyConnected); // iterator for the output image typedef ShapedNeighborhoodIterator< LabelImageType > OutputIteratorType; typedef typename OutputIteratorType::OffsetType OffsetType; typename OutputIteratorType::Iterator noIt; OutputIteratorType outputIt( radius, outputImage, outputImage->GetRequestedRegion() ); setConnectivity(&outputIt, m_FullyConnected); //--------------------------------------------------------------------------- // Meyer's algorithm //--------------------------------------------------------------------------- if ( m_MarkWatershedLine ) { // first stage: // - set markers pixels to already processed status // - copy markers pixels to output image // - init FAH with indexes of background pixels with marker pixel(s) in // their neighborhood ConstantBoundaryCondition< LabelImageType > lcbc2; // outside pixel are watershed so they won't be use to find real watershed // pixels lcbc2.SetConstant(wsLabel); outputIt.OverrideBoundaryCondition(&lcbc2); // create a temporary image to store the state of each pixel (processed or // not) typedef Image< bool, ImageDimension > StatusImageType; typename StatusImageType::Pointer statusImage = StatusImageType::New(); statusImage->SetRegions( markerImage->GetLargestPossibleRegion() ); statusImage->Allocate(); // iterator for the status image typedef ShapedNeighborhoodIterator< StatusImageType > StatusIteratorType; typename StatusIteratorType::Iterator nsIt; StatusIteratorType statusIt( radius, statusImage, outputImage->GetRequestedRegion() ); ConstantBoundaryCondition< StatusImageType > bcbc; bcbc.SetConstant(true); // outside pixel are already processed statusIt.OverrideBoundaryCondition(&bcbc); setConnectivity(&statusIt, m_FullyConnected); // the status image must be initialized before the first stage. In the // first stage, the set to true are the neighbors of the marker (and the // marker) so it's difficult (impossible ?) to init the status image at // the same time // the overhead should be small statusImage->FillBuffer(false); for ( markerIt.GoToBegin(), statusIt.GoToBegin(), outputIt.GoToBegin(), inputIt.GoToBegin(); !markerIt.IsAtEnd(); ++markerIt, ++outputIt ) { LabelImagePixelType markerPixel = markerIt.GetCenterPixel(); if ( markerPixel != bgLabel ) { IndexType idx = markerIt.GetIndex(); // move the iterators to the right place OffsetType shift = idx - statusIt.GetIndex(); statusIt += shift; inputIt += shift; // this pixel belongs to a marker // mark it as already processed statusIt.SetCenterPixel(true); // copy it to the output image outputIt.SetCenterPixel(markerPixel); // and increase progress because this pixel will not be used in the // flooding stage. progress.CompletedPixel(); // search the background pixels in the neighborhood for ( nmIt = markerIt.Begin(), nsIt = statusIt.Begin(), niIt = inputIt.Begin(); nmIt != markerIt.End(); nmIt++, nsIt++, niIt++ ) { if ( !nsIt.Get() && nmIt.Get() == bgLabel ) { // this neighbor is a background pixel and is not already // processed; add its index to fah fah[niIt.Get()].push( markerIt.GetIndex() + nmIt.GetNeighborhoodOffset() ); // mark it as already in the fah to avoid adding it several times nsIt.Set(true); } } } else { // Some pixels may be never processed so, by default, non marked pixels // must be marked as watershed outputIt.SetCenterPixel(wsLabel); } // one more pixel done in the init stage progress.CompletedPixel(); } // fill the borders of the status image with "true" //FillSides(statusImage, true); // Now disable the boundary checks //outputIt.NeedToUseBoundaryConditionOff(); //statusIt.NeedToUseBoundaryConditionOff(); //inputIt.NeedToUseBoundaryConditionOff(); // end of init stage // flooding // init all the iterators outputIt.GoToBegin(); statusIt.GoToBegin(); inputIt.GoToBegin(); // and start flooding while ( !fah.empty() ) { // store the current vars InputImagePixelType currentValue = fah.begin()->first; QueueType currentQueue = fah.begin()->second; // and remove them from the fah fah.erase( fah.begin() ); while ( !currentQueue.empty() ) { IndexType idx = currentQueue.front(); currentQueue.pop(); // move the iterators to the right place OffsetType shift = idx - outputIt.GetIndex(); outputIt += shift; statusIt += shift; inputIt += shift; // iterate over the neighbors. If there is only one marker value, give // that value to the pixel, else keep it as is (watershed line) LabelImagePixelType marker = wsLabel; bool collision = false; for ( noIt = outputIt.Begin(); noIt != outputIt.End(); noIt++ ) { LabelImagePixelType o = noIt.Get(); if ( o != wsLabel ) { if ( marker != wsLabel && o != marker ) { collision = true; break; } else { marker = o; } } } if ( !collision ) { // set the marker value outputIt.SetCenterPixel(marker); // and propagate to the neighbors for ( niIt = inputIt.Begin(), nsIt = statusIt.Begin(); niIt != inputIt.End(); niIt++, nsIt++ ) { if ( !nsIt.Get() ) { // the pixel is not yet processed. add it to the fah InputImagePixelType GrayVal = niIt.Get(); if ( GrayVal <= currentValue ) { currentQueue.push( inputIt.GetIndex() + niIt.GetNeighborhoodOffset() ); } else { fah[GrayVal].push( inputIt.GetIndex() + niIt.GetNeighborhoodOffset() ); } // mark it as already in the fah nsIt.Set(true); } } } // one more pixel in the flooding stage progress.CompletedPixel(); } } } //--------------------------------------------------------------------------- // Beucher's algorithm //--------------------------------------------------------------------------- else { // first stage: // - copy markers pixels to output image // - init FAH with indexes of pixels with background pixel in their // neighborhood ConstantBoundaryCondition< LabelImageType > lcbc2; // outside pixel are watershed so they won't be use to find real watershed // pixels lcbc2.SetConstant( NumericTraits< LabelImagePixelType >::max() ); outputIt.OverrideBoundaryCondition(&lcbc2); foregroundIt.GoToBegin(); for ( markerIt.GoToBegin(), outputIt.GoToBegin(), inputIt.GoToBegin(); !markerIt.IsAtEnd(); ++markerIt, ++outputIt ) { LabelImagePixelType markerPixel = markerIt.GetCenterPixel(); LabelImagePixelType fgPixel = foregroundIt.GetCenterPixel(); if ( ( markerPixel != bgLabel ) && ( fgPixel > 0 ) ) { IndexType idx = markerIt.GetIndex(); OffsetType shift = idx - inputIt.GetIndex(); inputIt += shift; // this pixels belongs to a marker // copy it to the output image outputIt.SetCenterPixel(markerPixel); // search if it has background pixel in its neighborhood bool haveBgNeighbor = false; fgIt = foregroundIt.Begin(); for ( nmIt = markerIt.Begin(); nmIt != markerIt.End(); nmIt++ ) { // check for the m_Foreground pixel only if ( ( nmIt.Get() == bgLabel ) && ( fgIt.Get() > 0 ) ) { haveBgNeighbor = true; break; } fgIt++; } if ( haveBgNeighbor ) { // there is a background pixel in the neighborhood; add to fah fah[inputIt.GetCenterPixel()].push( markerIt.GetIndex() ); } else { // increase progress because this pixel will not be used in the // flooding stage. progress.CompletedPixel(); } } else { outputIt.SetCenterPixel(wsLabel); } progress.CompletedPixel(); ++foregroundIt; } // end of init stage // flooding // init all the iterators outputIt.GoToBegin(); inputIt.GoToBegin(); foregroundIt.GoToBegin(); // and start flooding while ( !fah.empty() ) { // store the current vars InputImagePixelType currentValue = fah.begin()->first; QueueType currentQueue = fah.begin()->second; // and remove them from the fah fah.erase( fah.begin() ); while ( !currentQueue.empty() ) { IndexType idx = currentQueue.front(); currentQueue.pop(); // move the iterators to the right place OffsetType shift = idx - outputIt.GetIndex(); outputIt += shift; inputIt += shift; foregroundIt += shift; LabelImagePixelType currentMarker = outputIt.GetCenterPixel(); // get the current value of the pixel // iterate over neighbors to propagate the marker fgIt = foregroundIt.Begin(); for ( noIt = outputIt.Begin(), niIt = inputIt.Begin(); noIt != outputIt.End(); noIt++, niIt++, fgIt++ ) { if ( ( noIt.Get() == wsLabel ) && ( fgIt.Get() ) ) { // the pixel is not yet processed. It can be labeled with the // current label noIt.Set(currentMarker); InputImagePixelType GrayVal = niIt.Get(); if ( GrayVal <= currentValue ) { currentQueue.push( inputIt.GetIndex() + noIt.GetNeighborhoodOffset() ); } else { fah[GrayVal].push( inputIt.GetIndex() + noIt.GetNeighborhoodOffset() ); } progress.CompletedPixel(); } } } } } } template< class TInputImage, class TLabelImage > void MorphologicalWatershedFromMarkersImageFilter2< TInputImage, TLabelImage > ::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "FullyConnected: " << m_FullyConnected << std::endl; os << indent << "MarkWatershedLine: " << m_MarkWatershedLine << std::endl; } } // end namespace itk #endifGoFigure2-v0.9.0/Code/Filters/itkGradientWeightedDistanceImageFilter.h0000644000175000017500000002001311667757442025535 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkGradientWeightedDistanceImageFilter_h #define __itkGradientWeightedDistanceImageFilter_h #if defined( _MSC_VER ) #pragma warning ( disable : 4786 ) #endif #ifdef __BORLANDC__ #define ITK_LEAN_AND_MEAN #endif #include "itkImageToImageFilter.h" #include "itkGradientMagnitudeRecursiveGaussianImageFilter.h" #include "itkSigmoidImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkSignedMaurerDistanceMapImageFilter.h" #include "itkMultiScaleLoGImageFilter.h" #include "itkRescaleIntensityImageFilter.h" #include "itkAbsImageFilter.h" #include "itkThresholdImageFilter.h" #include "itkMinimumMaximumImageCalculator.h" #include "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" #include "itkImageRegion.h" #include "itkRegion.h" #include "itkIndex.h" #include "itkSize.h" #include "itkImageFileWriter.h" namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > class GradientWeightedDistanceImageFilter: public ImageToImageFilter< TFeatureImage, TInputImage > { public: typedef GradientWeightedDistanceImageFilter Self; typedef ImageToImageFilter< TFeatureImage, TInputImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkStaticConstMacro (ImageDimension, unsigned int, TFeatureImage::ImageDimension); /** Method for creation through object factory */ itkNewMacro (Self); /** Run-time type information */ itkTypeMacro (GradientWeightedDistanceImageFilter, ImageToImageFilter); /** Display */ void PrintSelf(std::ostream & os, Indent indent) const; typedef TFeatureImage FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef typename FeatureImageType::ConstPointer FeatureImageConstPointer; typedef typename FeatureImageType::PixelType FeatureImagePixelType; typedef typename FeatureImageType::RegionType FeatureImageRegionType; typedef typename FeatureImageType::SizeType FeatureImageSizeType; typedef typename FeatureImageSizeType::SizeValueType FeatureImageSizeValueType; typedef typename FeatureImageType::SpacingType FeatureImageSpacingType; typedef typename FeatureImageType::IndexType FeatureImageIndexType; typedef typename FeatureImageType::PointType FeatureImagePointType; typedef TInputImage ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::PixelType ImagePixelType; typedef typename ImageType::RegionType ImageRegionType; typedef typename ImageType::SizeType ImageSizeType; typedef typename ImageSizeType::SizeValueType ImageSizeValueType; typedef typename ImageType::SpacingType ImageSpacingType; typedef typename ImageType::IndexType ImageIndexType; typedef typename ImageType::PointType ImagePointType; typedef TSegmentImage SegmentImageType; typedef typename SegmentImageType::Pointer SegmentImagePointer; typedef typename SegmentImageType::ConstPointer SegmentImageConstPointer; typedef typename SegmentImageType::IndexType SegmentImageIndexType; typedef typename SegmentImageType::PixelType SegmentImagePixelType; typedef MultiScaleLoGImageFilter< FeatureImageType, ImageType > MultiScaleLoGFilterType; typedef typename MultiScaleLoGFilterType::Pointer MultiScaleLoGFilterPointer; typedef RescaleIntensityImageFilter< ImageType, ImageType > RescaleFilterType; typedef typename RescaleFilterType::Pointer RescaleFilterPointer; typedef GradientMagnitudeRecursiveGaussianImageFilter< FeatureImageType, ImageType > GradientFilterType; typedef typename GradientFilterType::Pointer GradientFilterPointer; typedef SigmoidImageFilter< ImageType, ImageType > SigmoidFilterType; typedef typename SigmoidFilterType::Pointer SigmoidFilterPointer; typedef AbsImageFilter< ImageType, ImageType > AbsFilterType; typedef typename AbsFilterType::Pointer AbsFilterPointer; typedef ThresholdImageFilter< ImageType > ThreshFilterType; typedef typename ThreshFilterType::Pointer ThreshFilterPointer; typedef ImageRegionConstIterator< FeatureImageType > ConstIteratorType; typedef ImageRegionIterator< ImageType > IteratorType; typedef ImageRegionIteratorWithIndex< ImageType > IndexIteratorType; typedef SignedMaurerDistanceMapImageFilter< SegmentImageType, ImageType > MaurerType; typedef typename MaurerType::Pointer MaurerPointer; typedef MinimumMaximumImageCalculator< ImageType > MinMaxCalculatorType; typedef typename MinMaxCalculatorType::Pointer MinMaxCalculatorPointer; typedef MinimumMaximumImageCalculator< FeatureImageType > FeatureMinMaxCalculatorType; typedef typename FeatureMinMaxCalculatorType::Pointer FeatureMinMaxCalculatorPointer; itkGetConstMacro (UseLevelSet, bool); itkSetMacro (UseLevelSet, bool); itkGetConstMacro (LargestCellRadius, double); itkSetMacro (LargestCellRadius, double); itkGetConstMacro (NucleiSigma, double); itkSetMacro (NucleiSigma, double); itkGetConstMacro (Alpha, double); itkSetMacro (Alpha, double); itkGetConstMacro (Beta, double); itkSetMacro (Beta, double); void SetForeground(SegmentImagePointer fg) { m_ForegroundMap = fg; } ImagePointer GetDistanceMap() { return m_DistanceMap; } ImagePointer GetGradient() { return m_Gradient; } protected: GradientWeightedDistanceImageFilter(); ~GradientWeightedDistanceImageFilter() {} void DistanceMap(); void Normalize(); void GenerateData(); bool m_UseLevelSet; double m_LargestCellRadius; double m_NucleiSigma; double m_Alpha; double m_Beta; SegmentImagePointer m_ForegroundMap; ImagePointer m_DistanceMap; ImagePointer m_Gradient; private: GradientWeightedDistanceImageFilter (Self &); // intentionally not implemented void operator=(const Self &); // intentionally not implemented }; } /* namespace itk */ #include "itkGradientWeightedDistanceImageFilter.txx" #endif GoFigure2-v0.9.0/Code/Filters/itkMultiScaleLoGImageFilter.h0000644000175000017500000001231411667757442023315 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkMultiScaleLoGImageFilter.h,v $ Language: C++ Date: $Date: 2007/04/01 23:13:46 $ Version: $Revision: 1.6 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkMultiScaleLoGImageFilter_h #define __itkMultiScaleLoGImageFilter_h #include "itkImageToImageFilter.h" #include "itkImage.h" #include "itkMatrix.h" #include #include "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" namespace itk { /**\class MultiScaleLoGImageFilter * \brief A filter to enhance 3D blob structures using LoG filter */ template< class TInputImage, class TOutputImage = TInputImage > class MultiScaleLoGImageFilter: public ImageToImageFilter< TInputImage, TOutputImage > { public: /** Standard class typedefs. */ typedef MultiScaleLoGImageFilter Self; typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; typedef TInputImage InputImageType; typedef typename InputImageType::Pointer InputImagePointer; typedef typename InputImageType::ConstPointer InputImageConstPointer; typedef typename InputImageType::PixelType InputPixelType; typedef TOutputImage OutputImageType; typedef typename OutputImageType::Pointer OutputImagePointer; typedef typename OutputImageType::PixelType OutputPixelType; /** Image dimension = 3. */ itkStaticConstMacro(ImageDimension, unsigned int, ::itk::GetImageDimension< InputImageType >::ImageDimension); /** Update image buffer that holds the best laplacian response */ typedef LaplacianRecursiveGaussianImageFilter< InputImageType, OutputImageType > LaplacianFilterType; typedef typename LaplacianFilterType::Pointer LaplacianFilterPointer; typedef ImageRegionIterator< OutputImageType > IteratorType; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Set/Get macros for Alpha */ itkSetMacro(SigmaMin, double); itkGetMacro(SigmaMin, double); /** Set/Get macros for Beta */ itkSetMacro(SigmaMax, double); itkGetMacro(SigmaMax, double); /** Set/Get macros for Number of Scales */ itkSetMacro(NumberOfSigmaSteps, int); itkGetMacro(NumberOfSigmaSteps, int); protected: MultiScaleLoGImageFilter(); ~MultiScaleLoGImageFilter() {} void PrintSelf(std::ostream & os, Indent indent) const; void GenerateData(void); private: void UpdateMaximumResponse(); double ComputeSigmaValue(int scaleLevel); //purposely not implemented MultiScaleLoGImageFilter(const Self &); void operator=(const Self &); //purposely not implemented double m_SigmaMin; double m_SigmaMax; int m_NumberOfSigmaSteps; LaplacianFilterPointer m_LaplacianFilter; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkMultiScaleLoGImageFilter.txx" #endif #endif GoFigure2-v0.9.0/Code/Filters/Mesh/0000755000175000017500000000000011667757442016552 5ustar mathieumathieuGoFigure2-v0.9.0/Code/Filters/Mesh/itkvtkMeshFilterBase.txx0000644000175000017500000001205511667757442023414 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshFilterBase_txx #define __itkvtkMeshFilterBase_txx #include "itkvtkMeshFilterBase.h" namespace itk { template< class TFeatureImage > vtkMeshFilterBase< TFeatureImage >:: vtkMeshFilterBase() : Superclass(), m_ShapeComputation( false ), m_IntensityComputation( false ) { } template< class TFeatureImage > void vtkMeshFilterBase< TFeatureImage >:: SetNumberOfImages( const size_t& iN ) { m_Images.resize( iN ); } template< class TFeatureImage > void vtkMeshFilterBase< TFeatureImage >:: SetFeatureImage( const size_t& iId, FeatureImageType* iImage ) { if( iId < m_Images.size() ) { m_Images[iId] = iImage; this->Modified(); } } template< class TFeatureImage > void vtkMeshFilterBase< TFeatureImage >:: Update() { this->GenerateData(); this->ComputeOutputAttributes(); } template< class TFeatureImage > void vtkMeshFilterBase< TFeatureImage >:: ComputeOutputAttributes() { if( m_ShapeComputation || m_IntensityComputation ) { std::vector< vtkPolyData* >::iterator it = m_Outputs.begin(); std::vector< vtkPolyData* >::iterator end = m_Outputs.end(); typename MeshToLabelFilterType::MeshVectorType mesh_vector( m_Outputs.size() ); size_t i = 0; while( it != end ) { MeshConverterPointer converter = MeshConverterType::New(); converter->SetInput( *it ); converter->Update(); mesh_vector[i] = converter->GetOutput(); mesh_vector[i]->DisconnectPipeline(); ++i; ++it; } FeatureImagePointer image = FeatureImageType::New(); image->CopyInformation( this->m_Images.front() ); image->SetRegions( this->m_Images.front()->GetLargestPossibleRegion() ); image->Allocate(); image->FillBuffer( 0 ); typename MeshToLabelFilterType::Pointer labelizer = MeshToLabelFilterType::New(); labelizer->SetInput( image ); labelizer->SetMeshes( mesh_vector ); labelizer->Update(); if( m_ShapeComputation ) { ShapeConverterPointer shapeConverter = ShapeConverterType::New(); shapeConverter->SetInput( image ); shapeConverter->SetBackgroundValue ( 0 ); shapeConverter->Update(); m_ShapeLabelMap = shapeConverter->GetOutput(); m_ShapeLabelMap->DisconnectPipeline(); } if( m_IntensityComputation ) { size_t NumberOfFeatureImages = m_Images.size(); m_StatLabelMap.resize( NumberOfFeatureImages ); typename std::vector< FeatureImagePointer >::iterator f_it = m_Images.begin(); typename std::vector< FeatureImagePointer >::iterator f_end = m_Images.end(); i = 0; while( f_it != f_end ) { StatConverterPointer statConverter = StatConverterType::New(); statConverter->SetInput( image ); statConverter->SetFeatureImage( *f_it ); statConverter->SetBackgroundValue( 0 ); statConverter->SetComputePerimeter(false); try { statConverter->Update(); } catch(itk::ExceptionObject & e) { std::cerr << "Exception Caught: " << e << std::endl; std::cerr << "statConverter->Update()" << std::endl; return; } m_StatLabelMap[i] = statConverter->GetOutput(); m_StatLabelMap[i]->DisconnectPipeline(); ++i; ++f_it; } } } } } #endif GoFigure2-v0.9.0/Code/Filters/Mesh/itkvtkMeshFilterBase.h0000644000175000017500000001377711667757442023034 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshFilterBase_h #define __itkvtkMeshFilterBase_h #include "itkObject.h" #include "itkConvertMeshesToLabelImageFilter.h" #include "itkvtkPolyDataToitkQuadEdgeMesh.h" #include "itkShapeLabelObject.h" #include "itkLabelMap.h" #include "itkLabelImageToShapeLabelMapFilter.h" #include "itkLabelImageToStatisticsLabelMapFilter.h" namespace itk { template< class TFeatureImage > class vtkMeshFilterBase : public Object { public: typedef Object Superclass; typedef vtkMeshFilterBase Self; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro( vtkMeshFilterBase, Object ); typedef TFeatureImage FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef typename FeatureImageType::PixelType FeatureImagePixelType; typedef typename FeatureImageType::IndexType FeatureImageIndexType; typedef typename FeatureImageType::PointType FeatureImagePointType; typedef ConvertMeshesToLabelImageFilter< FeatureImageType > MeshToLabelFilterType; typedef typename MeshToLabelFilterType::Pointer MeshToLabelFilterPointer; typedef typename MeshToLabelFilterType::MeshType QuadEdgeMeshType; typedef vtkPolyDataToitkQuadEdgeMesh< QuadEdgeMeshType > MeshConverterType; typedef typename MeshConverterType::Pointer MeshConverterPointer; // --------------------------------------------------------------------------- /** \typedef LabelType label type*/ typedef unsigned int LabelType; // --------------------------------------------------------------------------- /** \typedef ShapeLabelObjectType */ typedef ShapeLabelObject< LabelType, FeatureImageType::ImageDimension > ShapeLabelObjectType; typedef typename ShapeLabelObjectType::Pointer ShapeLabelObjectPointer; /** \typedef ShapeLabelMapType */ typedef LabelMap< ShapeLabelObjectType > ShapeLabelMapType; typedef typename ShapeLabelMapType::Pointer ShapeLabelMapPointer; /** \typedef ShapeConverterType */ typedef LabelImageToShapeLabelMapFilter< FeatureImageType, ShapeLabelMapType > ShapeConverterType; typedef typename ShapeConverterType::Pointer ShapeConverterPointer; typedef typename ShapeLabelMapType::LabelObjectContainerType LabelObjectContainerType; typedef typename LabelObjectContainerType::const_iterator LabelObjectIterator; // --------------------------------------------------------------------------- /** \typedef StatLabelObjectType */ typedef StatisticsLabelObject< LabelType, FeatureImageType::ImageDimension > StatLabelObjectType; typedef typename StatLabelObjectType::Pointer StatLabelObjectPointer; typedef LabelMap< StatLabelObjectType > StatLabelMapType; typedef typename StatLabelMapType::Pointer StatLabelMapPointer; typedef LabelImageToStatisticsLabelMapFilter< FeatureImageType, FeatureImageType, StatLabelMapType > StatConverterType; typedef typename StatConverterType::Pointer StatConverterPointer; // --------------------------------------------------------------------------- void SetNumberOfImages( const size_t& iN ); void SetFeatureImage( const size_t& iId, FeatureImageType* iImage ); void Update(); protected: vtkMeshFilterBase(); virtual ~vtkMeshFilterBase() {} virtual void GenerateData() = 0; virtual void SetRequiredAttributeComputationFlags() = 0; void ComputeOutputAttributes(); std::vector< FeatureImagePointer > m_Images; std::vector< vtkPolyData* > m_Outputs; ShapeLabelMapPointer m_ShapeLabelMap; std::vector< StatLabelMapPointer > m_StatLabelMap; std::map< size_t, LabelType > m_MeshtoLabelIdMap; bool m_ShapeComputation; bool m_IntensityComputation; private: vtkMeshFilterBase( const Self& ); void operator = ( const Self& ); }; } #include "itkvtkMeshFilterBase.txx" #endif GoFigure2-v0.9.0/Code/Filters/Mesh/Split/0000755000175000017500000000000011667757442017645 5ustar mathieumathieuGoFigure2-v0.9.0/Code/Filters/Mesh/Split/itkvtkMeshSplitterImageFilterBase.txx0000644000175000017500000001525111667757442027202 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshSplitterImageFilterBase_txx #define __itkvtkMeshSplitterImageFilterBase_txx #include "itkvtkMeshSplitterImageFilterBase.h" #include "itkConvertMeshesToLabelImageFilter.h" #include "itkvtkPolyDataToitkQuadEdgeMesh.h" namespace itk { template< class TFeatureImage, class TPointSet > vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: vtkMeshSplitterImageFilterBase() : Superclass( ), m_Seeds( NULL ), m_NumberOfThreads( 1 ), m_NumberOfTrianglesPerMesh( 200 ), m_NumberOfSmoothingIterations( 8 ), m_SmoothingRelaxationFactor( 0.75 ), m_DelaunayConforming( false ), m_UseSmoothing( true ), m_UseDecimation( true ) { this->SetRequiredAttributeComputationFlags(); } template< class TFeatureImage, class TPointSet > void vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: SetSeeds( PointSetType* iSeeds ) { if( iSeeds ) { m_Seeds = iSeeds; this->Modified(); } } template< class TFeatureImage, class TPointSet > bool vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: CheckAllSeeds() const { PointsContainerPointer points = m_Seeds->GetPoints(); PointsContainerConstIterator it = points->Begin(); PointsContainerConstIterator end = points->End(); while( it != end ) { if( !this->IsPointInMeshBounds( it->Value() ) ) { std::cout << it->Value() << " is out of bounds" << std::endl; return false; } ++it; } return true; } template< class TFeatureImage, class TPointSet > void vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: ComputeBinaryImageFromInputMesh() { typedef ConvertMeshesToLabelImageFilter< FeatureImageType > MeshToLabelFilterType; typedef typename MeshToLabelFilterType::Pointer MeshToLabelFilterPointer; typedef typename MeshToLabelFilterType::MeshType MeshType; typedef vtkPolyDataToitkQuadEdgeMesh< MeshType > MeshConverterType; typedef typename MeshConverterType::Pointer MeshConverterPointer; MeshConverterPointer converter = MeshConverterType::New(); converter->SetInput( this->m_Mesh ); converter->Update(); typename MeshToLabelFilterType::MeshVectorType mesh_vector( 1 ); mesh_vector[0] = converter->GetOutput(); m_BinaryImage = FeatureImageType::New(); m_BinaryImage->CopyInformation( this->m_Images.front() ); m_BinaryImage->SetRegions( this->m_Images.front()->GetLargestPossibleRegion() ); m_BinaryImage->Allocate(); m_BinaryImage->FillBuffer( 0 ); typename MeshToLabelFilterType::Pointer binarizer = MeshToLabelFilterType::New(); binarizer->SetInput( m_BinaryImage ); binarizer->SetMeshes( mesh_vector ); binarizer->Update(); } template< class TFeatureImage, class TPointSet > void vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: Split() { if( m_Seeds.IsNull() ) { itkGenericExceptionMacro( << "m_Seeds is NULL" ); } if( !CheckAllSeeds() ) { itkGenericExceptionMacro( <<"Out of bounds" ); } ComputeBinaryImageFromInputMesh(); this->SplitBinaryImage(); GenerateMeshesFromOutputImage(); } template< class TFeatureImage, class TPointSet > void vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: GenerateMeshesFromOutputImage() { ExtracMeshFilterPointer extractor = ExtracMeshFilterType::New(); extractor->SetInput( m_OutputImage ); size_t i = 0; size_t NumberOfImages = this->m_Images.size(); extractor->SetNumberOfFeatureImages( NumberOfImages ); for( ; i < NumberOfImages; ++i ) { extractor->SetFeatureImage( i, this->m_Images[i] ); } extractor->SetNumberOfThreads( m_NumberOfThreads ); extractor->SetUseSmoothing( m_UseSmoothing ); extractor->SetUseDecimation( m_UseDecimation ); extractor->SetNumberOfTrianglesPerMesh( m_NumberOfTrianglesPerMesh ); extractor->SetNumberOfSmoothingIterations( m_NumberOfSmoothingIterations ); extractor->SetSmoothingRelaxationFactor( m_SmoothingRelaxationFactor ); extractor->SetDelaunayConforming( m_DelaunayConforming ); extractor->Update(); this->m_ShapeLabelMap = extractor->GetShapeLabelMap(); this->m_StatLabelMap = extractor->GetStatLabelMap(); typedef typename ExtracMeshFilterType::MeshVectorType MeshVectorType; MeshVectorType MeshVector = extractor->GetOutputs(); typename MeshVectorType::const_iterator it = MeshVector.begin(); typename MeshVectorType::const_iterator end = MeshVector.end(); this->m_Outputs.resize( MeshVector.size() ); i = 0; while( it != end ) { ITKVTKMeshConverterPointer converter = ITKVTKMeshConverterType::New(); converter->SetInput( *it ); converter->Update(); this->m_Outputs[i] = vtkPolyData::New(); this->m_Outputs[i]->DeepCopy( converter->GetOutput() ); ++it; ++i; } } template< class TFeatureImage, class TPointSet > void vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: SetRequiredAttributeComputationFlags() { this->m_ShapeComputation = false; this->m_IntensityComputation = false; } } #endif // __itkvtkMeshSplitterImageFilterBase_txx GoFigure2-v0.9.0/Code/Filters/Mesh/Split/itkvtkMeshSplitterDanielssonDistanceImageFilter.txx0000644000175000017500000000777611667757442032117 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshSplitterDanielssonDistanceImageFilter_txx #define __itkvtkMeshSplitterDanielssonDistanceImageFilter_txx #include "itkvtkMeshSplitterDanielssonDistanceImageFilter.h" #include namespace itk { template< class TFeatureImage, class TPointSet > vtkMeshSplitterDanielssonDistanceImageFilter< TFeatureImage, TPointSet >:: vtkMeshSplitterDanielssonDistanceImageFilter() : Superclass() {} template< class TFeatureImage, class TPointSet > void vtkMeshSplitterDanielssonDistanceImageFilter< TFeatureImage, TPointSet >:: SplitBinaryImage() { FeatureImagePixelType zero = NumericTraits< FeatureImagePixelType >::Zero; FeatureImagePointer seed_image = FeatureImageType::New(); seed_image->SetRegions( this->m_BinaryImage->GetLargestPossibleRegion() ); seed_image->CopyInformation(this->m_BinaryImage); seed_image->Allocate(); seed_image->FillBuffer( zero ); // Fill the seeds FeatureImageIndexType index; FeatureImagePointType pt; PointsContainerPointer points = this->m_Seeds->GetPoints(); PointsContainerConstIterator it = points->Begin(); PointsContainerConstIterator end = points->End(); while( it != end ) { pt.CastFrom( it->Value() ); seed_image->TransformPhysicalPointToIndex( pt, index ); seed_image->SetPixel( index, 1 + it->Index() ); ++it; } //Compute the voronoi map DistanceFilterPointer distance_filter = DistanceFilterType::New(); distance_filter->SetInput( seed_image ); distance_filter->UseImageSpacingOn(); distance_filter->SetInputIsBinary( true ); distance_filter->SetSquaredDistance( false ); //distance_filter->UpdateLargestPossibleRegion(); distance_filter->Update(); this->m_OutputImage = distance_filter->GetVoronoiMap(); this->m_OutputImage->DisconnectPipeline(); IteratorType Vor_it( this->m_OutputImage, this->m_OutputImage->GetLargestPossibleRegion() ); ConstIteratorType Bin_it( this->m_BinaryImage, this->m_BinaryImage->GetLargestPossibleRegion() ); Vor_it.GoToBegin(); Bin_it.GoToBegin(); while( !Vor_it.IsAtEnd() ) { if( Bin_it.Get() == zero ) { Vor_it.Set( zero ); } ++Vor_it; ++Bin_it; } } } #endif // __itkvtkMeshSplitterDanielssonDistanceImageFilter_txx GoFigure2-v0.9.0/Code/Filters/Mesh/Split/itkvtkMeshSplitterFilterBase.txx0000644000175000017500000000547611667757442026247 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshSplitterFilterBase_txx #define __itkvtkMeshSplitterFilterBase_txx #include "itkvtkMeshSplitterFilterBase.h" namespace itk { template< class TFeatureImage > vtkMeshSplitterFilterBase< TFeatureImage >:: vtkMeshSplitterFilterBase() : Superclass(), m_Mesh( NULL ) { for( unsigned int dim = 0; dim < 3; ++dim ) { m_Bounds[2 * dim] = NumericTraits< double >::max(); m_Bounds[2 * dim + 1] = NumericTraits< double >::min(); } } template< class TFeatureImage > void vtkMeshSplitterFilterBase< TFeatureImage >:: SetMesh( vtkPolyData* iMesh ) { if( ( iMesh ) && ( iMesh != m_Mesh ) ) { m_Mesh = iMesh; m_Mesh->GetBounds( m_Bounds ); this->Modified(); } } template< class TFeatureImage > std::vector< vtkPolyData* > vtkMeshSplitterFilterBase< TFeatureImage >:: GetOutputs() { return this->m_Outputs; } template< class TFeatureImage > void vtkMeshSplitterFilterBase< TFeatureImage >:: GenerateData() { if( !m_Mesh ) { itkGenericExceptionMacro( << "m_Mesh is NULL" ); } this->Split(); } } #endif GoFigure2-v0.9.0/Code/Filters/Mesh/Split/itkvtkMeshSplitterImageFilterBase.h0000644000175000017500000001105611667757442026605 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshSplitterImageFilterBase_h #define __itkvtkMeshSplitterImageFilterBase_h #include "itkLightObject.h" #include "itkPointSet.h" #include "vtkPolyData.h" #include "itkvtkMeshSplitterFilterBase.h" #include "itkExtractMeshesFromLabelImageFilter.h" #include "itkQuadEdgeMeshTovtkPolyData.h" #include "itkImage.h" #include namespace itk { /** \class vtkMeshSplitterImageFilterBase \brief */ template< class TFeatureImage, class TPointSet > class vtkMeshSplitterImageFilterBase : public vtkMeshSplitterFilterBase< TFeatureImage > { public: typedef vtkMeshSplitterImageFilterBase Self; typedef vtkMeshSplitterFilterBase< TFeatureImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro( vtkMeshSplitterFilterBase, vtkMeshSplitterFilterBase ); typedef TFeatureImage FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef typename FeatureImageType::PixelType FeatureImagePixelType; typedef typename FeatureImageType::IndexType FeatureImageIndexType; typedef typename FeatureImageType::PointType FeatureImagePointType; typedef TPointSet PointSetType; typedef typename PointSetType::Pointer PointSetPointer; typedef typename PointSetType::PointsContainerPointer PointsContainerPointer; typedef typename PointSetType::PointsContainerConstIterator PointsContainerConstIterator; typedef typename PointSetType::PointType PointType; typedef ExtractMeshesFromLabelImageFilter< FeatureImageType > ExtracMeshFilterType; typedef typename ExtracMeshFilterType::Pointer ExtracMeshFilterPointer; typedef typename ExtracMeshFilterType::MeshType MeshType; typedef QuadEdgeMeshTovtkPolyData< MeshType > ITKVTKMeshConverterType; typedef typename ITKVTKMeshConverterType::Pointer ITKVTKMeshConverterPointer; void SetSeeds( PointSetType* iSeeds ); protected: vtkMeshSplitterImageFilterBase(); virtual ~vtkMeshSplitterImageFilterBase() {} FeatureImagePointer m_BinaryImage; FeatureImagePointer m_OutputImage; PointSetPointer m_Seeds; unsigned int m_NumberOfThreads; unsigned int m_NumberOfTrianglesPerMesh; unsigned int m_NumberOfSmoothingIterations; unsigned int m_SmoothingRelaxationFactor; bool m_DelaunayConforming; bool m_UseSmoothing; bool m_UseDecimation; bool CheckAllSeeds() const; virtual void ComputeBinaryImageFromInputMesh(); virtual void Split(); virtual void SplitBinaryImage() = 0; void GenerateMeshesFromOutputImage(); void SetRequiredAttributeComputationFlags(); private: vtkMeshSplitterImageFilterBase( const Self& ); void operator = ( const Self& ); }; } #include "itkvtkMeshSplitterImageFilterBase.txx" #endif // __itkvtkMeshSplitterImageFilterBase_h GoFigure2-v0.9.0/Code/Filters/Mesh/Split/itkvtkMeshSplitterFilterBase.h0000644000175000017500000000672611667757442025652 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshSplitterFilterBase_h #define __itkvtkMeshSplitterFilterBase_h #include "itkvtkMeshFilterBase.h" #include "itkPointSet.h" #include "vtkPolyData.h" #include namespace itk { /** \class vtkMeshSplitterFilterBase \brief */ template< class TFeatureImage > class vtkMeshSplitterFilterBase : public vtkMeshFilterBase< TFeatureImage > { public: typedef vtkMeshFilterBase< TFeatureImage > Superclass; typedef vtkMeshSplitterFilterBase Self; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro( vtkMeshSplitterFilterBase, vtkMeshFilterBase ); typedef typename Superclass::FeatureImageType FeatureImageType; typedef typename Superclass::FeatureImagePointer FeatureImagePointer; void SetMesh( vtkPolyData* iMesh ); std::vector< vtkPolyData* > GetOutputs(); protected: /** \brief Constructor */ vtkMeshSplitterFilterBase(); /** \brief Destructor */ virtual ~vtkMeshSplitterFilterBase() {} vtkPolyData* m_Mesh; double m_Bounds[6]; template< class TPoint > bool IsPointInMeshBounds( const TPoint& iP ) const { for( unsigned int i = 0; i < 3; ++i ) { double t = static_cast< double >( iP[i] ); if( ( t < m_Bounds[2*i] ) || ( t > m_Bounds[2*i+1] ) ) { return false; } } return true; } /** \brief Main method to be reimplemented in inherited classes */ virtual void Split() = 0; virtual void GenerateData(); private: vtkMeshSplitterFilterBase( const Self& ); void operator = ( const Self& ); }; } #include "itkvtkMeshSplitterFilterBase.txx" #endif // __itkvtkMeshSplitterFilterBase_h GoFigure2-v0.9.0/Code/Filters/Mesh/Split/itkvtkMeshSplitterDanielssonDistanceImageFilter.h0000644000175000017500000001010611667757442031500 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshSplitterDanielssonDistanceImageFilter_h #define __itkvtkMeshSplitterDanielssonDistanceImageFilter_h #include "itkvtkMeshSplitterImageFilterBase.h" #include "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" #include "itkDanielssonDistanceMapImageFilter.h" namespace itk { template< class TFeatureImage, class TPointSet = PointSet< typename TFeatureImage::PointType::CoordRepType, TFeatureImage::ImageDimension > > class vtkMeshSplitterDanielssonDistanceImageFilter : public vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet > { public: typedef vtkMeshSplitterDanielssonDistanceImageFilter Self; typedef vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro( vtkMeshSplitterDanielssonDistanceImageFilter, vtkMeshSplitterImageFilterBase ); /** Method for creation through the object factory. */ itkNewMacro(Self); typedef typename Superclass::FeatureImageType FeatureImageType; typedef typename Superclass::FeatureImagePointer FeatureImagePointer; typedef typename Superclass::FeatureImagePixelType FeatureImagePixelType; typedef typename Superclass::FeatureImageIndexType FeatureImageIndexType; typedef typename Superclass::FeatureImagePointType FeatureImagePointType; typedef typename Superclass::PointsContainerPointer PointsContainerPointer; typedef typename Superclass::PointsContainerConstIterator PointsContainerConstIterator; typedef ImageRegionIterator< FeatureImageType > IteratorType; typedef ImageRegionConstIterator< FeatureImageType > ConstIteratorType; typedef DanielssonDistanceMapImageFilter< FeatureImageType, FeatureImageType > DistanceFilterType; typedef typename DistanceFilterType::Pointer DistanceFilterPointer; protected: vtkMeshSplitterDanielssonDistanceImageFilter(); ~vtkMeshSplitterDanielssonDistanceImageFilter() {} void SplitBinaryImage(); private: vtkMeshSplitterDanielssonDistanceImageFilter( const Self& ); void operator = ( const Self& ); }; } #include "itkvtkMeshSplitterDanielssonDistanceImageFilter.txx" #endif // __itkvtkMeshSplitterDanielssonDistanceImageFilter_h GoFigure2-v0.9.0/Code/Filters/Mesh/itkExtractMeshesFromLabelImageFilter.txx0000644000175000017500000002350511667757442026510 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkExtractMeshesFromLabelImageFilter_txx #define __itkExtractMeshesFromLabelImageFilter_txx #include "itkExtractMeshesFromLabelImageFilter.h" static itk::SimpleFastMutexLock m_Mutex; namespace itk { template< class TImage, class TFeatureImage > ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage > ::ExtractMeshesFromLabelImageFilter() { m_Input = 0; m_NumberOfMeshes = 0; m_NumberOfTrianglesPerMesh = 200; m_NumberOfSmoothingIterations = 15; m_SmoothingRelaxationFactor = 1.0; m_DelaunayConforming = true; m_NumberOfThreads = 1; m_UseSmoothing = true; m_UseDecimation = true; m_ComputeIntensityStatistics = false; } template< class TImage, class TFeatureImage > void ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: SetNumberOfFeatureImages( const size_t& iN ) { m_FeatureImages.resize( iN ); } template< class TImage, class TFeatureImage > void ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: SetFeatureImage( const size_t& iId, FeatureImageType* iF ) { if( iId < m_FeatureImages.size() ) { m_FeatureImages[iId] = iF; } } template< class TImage, class TFeatureImage > void ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: Update() { if( m_Input.IsNull() ) { itkGenericExceptionMacro( << "Input is NULL" ); } this->GenerateData(); } template< class TImage, class TFeatureImage > typename ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >::MeshVectorType ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: GetOutputs() { return m_Meshes; } template< class TImage, class TFeatureImage > void ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: GenerateData() { ShapeConverterPointer shapeConverter = ShapeConverterType::New(); shapeConverter->SetInput ( m_Input ); shapeConverter->SetBackgroundValue ( 0 ); shapeConverter->Update(); m_ShapeLabelMap = shapeConverter->GetOutput(); m_ShapeLabelMap->DisconnectPipeline(); m_NumberOfMeshes = m_ShapeLabelMap->GetNumberOfLabelObjects(); this->m_Meshes.resize( m_NumberOfMeshes ); if( m_ComputeIntensityStatistics ) { size_t NumberOfFeatureImages = m_FeatureImages.size(); if( NumberOfFeatureImages == 0 ) { itkGenericExceptionMacro( <<"No Feature Image Provided" ); } m_StatLabelMap.resize( NumberOfFeatureImages ); typename FeatureImageVectorType::iterator f_it = m_FeatureImages.begin(); typename FeatureImageVectorType::iterator f_end = m_FeatureImages.end(); size_t i = 0; while( f_it != f_end ) { StatConverterPointer statConverter = StatConverterType::New(); statConverter->SetInput( m_Input ); statConverter->SetFeatureImage( *f_it ); statConverter->SetBackgroundValue ( 0 ); statConverter->SetComputePerimeter(false); try { statConverter->Update(); } catch(itk::ExceptionObject & e) { std::cerr << "Exception Caught: " << e << std::endl; std::cerr << "statConverter->Update()" << std::endl; return; } m_StatLabelMap[i] = statConverter->GetOutput(); m_StatLabelMap[i]->DisconnectPipeline(); ++i; ++f_it; } } ThreadStruct str( this ); ThreaderPointer threader = ThreaderType::New(); threader->SetNumberOfThreads( m_NumberOfThreads ); threader->SetSingleMethod( this->ThreaderCallback, &str ); threader->SingleMethodExecute(); } template< class TImage, class TFeatureImage > ITK_THREAD_RETURN_TYPE ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: ThreaderCallback(void * arg) { unsigned int ThreadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID; ThreadStruct * str = (ThreadStruct *) (((MultiThreader::ThreadInfoStruct *)(arg))->UserData); unsigned int numOfMeshes = str->Filter->m_NumberOfMeshes; unsigned int numOfThreads = str->Filter->m_NumberOfThreads; unsigned int MeshChunk = numOfMeshes/ numOfThreads; ++MeshChunk; unsigned int startLabel = ThreadId * MeshChunk + 1; unsigned int endLabel = ThreadId * MeshChunk + MeshChunk; if ( ThreadId == numOfThreads-1 ) { endLabel = numOfMeshes; } str->Filter->ThreadedExtractMesh( startLabel, endLabel ); return ITK_THREAD_RETURN_VALUE; } template< class TImage, class TFeatureImage > void ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: ThreadedExtractMesh( const unsigned int& startLabel, const unsigned int& endLabel ) { LabelObjectContainerType container = m_ShapeLabelMap->GetLabelObjectContainer(); SizeType size; IndexType index; RegionType region; SizeType inputSize = m_Input->GetLargestPossibleRegion().GetSize(); LabelObjectIterator l_it = container.begin(); for ( unsigned int j = 1; j < startLabel; ++j, ++l_it ) {} MeshPointer mesh, smoothMesh, decimatedMesh; LabelType label = startLabel; LabelObjectIterator l_end = container.end(); while( ( label <= endLabel ) && ( l_it != l_end ) ) { LabelType i = l_it->first; #ifdef ITKv4 region = m_ShapeLabelMap->GetLabelObject ( i )->GetBoundingBox(); #else region = m_ShapeLabelMap->GetLabelObject ( i )->GetRegion(); #endif index = region.GetIndex(); size = region.GetSize(); for( unsigned int j = 0; j < ImageDimension; ++j ) { if ( static_cast( index[j] ) > 0 ) { index[j] = static_cast( index[j] - 1 ); size[j] = static_cast( size[j] + 1 ); } if ( static_cast( index[j] + size[j] ) < inputSize[j] ) { size[j] = static_cast( size[j] + 1 ); } } region.SetIndex( index ); region.SetSize( size ); // Extract mesh MeshSourcePointer meshSource = MeshSourceType::New(); meshSource->SetInput( m_Input ); #ifdef ITKv4 meshSource->SetRegionOfInterest ( region ); #else //no region, the whole image will be processed #endif meshSource->SetObjectValue( i ); meshSource->Update(); mesh = meshSource->GetOutput(); mesh->DisconnectPipeline(); // Smooth the mesh if ( m_UseSmoothing ) { ConformalMatrixCoefficients< MeshType > coeff0; MeshSmoothingPointer smoothingFilter = MeshSmoothingType::New( ); smoothingFilter->SetInput( mesh ); smoothingFilter->SetNumberOfIterations( m_NumberOfSmoothingIterations ); smoothingFilter->SetRelaxationFactor( m_SmoothingRelaxationFactor ); smoothingFilter->SetDelaunayConforming( m_DelaunayConforming ); smoothingFilter->SetCoefficientsMethod( &coeff0 ); smoothingFilter->Update(); smoothMesh = smoothingFilter->GetOutput(); smoothMesh->DisconnectPipeline(); } else { smoothMesh = mesh; } // Check topology // Decimate the mesh if ( m_UseDecimation ) { CriterionPointer criterion = CriterionType::New(); criterion->SetTopologicalChange( true ); criterion->SetNumberOfElements( m_NumberOfTrianglesPerMesh ); DecimationPointer decimate = DecimationType::New(); decimate->SetInput( smoothMesh ); decimate->SetCriterion( criterion ); decimate->Update(); decimatedMesh = decimate->GetOutput(); decimatedMesh->DisconnectPipeline(); } else { decimatedMesh = smoothMesh; } m_Meshes[label-1] = decimatedMesh; m_Meshes[label-1]->DisconnectPipeline(); m_MeshtoLabelIdMap.insert( std::pair< size_t, LabelType >( label - 1, i ) ); ++l_it; ++label; } } /** Print Self information */ template< class TImage, class TFeatureImage > void ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage > ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); os << indent << "NumberOfMeshes: " << m_NumberOfMeshes << std::endl; os << indent << "NumberOfTrianglesPerMesh: " << m_NumberOfTrianglesPerMesh << std::endl; os << indent << "NumberOfSmoothingIterations: " << m_NumberOfSmoothingIterations << std::endl; os << indent << "SmoothingRelaxationFactor: " << m_SmoothingRelaxationFactor << std::endl; } } // end namespace #endif GoFigure2-v0.9.0/Code/Filters/Mesh/Merge/0000755000175000017500000000000011667757442017611 5ustar mathieumathieuGoFigure2-v0.9.0/Code/Filters/Mesh/Merge/itkvtkMeshMergeConvexHullFilter.txx0000644000175000017500000000674211667757442026656 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshMergeConvexHullFilter_txx #define __itkvtkMeshMergeConvexHullFilter_txx #include "itkvtkMeshMergeConvexHullFilter.h" #include "vtkSmartPointer.h" #include "vtkAppendPolyData.h" #include "vtkDelaunay3D.h" #include "vtkDataSetSurfaceFilter.h" namespace itk { template< class TFeatureImage, class TPolyDataContainer > vtkMeshMergeConvexHullFilter< TFeatureImage, TPolyDataContainer >:: vtkMeshMergeConvexHullFilter() : Superclass() { this->SetRequiredAttributeComputationFlags(); } template< class TFeatureImage, class TPolyDataContainer > void vtkMeshMergeConvexHullFilter< TFeatureImage, TPolyDataContainer >:: GenerateData() { vtkSmartPointer< vtkAppendPolyData > append = vtkSmartPointer< vtkAppendPolyData >::New(); typename std::list< vtkPolyData* >::iterator it = this->m_Inputs.begin(); typename std::list< vtkPolyData* >::iterator end = this->m_Inputs.end(); while( it != end ) { append->AddInput( *it ); ++it; } append->Update(); vtkSmartPointer< vtkDelaunay3D > delaunay = vtkSmartPointer< vtkDelaunay3D >::New(); delaunay->SetInputConnection( append->GetOutputPort() ); delaunay->Update(); vtkSmartPointer surfaceFilter = vtkSmartPointer::New(); surfaceFilter->SetInputConnection(delaunay->GetOutputPort()); surfaceFilter->Update(); this->m_Outputs.front()->DeepCopy( surfaceFilter->GetOutput() ); } template< class TFeatureImage, class TPolyDataContainer > void vtkMeshMergeConvexHullFilter< TFeatureImage, TPolyDataContainer >:: SetRequiredAttributeComputationFlags() { this->m_ShapeComputation = true; this->m_IntensityComputation = true; } } #endif // __itkvtkMeshMergeConvexHullFilter_h GoFigure2-v0.9.0/Code/Filters/Mesh/Merge/itkvtkMeshMergeFilterBase.h0000644000175000017500000000566711667757442025052 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshMergeFilterBase_h #define __itkvtkMeshMergeFilterBase_h #include "itkvtkMeshFilterBase.h" #include class vtkPolyData; namespace itk { template< class TFeatureImage, class TPolyDataContainer > class vtkMeshMergeFilterBase : public vtkMeshFilterBase< TFeatureImage > { public: typedef vtkMeshFilterBase< TFeatureImage > Superclass; typedef vtkMeshMergeFilterBase Self; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; typedef TPolyDataContainer PolyDataContainerType; typedef typename PolyDataContainerType::value_type PolyDataType; itkTypeMacro( vtkMeshMergeFilterBase, vtkMeshFilterBase ); typedef typename Superclass::FeatureImageType FeatureImageType; typedef typename Superclass::FeatureImagePointer FeatureImagePointer; void SetInputs( const PolyDataContainerType& iMeshes ); vtkPolyData* GetOutput(); protected: vtkMeshMergeFilterBase(); virtual ~vtkMeshMergeFilterBase() {} PolyDataContainerType m_Inputs; private: vtkMeshMergeFilterBase( const Self& ); void operator = ( const Self& ); }; } #include "itkvtkMeshMergeFilterBase.txx" #endif // __itkvtkMeshMergeFilterBase_h GoFigure2-v0.9.0/Code/Filters/Mesh/Merge/itkvtkMeshMergeFilterBase.txx0000644000175000017500000000505111667757442025431 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshMergeFilterBase_txx #define __itkvtkMeshMergeFilterBase_txx #include "itkvtkMeshMergeFilterBase.h" #include "vtkPolyData.h" namespace itk { template< class TFeature, class TPolyDataContainer > vtkMeshMergeFilterBase< TFeature, TPolyDataContainer >:: vtkMeshMergeFilterBase() : Superclass() { this->m_Outputs.resize( 1, NULL ); this->m_Outputs[0] = vtkPolyData::New(); } template< class TFeature, class TPolyDataContainer > void vtkMeshMergeFilterBase< TFeature, TPolyDataContainer >:: SetInputs( const PolyDataContainerType& iMeshes ) { m_Inputs = iMeshes; this->Modified(); } template< class TFeature, class TPolyDataContainer > vtkPolyData* vtkMeshMergeFilterBase< TFeature, TPolyDataContainer >:: GetOutput() { return this->m_Outputs.front(); } } #endif GoFigure2-v0.9.0/Code/Filters/Mesh/Merge/itkvtkMeshMergeConvexHullFilter.h0000644000175000017500000000560211667757442026254 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkMeshMergeConvexHullFilter_h #define __itkvtkMeshMergeConvexHullFilter_h #include "itkvtkMeshMergeFilterBase.h" #include "itkObjectFactory.h" namespace itk { template< class TFeatureImage, class TPolyDataContainer > class vtkMeshMergeConvexHullFilter : public vtkMeshMergeFilterBase< TFeatureImage, TPolyDataContainer > { public: typedef vtkMeshMergeFilterBase< TFeatureImage, TPolyDataContainer > Superclass; typedef vtkMeshMergeConvexHullFilter Self; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro( vtkMeshMergeConvexHullFilter, vtkMeshMergeFilterBase ); /** Method for creation through the object factory. */ itkNewMacro(Self); protected: vtkMeshMergeConvexHullFilter(); ~vtkMeshMergeConvexHullFilter() {} void GenerateData(); void SetRequiredAttributeComputationFlags(); private: vtkMeshMergeConvexHullFilter( const Self& ); void operator = ( const Self& ); }; } #include "itkvtkMeshMergeConvexHullFilter.txx" #endif // __itkvtkMeshMergeConvexHullFilter_h GoFigure2-v0.9.0/Code/Filters/Mesh/itkvtkPolyDataToBinaryMaskImageFilter.h0000644000175000017500000001003611667757442026272 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkPolyDataToBinaryMaskImageFilter_h #define __itkvtkPolyDataToBinaryMaskImageFilter_h #include "itkImageToImageFilter.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "vtkPolyDataToImageStencil.h" #include "vtkImageStencil.h" #include "vtkImageExport.h" #include "itkVTKImageImport.h" #include "itkVTKImageToImageFilter.h" namespace itk { template< class TInput, class TOutput > class vtkPolyDataToBinaryMaskImageFilter: public ImageToImageFilter< TInput, TOutput > { public: typedef vtkPolyDataToBinaryMaskImageFilter Self; typedef ImageToImageFilter< TInput, TOutput > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Method for creation through object factory */ itkNewMacro(Self); /** Run-time type information */ itkTypeMacro(vtkPolyDataToBinaryMaskImageFilter, ImageToImageFilter); typedef TInput InputImageType; typedef typename InputImageType::Pointer InputImagePointer; typedef typename InputImageType::ConstPointer InputImageConstPointer; typedef typename InputImageType::SizeType InputImageSizeType; typedef typename InputImageType::SpacingType InputImageSpacingType; itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension); typedef TOutput BinaryMaskImageType; typedef typename BinaryMaskImageType::Pointer BinaryMaskImagePointer; typedef VTKImageImport< BinaryMaskImageType > ImageImportType; typedef typename ImageImportType::Pointer ImageImportPointer; virtual void SetPolyData(vtkPolyData *iMesh); protected: vtkPolyDataToBinaryMaskImageFilter(); ~vtkPolyDataToBinaryMaskImageFilter(); vtkPolyData *m_Mesh; vtkSmartPointer< vtkImageData > m_WhiteImage; vtkSmartPointer< vtkPolyDataToImageStencil > m_Pol2stenc; vtkSmartPointer< vtkImageStencil > m_ImageStencil; vtkSmartPointer< vtkImageExport > m_VTKExporter; ImageImportPointer m_ITKImporter; virtual void GenerateData(); private: vtkPolyDataToBinaryMaskImageFilter(const Self &); void operator=(const Self &); }; } #include "itkvtkPolyDataToBinaryMaskImageFilter.txx" #endif GoFigure2-v0.9.0/Code/Filters/Mesh/MeshToContourFilter.h0000644000175000017500000000556711667757442022657 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __MeshToContourFilter_h #define __MeshToContourFilter_h #include "map" class vtkPolyData; /** * \class MeshToContourFilter * \brief **/ class MeshToContourFilter { public: MeshToContourFilter(); ~MeshToContourFilter(); enum ORIENTATION { XY = 0, XZ = 1, YZ = 2 }; /** * \brief Set polydata to be splitted * \param[in] iInput polydata to be splitted */ void SetInput(vtkPolyData* iInput); /** * \brief Set spacing of the original image to know how many slices to extract * \param[in] iX X spacing * \param[in] iY Y spacing * \param[in] iZ Z spacing */ void SetSpacing(const double& iX, const double & iY, const double& iZ); /** * \brief Extract contours from polydata given an orientation * \param[in] iOrientation Desired Orientation (XY, XZ, YZ) * \return Map of polydatas indexed by slice position. * \note polydatas has to be deleted */ std::map ExtractPolyData(ORIENTATION iOrientation); private: vtkPolyData* m_Input; double m_Spacing[3]; }; #endif GoFigure2-v0.9.0/Code/Filters/Mesh/itkvtkPolyDataToBinaryMaskImageFilter.txx0000644000175000017500000001323411667757442026671 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkPolyDataToBinaryMaskImageFilter_txx #define __itkvtkPolyDataToBinaryMaskImageFilter_txx #include "itkvtkPolyDataToBinaryMaskImageFilter.h" #include "vtkPointData.h" #include "vtkitkAdaptor.h" namespace itk { template< class TInput, class TOutput > vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >:: vtkPolyDataToBinaryMaskImageFilter() { m_WhiteImage = vtkSmartPointer< vtkImageData >::New(); m_Pol2stenc = vtkSmartPointer< vtkPolyDataToImageStencil >::New(); m_ImageStencil = vtkSmartPointer< vtkImageStencil >::New(); m_VTKExporter = vtkSmartPointer< vtkImageExport >::New(); m_ITKImporter = ImageImportType::New(); } template< class TInput, class TOutput > vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >:: ~vtkPolyDataToBinaryMaskImageFilter() { } template< class TInput, class TOutput > void vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >:: SetPolyData(vtkPolyData *iMesh) { m_Mesh = iMesh; this->Modified(); } template< class TInput, class TOutput > void vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >:: GenerateData() { InputImageConstPointer input = this->GetInput(); if( input.IsNull() ) { itkGenericExceptionMacro( << "input is NULL" ); } double bounds[6]; m_Mesh->GetBounds(bounds); if ( ( m_Mesh->GetNumberOfCells() == 0 ) && ( m_Mesh->GetNumberOfPoints() == 0 ) ) { itkExceptionMacro( "vtkPolyDataToBinaryMaskImageFilter::GenerateData(): m_Mesh has nor cells nor points"); return; } // spacing is got from the input image InputImageSpacingType itk_spacing = input->GetSpacing(); double vtk_spacing[3] = { 0., 0., 0. }; int vtk_size[3] = { 0, 0, 0 }; // origin is the lowest bound! double origin[3]; origin[0] = bounds[0] - itk_spacing[0]; origin[1] = bounds[2] - itk_spacing[1]; origin[2] = bounds[4] - itk_spacing[2]; typename InputImageType::PointType itk_pt; itk_pt[0] = origin[0]; itk_pt[1] = origin[1]; itk_pt[2] = origin[2]; typename InputImageType::IndexType itk_idx; input->TransformPhysicalPointToIndex( itk_pt, itk_idx ); input->TransformIndexToPhysicalPoint( itk_idx, itk_pt ); origin[0] = itk_pt[0]; origin[1] = itk_pt[1]; origin[2] = itk_pt[2]; for ( unsigned int dim = 0; dim < ImageDimension; dim++ ) { vtk_spacing[dim] = static_cast< double >(itk_spacing[dim]); vtk_size[dim] = 1 + static_cast< int >( vcl_ceil( bounds[2 * dim + 1] - bounds[2 * dim] ) / vtk_spacing[dim]); } m_WhiteImage->SetSpacing(vtk_spacing); m_WhiteImage->SetDimensions(vtk_size); m_WhiteImage->SetExtent(0, vtk_size[0], 0, vtk_size[1], 0, vtk_size[2]); m_WhiteImage->SetOrigin(origin); m_WhiteImage->SetScalarTypeToUnsignedChar(); m_WhiteImage->AllocateScalars(); // fill the image with foreground voxels: unsigned char inval = 255; unsigned char outval = 0; vtkIdType count = m_WhiteImage->GetNumberOfPoints(); for ( vtkIdType i = 0; i < count; ++i ) { m_WhiteImage->GetPointData()->GetScalars()->SetTuple1(i, inval); } m_Pol2stenc->SetInput(m_Mesh); m_Pol2stenc->SetOutputOrigin(origin); m_Pol2stenc->SetOutputSpacing(vtk_spacing); m_Pol2stenc->SetOutputWholeExtent( m_WhiteImage->GetExtent() ); m_Pol2stenc->Update(); // cut the corresponding white image and set the background: m_ImageStencil->SetInput(m_WhiteImage); m_ImageStencil->SetStencil( m_Pol2stenc->GetOutput() ); m_ImageStencil->ReverseStencilOff(); m_ImageStencil->SetBackgroundValue(outval); m_ImageStencil->Update(); //Export VTK image to ITK m_VTKExporter->SetInput( m_ImageStencil->GetOutput() ); // typedef itk::VTKImageImport ImageImportType; // ImageImportType::Pointer m_ITKImporter = ImageImportType::New(); ConnectPipelines< vtkImageExport, ImageImportPointer >(m_VTKExporter, m_ITKImporter); this->GraftOutput( m_ITKImporter->GetOutput() ); } } #endif GoFigure2-v0.9.0/Code/Filters/Mesh/itkExtractMeshesFromLabelImageFilter.h0000644000175000017500000002432511667757442026115 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkExtractMeshesFromLabelImageFilter_h #define __itkExtractMeshesFromLabelImageFilter_h #ifdef _MSC_VER #pragma warning ( disable : 4786 ) #endif #include "itkImageToImageFilter.h" #include "itkImage.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkRegionOfInterestImageFilter.h" #include "itkShapeLabelObject.h" #include "itkLabelMap.h" #include "itkLabelImageToShapeLabelMapFilter.h" #include "itkLabelImageToStatisticsLabelMapFilter.h" #include "itkShapeRelabelImageFilter.h" #include "itkVector.h" #include "itkQuadEdgeMesh.h" #ifdef ITKv4 #include "itkSmoothingQuadEdgeMeshFilter.h" #include "itkSquaredEdgeLengthDecimationQuadEdgeMeshFilter.h" #else #include "itkQuadEdgeMeshSmoothing.h" #include "itkQuadEdgeMeshSquaredEdgeLengthDecimation.h" #endif #include "itkQuadEdgeMeshParamMatrixCoefficients.h" #include "itkQuadEdgeMeshDecimationCriteria.h" #include "itkBinaryMask3DMeshSource.h" #include #include "itkVTKPolyDataWriter.h" #include "itkMultiThreader.h" namespace itk { /** \class ExtractMeshesFromLabelImageFilter \brief \author Kishore Mosaliganti */ template< class TImage, class TFeatureImage = TImage > class ExtractMeshesFromLabelImageFilter : public Object { public: typedef ExtractMeshesFromLabelImageFilter Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; itkStaticConstMacro ( ImageDimension, unsigned int, TImage::ImageDimension ); /** Run-time type information (and related methods). */ itkTypeMacro( ExtractMeshesFromLabelImageFilter, Object ); /** Method for creation through the object factory. */ itkNewMacro(Self); /** \typedef ImageType Input Image type */ typedef TImage ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::IndexType IndexType; typedef typename IndexType::IndexValueType IndexValueType; typedef typename ImageType::PixelType PixelType; typedef typename ImageType::SizeType SizeType; typedef typename SizeType::SizeValueType SizeValueType; typedef typename ImageType::RegionType RegionType; typedef typename ImageType::SpacingType SpacingType; typedef typename ImageType::PointType PointType; typedef typename PointType::CoordRepType CoordType; typedef TFeatureImage FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef std::vector< FeatureImagePointer > FeatureImageVectorType; /** \typedef MeshType Output Mesh type */ typedef QuadEdgeMesh< CoordType, ImageDimension > MeshType; typedef typename MeshType::Pointer MeshPointer; typedef std::vector< MeshPointer > MeshVectorType; /** \typedef LabelType label type*/ typedef unsigned int LabelType; // --------------------------------------------------------------------------- /** \typedef ShapeLabelObjectType */ typedef ShapeLabelObject< LabelType, ImageDimension > ShapeLabelObjectType; typedef typename ShapeLabelObjectType::Pointer ShapeLabelObjectPointer; /** \typedef ShapeLabelMapType */ typedef LabelMap< ShapeLabelObjectType > ShapeLabelMapType; typedef typename ShapeLabelMapType::Pointer ShapeLabelMapPointer; /** \typedef ShapeConverterType */ typedef LabelImageToShapeLabelMapFilter< ImageType, ShapeLabelMapType > ShapeConverterType; typedef typename ShapeConverterType::Pointer ShapeConverterPointer; typedef typename ShapeLabelMapType::LabelObjectContainerType LabelObjectContainerType; typedef typename LabelObjectContainerType::const_iterator LabelObjectIterator; // --------------------------------------------------------------------------- /** \typedef StatLabelObjectType */ typedef StatisticsLabelObject< LabelType, ImageDimension > StatLabelObjectType; typedef typename StatLabelObjectType::Pointer StatLabelObjectPointer; typedef LabelMap< StatLabelObjectType > StatLabelMapType; typedef typename StatLabelMapType::Pointer StatLabelMapPointer; typedef LabelImageToStatisticsLabelMapFilter< ImageType, ImageType, StatLabelMapType > StatConverterType; typedef typename StatConverterType::Pointer StatConverterPointer; // --------------------------------------------------------------------------- typedef RegionOfInterestImageFilter< ImageType, ImageType > ROIFilterType; typedef typename ROIFilterType::Pointer ROIFilterPointer; typedef ImageRegionIterator< ImageType > IteratorType; typedef ImageRegionIteratorWithIndex< ImageType > IndexIteratorType; typedef BinaryMask3DMeshSource< ImageType, MeshType > MeshSourceType; typedef typename MeshSourceType::Pointer MeshSourcePointer; #ifdef ITKv4 typedef SmoothingQuadEdgeMeshFilter< MeshType, MeshType > MeshSmoothingType; #else typedef QuadEdgeMeshSmoothing< MeshType, MeshType > MeshSmoothingType; #endif typedef typename MeshSmoothingType::Pointer MeshSmoothingPointer; typedef NumberOfFacesCriterion< MeshType > CriterionType; typedef typename CriterionType::Pointer CriterionPointer; #ifdef ITKv4 typedef SquaredEdgeLengthDecimationQuadEdgeMeshFilter< MeshType, MeshType, CriterionType > DecimationType; #else typedef QuadEdgeMeshSquaredEdgeLengthDecimation< MeshType, MeshType, CriterionType > DecimationType; #endif typedef typename DecimationType::Pointer DecimationPointer; typedef VTKPolyDataWriter< MeshType > MeshWriterType; typedef typename MeshWriterType::Pointer MeshWriterPointer; typedef MultiThreader ThreaderType; typedef typename ThreaderType::Pointer ThreaderPointer; itkSetConstObjectMacro( Input, ImageType ); void SetNumberOfFeatureImages( const size_t& iN ); void SetFeatureImage( const size_t& iId, FeatureImageType* iF ); itkGetConstMacro( NumberOfMeshes, unsigned int ); itkSetMacro( NumberOfTrianglesPerMesh, unsigned int ); itkGetConstMacro( NumberOfTrianglesPerMesh, unsigned int ); itkGetConstMacro( DelaunayConforming, bool ); itkSetMacro( DelaunayConforming, bool ); itkSetMacro( UseDecimation, bool ); itkGetConstMacro( UseDecimation, bool ); itkSetMacro( UseSmoothing, bool ); itkGetConstMacro( UseSmoothing, bool ); itkSetMacro( NumberOfSmoothingIterations, unsigned int ); itkGetConstMacro( NumberOfSmoothingIterations, unsigned int ); itkSetMacro( SmoothingRelaxationFactor, double ); itkGetConstMacro( SmoothingRelaxationFactor, double ); #ifdef ITKv4 itkGetConstMacro( NumberOfThreads, ThreadIdType ); itkSetMacro( NumberOfThreads, ThreadIdType ); #else itkGetConstMacro( NumberOfThreads, int ); itkSetMacro( NumberOfThreads, int ); #endif itkGetObjectMacro( ShapeLabelMap, ShapeLabelMapType ); std::vector< StatLabelMapPointer > GetStatLabelMap() { return m_StatLabelMap; } void Update(); MeshVectorType GetOutputs(); protected: ExtractMeshesFromLabelImageFilter(); ~ExtractMeshesFromLabelImageFilter(){} void PrintSelf(std::ostream& os, Indent indent) const; void ThreadedExtractMesh( const unsigned int& startLabel, const unsigned int& endLabel ); static ITK_THREAD_RETURN_TYPE ThreaderCallback(void * arg); struct ThreadStruct { ThreadStruct( Self* iFilter ) : Filter( iFilter ) {} Self* Filter; }; void GenerateData(); ImageConstPointer m_Input; ShapeLabelMapPointer m_ShapeLabelMap; std::vector< StatLabelMapPointer > m_StatLabelMap; std::map< size_t, LabelType > m_MeshtoLabelIdMap; MeshVectorType m_Meshes; FeatureImageVectorType m_FeatureImages; #ifdef ITKv4 ThreadIdType m_NumberOfThreads; #else int m_NumberOfThreads; #endif unsigned int m_NumberOfMeshes; unsigned int m_NumberOfTrianglesPerMesh; unsigned int m_NumberOfSmoothingIterations; unsigned int m_SmoothingRelaxationFactor; bool m_DelaunayConforming; bool m_UseSmoothing; bool m_UseDecimation; bool m_ComputeIntensityStatistics; private: ExtractMeshesFromLabelImageFilter(const Self&) {} void operator=(const Self&) {} }; } // end namespace itk #include "itkExtractMeshesFromLabelImageFilter.txx" #endif GoFigure2-v0.9.0/Code/Filters/Mesh/MeshToContourFilter.cxx0000644000175000017500000001064011667757442023216 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "MeshToContourFilter.h" #include "vtkPolyData.h" #include "vtkPlane.h" #include "vtkCutter.h" //----------------------------------------------------------------------------- MeshToContourFilter:: MeshToContourFilter() : m_Input(NULL) { SetSpacing(0., 0., 0.); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- MeshToContourFilter:: ~MeshToContourFilter() { } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MeshToContourFilter:: SetInput(vtkPolyData* iInput) { m_Input = iInput; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MeshToContourFilter:: SetSpacing(const double& iX, const double & iY, const double& iZ) { m_Spacing[0] = iX; m_Spacing[1] = iY; m_Spacing[2] = iZ; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- std::map MeshToContourFilter:: ExtractPolyData(ORIENTATION iOrientation) { std::map contours; // create plane to extract contours (based on orientation) double normal[3] = {0., 0., 0.}; switch (iOrientation) { case XY: { normal[2] = 1; break; } case XZ: { normal[1] = 1; break; } case YZ: { normal[0] = 1; break; } default: { break; } } double origin[3] = {0., 0., 0.}; origin[0] = m_Input->GetCenter()[0]; origin[1] = m_Input->GetCenter()[1]; origin[2] = m_Input->GetCenter()[2]; double position = m_Input->GetBounds()[4 - 2*iOrientation]; double maxPosition = m_Input->GetBounds()[5 - 2*iOrientation]; double spacing = this->m_Spacing[2-iOrientation]; while( position < maxPosition) { origin[2-iOrientation] = position; vtkPlane* plane = vtkPlane::New(); plane->SetNormal(normal); plane->SetOrigin(origin); // cut vtkCutter* cutter = vtkCutter::New(); cutter->SetInput(m_Input); cutter->SetCutFunction(plane); cutter->Update(); vtkPolyData* polydata = vtkPolyData::New(); polydata->DeepCopy( cutter->GetOutput() ); plane->Delete(); cutter->Delete(); contours[position] = polydata; // increase position position += spacing; } return contours; } //----------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/Filters/Mesh/itkConvertMeshesToLabelImageFilter.txx0000644000175000017500000001447611667757442026204 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkConvertMeshesToLabelImageFilter_txx #define __itkConvertMeshesToLabelImageFilter_txx #include "itkConvertMeshesToLabelImageFilter.h" static itk::SimpleFastMutexLock m_MutexCMLF; namespace itk { template< class TImage, class TMesh > ConvertMeshesToLabelImageFilter< TImage, TMesh > ::ConvertMeshesToLabelImageFilter() { m_NumberOfMeshes = 0; m_NumberOfThreads = 1; m_Input = NULL; } template< class TImage, class TMesh > void ConvertMeshesToLabelImageFilter< TImage, TMesh >:: SetMeshes( const MeshVectorType& iMeshes ) { m_Meshes = iMeshes; this->Modified(); } template< class TImage, class TMesh > void ConvertMeshesToLabelImageFilter< TImage, TMesh >:: Update() { // Create an empty image if ( !this->m_Input ) { itkGenericExceptionMacro( << "Input is NULL" ); } this->GenerateData(); } template< class TImage, class TMesh > void ConvertMeshesToLabelImageFilter< TImage, TMesh >:: GenerateData() { m_NumberOfMeshes = this->m_Meshes.size(); ThreadStruct str; str.Filter = this; ThreaderPointer threader = ThreaderType::New(); threader->SetNumberOfThreads( m_NumberOfThreads ); threader->SetSingleMethod( this->ThreaderCallback, &str ); threader->SingleMethodExecute(); } template< class TImage, class TMesh > ITK_THREAD_RETURN_TYPE ConvertMeshesToLabelImageFilter< TImage, TMesh >:: ThreaderCallback(void * arg) { unsigned int ThreadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID; ThreadStruct * str = (ThreadStruct *) (((MultiThreader::ThreadInfoStruct *)(arg))->UserData); size_t numOfMeshes = str->Filter->m_NumberOfMeshes; size_t numOfThreads = static_cast< size_t >( str->Filter->m_NumberOfThreads ); unsigned int MeshChunk = static_cast< unsigned int >( numOfMeshes/ numOfThreads); ++MeshChunk; unsigned int startLabel = ThreadId * MeshChunk + 1; unsigned int endLabel = ThreadId * MeshChunk + MeshChunk; if ( ThreadId == numOfThreads-1 ) { endLabel = numOfMeshes; } str->Filter->ThreadedExtractMesh( startLabel, endLabel ); return ITK_THREAD_RETURN_VALUE; } template< class TImage, class TMesh > void ConvertMeshesToLabelImageFilter< TImage, TMesh >:: ThreadedExtractMesh( const unsigned int& startLabel, const unsigned int& endLabel ) { //PointType origin = m_Input->GetOrigin(); SpacingType spacing = m_Input->GetSpacing(); RegionType m_LargestRegion = m_Input->GetLargestPossibleRegion(); PointType pmin, pmax; IndexType imin, imax, null_index; SizeType size; RegionType region, newRegion; PointType newOrigin; for( unsigned int i = 0; i < ImageDimension; i++ ) { null_index[i] = 0; } unsigned int label = startLabel; while( label <= endLabel ) { MeshPointer temp_mesh = m_Meshes[label-1]; // Convert the bounding box into an image region and origin pmin = temp_mesh->GetBoundingBox()->GetMinimum(); pmax = temp_mesh->GetBoundingBox()->GetMaximum(); m_Input->TransformPhysicalPointToIndex( pmin, imin ); m_Input->TransformPhysicalPointToIndex( pmax, imax ); for( unsigned int i = 0; i < ImageDimension; ++i ) { imin[i] = imin[i] - 1; imax[i] = imax[i] + 1; size[i] = imax[i] - imin[i] + 1; } region.SetIndex( imin ); region.SetSize( size ); region.Crop( m_LargestRegion ); m_Input->TransformIndexToPhysicalPoint( imin, newOrigin ); newRegion.SetIndex( null_index ); newRegion.SetSize( region.GetSize() ); // Call TriangleMeshToBinaryImageFilter MeshToImageFilterPointer imageFilter = MeshToImageFilterType::New(); imageFilter->SetInput( temp_mesh ); imageFilter->SetInsideValue( label ); imageFilter->SetOrigin( newOrigin ); imageFilter->SetSpacing( spacing ); imageFilter->SetIndex( null_index ); imageFilter->SetSize( size ); imageFilter->Update(); ImagePointer comp = imageFilter->GetOutput(); // Copy the small output image here into the m_Input IteratorType iIt( m_Input, region ); iIt.GoToBegin(); IteratorType cIt( comp, comp->GetLargestPossibleRegion() ); cIt.GoToBegin(); while( !iIt.IsAtEnd() ) { if ( ( cIt.Get() != 0 ) && ( iIt.Get() == 0 ) ) { iIt.Set( cIt.Get() ); } ++iIt; ++cIt; } ++label; } } /** Print Self information */ template< class TImage, class TMesh > void ConvertMeshesToLabelImageFilter< TImage, TMesh > ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); os << indent << "NumberOfMeshes: " << m_NumberOfMeshes << std::endl; } } // end namespace #endif GoFigure2-v0.9.0/Code/Filters/Mesh/itkQuadEdgeMeshTovtkPolyData.txx0000644000175000017500000001132311667757442025011 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkQuadEdgeMeshTovtkPolyData_txx #define __itkQuadEdgeMeshTovtkPolyData_txx #include "itkQuadEdgeMeshTovtkPolyData.h" namespace itk { template< class TMesh > QuadEdgeMeshTovtkPolyData< TMesh > ::QuadEdgeMeshTovtkPolyData() { m_PolyData = vtkSmartPointer< vtkPolyData >::New(); } template< class TMesh > QuadEdgeMeshTovtkPolyData< TMesh > ::~QuadEdgeMeshTovtkPolyData() { } template< class TMesh > void QuadEdgeMeshTovtkPolyData< TMesh > ::SetInput(MeshType* mesh) { if( mesh ) { m_itkMesh = mesh; this->Modified(); } } template< class TMesh > vtkPolyData * QuadEdgeMeshTovtkPolyData< TMesh > ::GetOutput() { return m_PolyData; } template< class TMesh > void QuadEdgeMeshTovtkPolyData< TMesh > ::Update() { if( m_itkMesh.IsNull() ) { itkGenericExceptionMacro( << "m_itkMesh is NULL" ); } this->GenerateData(); } template< class TMesh > void QuadEdgeMeshTovtkPolyData< TMesh > ::GenerateData() { PointIdentifier NumberOfPoints = m_itkMesh->GetNumberOfPoints(); if( NumberOfPoints == 0 ) { itkGenericExceptionMacro( << "NumberOfPoints == 0" ); } vtkSmartPointer< vtkPoints > vtk_Points = vtkSmartPointer< vtkPoints >::New(); vtk_Points->SetNumberOfPoints( NumberOfPoints ); PointsContainerPointer itk_Points = m_itkMesh->GetPoints(); PointsContainerConstIterator p_it = itk_Points->Begin(); PointsContainerConstIterator p_end = itk_Points->End(); PointType itk_point; vtkIdType id=0; double vtk_point[3]; while( p_it != p_end ) { itk_point = p_it.Value(); vtk_point[0] = itk_point[0]; vtk_point[1] = itk_point[1]; vtk_point[2] = itk_point[2]; vtk_Points->SetPoint( id, vtk_point ); ++p_it; ++id; } if( m_itkMesh->GetNumberOfCells() == 0 ) { itkGenericExceptionMacro( << "NumberOfCells == 0" ); } CellsContainerPointer itk_Cells = m_itkMesh->GetCells(); CellsContainerConstIterator c_it = itk_Cells->Begin(); CellsContainerConstIterator c_end = itk_Cells->End(); vtkSmartPointer< vtkCellArray > vtk_Polys = vtkSmartPointer< vtkCellArray >::New(); while ( c_it != c_end ) { CellType* temp_cell = c_it->Value(); typename CellType::PointIdIterator temp_c_it = temp_cell->PointIdsBegin(); typename CellType::PointIdIterator temp_c_end = temp_cell->PointIdsEnd(); size_t nb_pts = temp_cell->GetNumberOfPoints(); std::vector< vtkIdType > pts( nb_pts ); size_t i = 0; switch (temp_cell->GetType()) { default: case CellType::VERTEX_CELL: case CellType::LINE_CELL: break; case CellType::TRIANGLE_CELL: case CellType::POLYGON_CELL: while( temp_c_it != temp_c_end ) { pts[i] = *temp_c_it; ++i; ++temp_c_it; } vtk_Polys->InsertNextCell( nb_pts, &( pts.front() ) ); break; } ++c_it; } m_PolyData->SetPoints( vtk_Points ); m_PolyData->SetPolys( vtk_Polys ); } } #endif GoFigure2-v0.9.0/Code/Filters/Mesh/itkConvertMeshesToLabelImageFilter.h0000644000175000017500000001264311667757442025602 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkConvertMeshesToLabelImageFilter_h #define __itkConvertMeshesToLabelImageFilter_h #ifdef _MSC_VER #pragma warning ( disable : 4786 ) #endif #include "itkImageToImageFilter.h" #include "itkImage.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkRegionOfInterestImageFilter.h" #include "itkQuadEdgeMesh.h" #include "itkTriangleMeshToBinaryImageFilter.h" #include "itkVector.h" #include #include "itkMultiThreader.h" namespace itk { template< class TImage, class TMesh = QuadEdgeMesh< typename TImage::PointType::CoordRepType, TImage::ImageDimension > > class ConvertMeshesToLabelImageFilter : public Object { public: typedef ConvertMeshesToLabelImageFilter Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; itkStaticConstMacro ( ImageDimension, unsigned int, TImage::ImageDimension ); /** Run-time type information (and related methods). */ itkTypeMacro( ConvertMeshesToLabelImageFilter, Object ); /** Method for creation through the object factory. */ itkNewMacro(Self); /** Input Image typedef */ typedef TImage ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::IndexType IndexType; typedef typename IndexType::IndexValueType IndexValueType; typedef typename ImageType::PixelType PixelType; typedef typename ImageType::SizeType SizeType; typedef typename SizeType::SizeValueType SizeValueType; typedef typename ImageType::RegionType RegionType; typedef typename ImageType::SpacingType SpacingType; typedef typename ImageType::PointType PointType; typedef typename PointType::CoordRepType CoordType; typedef TMesh MeshType; typedef typename MeshType::Pointer MeshPointer; typedef std::vector< MeshPointer > MeshVectorType; typedef RegionOfInterestImageFilter< ImageType, ImageType > ROIFilterType; typedef typename ROIFilterType::Pointer ROIFilterPointer; typedef ImageRegionIterator< ImageType > IteratorType; typedef ImageRegionIteratorWithIndex< ImageType > IndexIteratorType; typedef TriangleMeshToBinaryImageFilter< MeshType, ImageType > MeshToImageFilterType; typedef typename MeshToImageFilterType::Pointer MeshToImageFilterPointer; typedef MultiThreader ThreaderType; typedef typename ThreaderType::Pointer ThreaderPointer; itkSetObjectMacro( Input , ImageType ); itkGetConstMacro( NumberOfMeshes, size_t ); #ifdef ITKv4 itkGetConstMacro( NumberOfThreads, ThreadIdType ); itkSetMacro( NumberOfThreads, ThreadIdType ); #else itkGetConstMacro( NumberOfThreads, int ); itkSetMacro( NumberOfThreads, int ); #endif void SetMeshes( const MeshVectorType& iMeshes ); void Update(); protected: ConvertMeshesToLabelImageFilter(); ~ConvertMeshesToLabelImageFilter(){} void PrintSelf(std::ostream& os, Indent indent) const; void ThreadedExtractMesh( const unsigned int& startLabel, const unsigned int& endLabel ); static ITK_THREAD_RETURN_TYPE ThreaderCallback(void * arg); struct ThreadStruct { Self* Filter; }; size_t m_NumberOfMeshes; #ifdef ITKv4 ThreadIdType m_NumberOfThreads; #else int m_NumberOfThreads; #endif ImageType* m_Input; MeshVectorType m_Meshes; void GenerateData(); private: ConvertMeshesToLabelImageFilter(const Self&); void operator=(const Self&); }; } // end namespace itk #include "itkConvertMeshesToLabelImageFilter.txx" #endif GoFigure2-v0.9.0/Code/Filters/Mesh/Attributes/0000755000175000017500000000000011667757442020700 5ustar mathieumathieuGoFigure2-v0.9.0/Code/Filters/Mesh/Attributes/itkBinaryMaskImageToGoFigureMeshAttributes.h0000644000175000017500000001335611667757442031413 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkBinaryMaskImageToGoFigureMeshAttributes_h #define __itkBinaryMaskImageToGoFigureMeshAttributes_h #include "itkLightObject.h" #include "itkShapeLabelObject.h" #include "itkStatisticsLabelObject.h" #include "itkLabelImageToShapeLabelMapFilter.h" #include "itkLabelImageToStatisticsLabelMapFilter.h" namespace itk { /** \class BinaryMaskImageToGoFigureMeshAttributes * \brief Compute Mesh Attributes from a binary mask image * \tparam TInput Input Image Type (depends on the kind of images used, * but one channel) * \tparam TMask Mast Image Type * \sa GoFigureMeshAttributes * */ template< class TInput, class TMask > class BinaryMaskImageToGoFigureMeshAttributes:public LightObject { public: typedef BinaryMaskImageToGoFigureMeshAttributes Self; typedef LightObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; typedef TInput ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::SizeType ImageSizeType; typedef typename ImageType::SpacingType ImageSpacingType; typedef TMask MaskImageType; typedef typename MaskImageType::Pointer MaskImagePointer; itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension); /** Method for creation through object factory */ itkNewMacro(Self); /** Run-time type information */ itkTypeMacro(BinaryMaskImageToGoFigureMeshAttributes, LightObject); /** Display */ // void PrintSelf( std::ostream& os, Indent indent ) const; typedef unsigned char LabelType; typedef ShapeLabelObject< LabelType, ImageDimension > ShapeLabelObjectType; typedef typename ShapeLabelObjectType::Pointer ShapeLabelObjectPointer; typedef StatisticsLabelObject< LabelType, ImageDimension > StatLabelObjectType; typedef typename StatLabelObjectType::Pointer StatLabelObjectPointer; typedef LabelMap< ShapeLabelObjectType > ShapeLabelMapType; typedef typename ShapeLabelMapType::Pointer ShapeLabelMapPointer; typedef LabelMap< StatLabelObjectType > StatLabelMapType; typedef typename StatLabelMapType::Pointer StatLabelMapPointer; typedef LabelImageToShapeLabelMapFilter< MaskImageType, ShapeLabelMapType > ShapeConverterType; typedef typename ShapeConverterType::Pointer ShapeConverterPointer; typedef LabelImageToStatisticsLabelMapFilter< MaskImageType, ImageType, StatLabelMapType > StatConverterType; typedef typename StatConverterType::Pointer StatConverterPointer; /** \brief Set the Image */ void SetImage(ImageType *iInput); /** \brief Set the binary mask which corresponds to the input mesh */ void SetMaskImage(MaskImageType *iMask); /** \brief Do you need to compute any intensity related attributes */ void SetIntensityBasedComputation( const bool& iComputation ); /** \brief Here make all the computation */ void Update(); /** \brief Get the number of voxels inside the mesh */ unsigned int GetSize(); /** \brief Get the volume inside the mesh */ double GetPhysicalSize(); /** \brief Get the mean intensity inside the mesh */ double GetMeanIntensity(); /** \brief Get the total intensity inside the mesh */ double GetSumIntensity(); protected: /** \brief Constructor */ BinaryMaskImageToGoFigureMeshAttributes(); /** \brief Destructor*/ ~BinaryMaskImageToGoFigureMeshAttributes(); ImagePointer m_InputImage; MaskImagePointer m_MaskImage; unsigned int m_Size; double m_PhysicalSize; double m_Mean; double m_Sum; bool m_IntensityComputation; virtual void GenerateData(); private: BinaryMaskImageToGoFigureMeshAttributes(const Self &); void operator=(const Self &); }; } #include "itkBinaryMaskImageToGoFigureMeshAttributes.txx" #endif GoFigure2-v0.9.0/Code/Filters/Mesh/Attributes/itkvtkPolyDataToGoFigureMeshAttributes.txx0000644000175000017500000001426011667757442031241 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkPolyDataToGoFigureMeshAttributes_txx #define __itkvtkPolyDataToGoFigureMeshAttributes_txx #include "itkvtkPolyDataToGoFigureMeshAttributes.h" #include "vtkTriangle.h" namespace itk { template< class TImage > vtkPolyDataToGoFigureMeshAttributes< TImage >::vtkPolyDataToGoFigureMeshAttributes() : m_Mesh(NULL), m_Image(NULL) { m_IntensityComputation = true; m_Binarizer = PolyDataToBinaryMaskImageFilterType::New(); m_AttributeCalculator = BinaryMaskImageToGoFigureMeshAttributesType::New(); m_ROIFilter = ROIFilterType::New(); } template< class TImage > vtkPolyDataToGoFigureMeshAttributes< TImage >:: ~vtkPolyDataToGoFigureMeshAttributes() { } template< class TImage > void vtkPolyDataToGoFigureMeshAttributes< TImage >::SetIntensityBasedComputation(const bool & iComputation) { this->m_IntensityComputation = iComputation; } template< class TImage > void vtkPolyDataToGoFigureMeshAttributes< TImage >::SetPolyData(vtkPolyData *iMesh) { m_Mesh = iMesh; if ( m_Mesh && m_Image.IsNotNull() ) { m_Binarizer->SetInput(m_Image); m_Binarizer->SetPolyData(m_Mesh); try { m_Binarizer->Update(); } catch(itk::ExceptionObject & e) { std::cerr << "Exception: " << e << std::endl; } } } template< class TImage > void vtkPolyDataToGoFigureMeshAttributes< TImage >::SetImage(ImageType *iImage) { m_Image = iImage; m_ROIFilter->SetInput(m_Image); if ( m_Mesh && m_Image.IsNotNull() ) { m_Binarizer->SetInput(m_Image); m_Binarizer->SetPolyData(m_Mesh); try { m_Binarizer->Update(); } catch(itk::ExceptionObject & e) { std::cerr << "Exception: " << e << std::endl; } } } template< class TImage > void vtkPolyDataToGoFigureMeshAttributes< TImage >::Update() { GenerateData(); } template< class TImage > unsigned int vtkPolyDataToGoFigureMeshAttributes< TImage >::GetSize() { return m_Size; } template< class TImage > double vtkPolyDataToGoFigureMeshAttributes< TImage >::GetPhysicalSize() { return m_PhysicalSize; } template< class TImage > double vtkPolyDataToGoFigureMeshAttributes< TImage >::GetMeanIntensity() { return m_Mean; } template< class TImage > double vtkPolyDataToGoFigureMeshAttributes< TImage >::GetSumIntensity() { return m_Sum; } template< class TImage > double vtkPolyDataToGoFigureMeshAttributes< TImage >::GetArea() { return m_Area; } template< class TImage > void vtkPolyDataToGoFigureMeshAttributes< TImage >::GenerateData() { m_AttributeCalculator->SetMaskImage( m_Binarizer->GetOutput() ); m_AttributeCalculator->SetIntensityBasedComputation(m_IntensityComputation); if ( m_IntensityComputation ) { double bounds[6]; m_Mesh->GetBounds(bounds); typename ImageType::PointType org; org[0] = bounds[0]; org[1] = bounds[2]; org[2] = bounds[4]; typename ImageType::IndexType start_idx; m_Image->TransformPhysicalPointToIndex(org, start_idx); typename ImageType::SizeType size = m_Binarizer->GetOutput()->GetLargestPossibleRegion().GetSize(); typename ImageType::SizeType image_size = m_Image->GetLargestPossibleRegion().GetSize(); // make sure we will stay inside the bounding box while iterating for(int i = 0; i<3; i++) { if(size[i] + start_idx[i] > image_size[i]) { size[i] = image_size[i] - start_idx[i]; } } typename ImageType::RegionType region; region.SetSize(size); region.SetIndex(start_idx); m_ROIFilter->SetRegionOfInterest(region); try { m_ROIFilter->Update(); } catch(itk::ExceptionObject & e) { std::cerr << "Exception: " << e << std::endl; } m_AttributeCalculator->SetImage( m_ROIFilter->GetOutput() ); } try { m_AttributeCalculator->Update(); } catch(itk::ExceptionObject & e) { std::cerr << "Exception: " << e << std::endl; } m_Size = m_AttributeCalculator->GetSize(); m_PhysicalSize = m_AttributeCalculator->GetPhysicalSize(); m_Mean = m_AttributeCalculator->GetMeanIntensity(); m_Sum = m_AttributeCalculator->GetSumIntensity(); ComputeArea(); } template< class TImage > void vtkPolyDataToGoFigureMeshAttributes< TImage >::ComputeArea() { vtkIdType NbOfCells = m_Mesh->GetNumberOfCells(); m_Area = 0.; for ( vtkIdType i = 0; i < NbOfCells; ++i ) { vtkTriangle *t = dynamic_cast< vtkTriangle * >( m_Mesh->GetCell(i) ); m_Area += t->ComputeArea(); } } } #endif GoFigure2-v0.9.0/Code/Filters/Mesh/Attributes/itkBinaryMaskImageToGoFigureMeshAttributes.txx0000644000175000017500000001266111667757442032005 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkBinaryMaskImageToGoFigureMeshAttributes_txx #define __itkBinaryMaskImageToGoFigureMeshAttributes_txx namespace itk { template< class TInput, class TMask > BinaryMaskImageToGoFigureMeshAttributes< TInput, TMask >::BinaryMaskImageToGoFigureMeshAttributes() { m_IntensityComputation = true; m_Mean = 0; m_Sum = 0; m_Size = 0; m_PhysicalSize = 0; } template< class TInput, class TMask > BinaryMaskImageToGoFigureMeshAttributes< TInput, TMask >:: ~BinaryMaskImageToGoFigureMeshAttributes() { } template< class TInput, class TMask > void BinaryMaskImageToGoFigureMeshAttributes< TInput, TMask >::SetIntensityBasedComputation(const bool & iComputation) { m_IntensityComputation = iComputation; } template< class TInput, class TMask > void BinaryMaskImageToGoFigureMeshAttributes< TInput, TMask >::SetImage(ImageType *iInput) { m_InputImage = iInput; } template< class TInput, class TMask > void BinaryMaskImageToGoFigureMeshAttributes< TInput, TMask >::SetMaskImage(MaskImageType *iMask) { m_MaskImage = iMask; } template< class TInput, class TMask > void BinaryMaskImageToGoFigureMeshAttributes< TInput, TMask >::Update() { GenerateData(); } template< class TInput, class TMask > unsigned int BinaryMaskImageToGoFigureMeshAttributes< TInput, TMask >::GetSize() { return m_Size; } template< class TInput, class TMask > double BinaryMaskImageToGoFigureMeshAttributes< TInput, TMask >::GetPhysicalSize() { return m_PhysicalSize; } template< class TInput, class TMask > double BinaryMaskImageToGoFigureMeshAttributes< TInput, TMask >::GetMeanIntensity() { return m_Mean; } template< class TInput, class TMask > double BinaryMaskImageToGoFigureMeshAttributes< TInput, TMask >::GetSumIntensity() { return m_Sum; } template< class TInput, class TMask > void BinaryMaskImageToGoFigureMeshAttributes< TInput, TMask >::GenerateData() { // shape stuff ShapeConverterPointer shapeConverter = ShapeConverterType::New(); shapeConverter->SetInput(m_MaskImage); shapeConverter->SetBackgroundValue(0); shapeConverter->SetComputePerimeter(false); try { shapeConverter->Update(); } catch(itk::ExceptionObject & e) { std::cerr << "Exception Caught: " << e << std::endl; std::cerr << "shapeConverter->Update()" << std::endl; return; } ShapeLabelMapPointer shapeLabelMap = shapeConverter->GetOutput(); LabelType maxLabel = NumericTraits< LabelType >::max(); if ( shapeLabelMap->HasLabel(maxLabel) ) { const ShapeLabelObjectType *shapeObject = shapeLabelMap->GetLabelObject(maxLabel); // Number of voxels; m_Size = shapeObject->Size(); // Volume or area in um^3 m_PhysicalSize = shapeObject->GetPhysicalSize(); } else { // Number of voxels; m_Size = 0; // Volume or area in um^3 m_PhysicalSize = 0; } if ( m_IntensityComputation ) { // stat stuff StatConverterPointer statConverter = StatConverterType::New(); statConverter->SetInput(m_MaskImage); statConverter->SetFeatureImage(m_InputImage); statConverter->SetBackgroundValue(0); statConverter->SetComputePerimeter(false); try { statConverter->Update(); } catch(itk::ExceptionObject & e) { std::cerr << "Exception Caught: " << e << std::endl; std::cerr << "statConverter->Update()" << std::endl; return; } StatLabelMapPointer statLabelMap = statConverter->GetOutput(); if ( statLabelMap->HasLabel(maxLabel) ) { const StatLabelObjectType *statObject = statLabelMap->GetLabelObject(maxLabel); m_Mean = statObject->GetMean(); m_Sum = statObject->GetSum(); } else { m_Mean = 0; m_Sum = 0; } } } } #endif GoFigure2-v0.9.0/Code/Filters/Mesh/Attributes/itkvtkPolyDataToGoFigureMeshAttributes.h0000644000175000017500000001040311667757442030640 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkvtkPolyDataToGoFigureMeshAttributes_h #define __itkvtkPolyDataToGoFigureMeshAttributes_h #include "itkLightObject.h" #include "itkvtkPolyDataToBinaryMaskImageFilter.h" #include "itkBinaryMaskImageToGoFigureMeshAttributes.h" #include "itkRegionOfInterestImageFilter.h" #include "itkImageFileWriter.h" namespace itk { template< class TImage > class vtkPolyDataToGoFigureMeshAttributes:public LightObject { public: typedef vtkPolyDataToGoFigureMeshAttributes Self; typedef LightObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; typedef TImage ImageType; typedef typename ImageType::Pointer ImagePointer; /** Method for creation through object factory */ itkNewMacro(Self); /** Run-time type information */ itkTypeMacro(vtkPolyDataToGoFigureMeshAttributes, LightObject); typedef vtkPolyDataToBinaryMaskImageFilter< ImageType, ImageType > PolyDataToBinaryMaskImageFilterType; typedef typename PolyDataToBinaryMaskImageFilterType::Pointer PolyDataToBinaryMaskImageFilterPointer; typedef BinaryMaskImageToGoFigureMeshAttributes< ImageType, ImageType > BinaryMaskImageToGoFigureMeshAttributesType; typedef typename BinaryMaskImageToGoFigureMeshAttributesType::Pointer BinaryMaskImageToGoFigureMeshAttributesPointer; typedef RegionOfInterestImageFilter< ImageType, ImageType > ROIFilterType; typedef typename ROIFilterType::Pointer ROIFilterPointer; typedef ImageFileWriter< ImageType > WriterType; virtual void SetImage(ImageType *iImage); virtual void SetPolyData(vtkPolyData *iMesh); void SetIntensityBasedComputation( const bool& iComputation ); virtual void Update(); unsigned int GetSize(); double GetPhysicalSize(); double GetMeanIntensity(); double GetSumIntensity(); double GetArea(); protected: vtkPolyDataToGoFigureMeshAttributes(); ~vtkPolyDataToGoFigureMeshAttributes(); vtkPolyData *m_Mesh; ImagePointer m_Image; PolyDataToBinaryMaskImageFilterPointer m_Binarizer; BinaryMaskImageToGoFigureMeshAttributesPointer m_AttributeCalculator; ROIFilterPointer m_ROIFilter; unsigned int m_Size; double m_PhysicalSize; double m_Area; double m_Mean; double m_Sum; bool m_IntensityComputation; virtual void GenerateData(); void ComputeArea(); private: vtkPolyDataToGoFigureMeshAttributes(const Self &); void operator=(const Self &); }; } #include "itkvtkPolyDataToGoFigureMeshAttributes.txx" #endif GoFigure2-v0.9.0/Code/Filters/Mesh/itkvtkPolyDataToitkQuadEdgeMesh.h0000644000175000017500000001143511667757442025131 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkPolyDataToitkQuadEdgeMesh_h #define __vtkPolyDataToitkQuadEdgeMesh_h #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkIdList.h" #include "itkQuadEdgeMesh.h" #include "itkTriangleCell.h" #include "itkObject.h" namespace itk { template< class TMesh > class vtkPolyDataToitkQuadEdgeMesh : public Object { public: typedef vtkPolyDataToitkQuadEdgeMesh Self; typedef Object Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(vtkPolyDataToitkQuadEdgeMesh, Object); typedef TMesh MeshType; typedef typename MeshType::Pointer MeshPointer; typedef typename MeshType::PointsContainerPointer PointsContainerPointer; typedef typename MeshType::PointIdentifier PointIdentifier; typedef typename MeshType::CellAutoPointer CellAutoPointer; typedef typename MeshType::CellType CellType; typedef typename MeshType::PointType PointType; typedef typename PointType::CoordRepType CoordType; typedef TriangleCell< CellType > TriangleCellType; void SetInput( vtkPolyData* iMesh ) { m_PolyData = iMesh; } void Update() { GenerateData(); } MeshType* GetOutput() const { return m_OutputMesh.GetPointer(); } protected: vtkPolyDataToitkQuadEdgeMesh() { m_OutputMesh = MeshType::New(); } ~vtkPolyDataToitkQuadEdgeMesh() {} vtkSmartPointer< vtkPolyData > m_PolyData; MeshPointer m_OutputMesh; void GenerateData() { vtkIdType NbOfPoints = m_PolyData->GetNumberOfPoints(); if( NbOfPoints == 0 ) { itkGenericExceptionMacro( <<"Number Of Points is 0" ); } vtkIdType NbOfCells = m_PolyData->GetNumberOfCells(); if( NbOfCells == 0 ) { itkGenericExceptionMacro( <<"Number Of Cells is 0" ); } PointsContainerPointer points = m_OutputMesh->GetPoints(); points->Reserve( NbOfPoints ); double vtk_p[3]; PointType itk_p; unsigned int dim; for( vtkIdType i = 0; i < NbOfPoints; ++i ) { m_PolyData->GetPoint( i, vtk_p ); for( dim = 0; dim < 3; ++dim ) { itk_p[dim] = static_cast< CoordType >( vtk_p[dim] ); } m_OutputMesh->SetPoint( i, itk_p ); } for( vtkIdType i = 0; i < NbOfCells; ++i ) { vtkIdList* cell_list = vtkIdList::New(); m_PolyData->GetCellPoints( i, cell_list ); CellAutoPointer cell; TriangleCellType *triangleCell = new TriangleCellType; for ( vtkIdType k = 0; k < cell_list->GetNumberOfIds(); ++k ) { triangleCell->SetPointId( k, cell_list->GetId( k ) ); } cell.TakeOwnership(triangleCell); m_OutputMesh->SetCell(i, cell); cell_list->Delete(); } } private: vtkPolyDataToitkQuadEdgeMesh( const Self& ); void operator = ( const Self & ); }; } #endif // __vtkPolyDataToitkQuadEdgeMesh_h GoFigure2-v0.9.0/Code/Filters/Mesh/itkQuadEdgeMeshTovtkPolyData.h0000644000175000017500000000713111667757442024417 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkQuadEdgeMeshTovtkPolyData_h #define __itkQuadEdgeMeshTovtkPolyData_h #include "vtkPoints.h" #include "vtkCellArray.h" #include "vtkPolyData.h" #include "vtkSmartPointer.h" #include "itkQuadEdgeMesh.h" #include "itkTriangleCell.h" #include "itkObject.h" namespace itk { /** \class QuadEdgeMeshTovtkPolyData */ template< class TMesh > class QuadEdgeMeshTovtkPolyData : public Object { public: typedef QuadEdgeMeshTovtkPolyData Self; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; typedef Object Superclass; /** Run-time type information (and related methods). */ itkTypeMacro( QuadEdgeMeshTovtkPolyData, Object ); /** Method for creation through the object factory. */ itkNewMacro(Self); typedef TMesh MeshType; typedef typename MeshType::Pointer MeshPointer; typedef typename MeshType::PointIdentifier PointIdentifier; typedef typename MeshType::PointType PointType; typedef typename MeshType::PointsContainer PointsContainer; typedef typename MeshType::PointsContainerPointer PointsContainerPointer; typedef typename MeshType::PointsContainerConstIterator PointsContainerConstIterator; typedef typename MeshType::CellType CellType; typedef typename MeshType::CellsContainerPointer CellsContainerPointer; typedef typename MeshType::CellsContainerConstIterator CellsContainerConstIterator; void SetInput( MeshType* mesh ); vtkPolyData * GetOutput(); void Update(); protected: QuadEdgeMeshTovtkPolyData( ); virtual ~QuadEdgeMeshTovtkPolyData( ); void GenerateData(); MeshPointer m_itkMesh; vtkSmartPointer< vtkPolyData > m_PolyData; }; } #include "itkQuadEdgeMeshTovtkPolyData.txx" #endif // __itkQuadEdgeMeshTovtkPolyData_h GoFigure2-v0.9.0/Code/Filters/itkGaussianProfileMatchingImageFilter.txx0000644000175000017500000002134411667757442026016 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkGaussianProfileMatchingImageFilter_txx #define __itkGaussianProfileMatchingImageFilter_txx #include "itkGaussianProfileMatchingImageFilter.h" namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage > ::GaussianProfileMatchingImageFilter() : m_SigmaForm (2.0), m_LargestCellRadius (4.0) { m_Blob = 0; this->Superclass::SetNumberOfRequiredInputs (1); this->Superclass::SetNumberOfRequiredOutputs (1); this->Superclass::SetNthOutput ( 0, TInputImage::New() ); } template< class TFeatureImage, class TInputImage, class TSegmentImage > typename GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage >:: ImagePointer GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage > ::InitializeBlob (FeatureImageSpacingType spacing, FeatureImageSizeType CellExtent) { ImageRegionType blobRegion; ImageIndexType blobStart, blobOrigin; unsigned int i; for ( i = 0; i < ImageDimension; i++ ) { blobOrigin[i] = static_cast< ImageSizeValueType >(CellExtent[i] / 2); blobStart[i] = 0; } blobRegion.SetSize (CellExtent); blobRegion.SetIndex (blobStart); ImagePointer blob = ImageType::New(); blob->SetRegions (blobRegion); blob->Allocate(); blob->SetSpacing (spacing); float T = -1. / ( 2. * m_SigmaForm * m_SigmaForm ); ImageIndexType idx; float dx, sum; IndexIteratorType blobIt( blob, blob->GetLargestPossibleRegion() ); for ( blobIt.GoToBegin(); !blobIt.IsAtEnd(); ++blobIt ) { idx = blobIt.GetIndex(); sum = 0; for ( i = 0; i < ImageDimension; ++i ) { dx = ( idx[i] - blobOrigin[i] ) * spacing[i]; sum += dx * dx; } blobIt.Set ( static_cast< ImagePixelType >( vcl_exp (sum * T) ) ); } return ( blob ); } template< class TFeatureImage, class TInputImage, class TSegmentImage > typename GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage >::ImagePixelType GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage > ::PearsonCorrelation (ImageRegionType & region) { unsigned int n(0); double x(0), y (0), xy (0), x2 (0), y2 (0); IteratorType inputIt1( m_Blob, m_Blob->GetLargestPossibleRegion() ); FeatureConstIteratorType inputIt2(this->GetInput(), region); ImagePixelType p1; FeatureImagePixelType p2; for ( inputIt1.GoToBegin(), inputIt2.GoToBegin(); !inputIt1.IsAtEnd(); ++inputIt1, ++inputIt2, ++n ) { p1 = inputIt1.Get(); p2 = inputIt2.Get(); x += p1; y += p2; xy += p1 * p2; x2 += p1 * p1; y2 += p2 * p2; } double d = ( static_cast< double >( n ) * x2 - x * x ) * ( static_cast< double >( n ) * y2 - y * y ); if ( d > vnl_math::eps ) { return static_cast< ImagePixelType >( ( ( static_cast< double >( n ) * xy ) - ( x * y ) ) / vcl_sqrt (d) ); } else { return 0; } } template< class TFeatureImage, class TInputImage, class TSegmentImage > void GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage >::EnlargeOutputRequestedRegion( DataObject *output) { Superclass::EnlargeOutputRequestedRegion(output); output->SetRequestedRegionToLargestPossibleRegion(); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage >::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); if ( this->GetInput() ) { FeatureImagePointer image = const_cast< FeatureImageType * >( this->GetInput() ); image->SetRequestedRegionToLargestPossibleRegion(); } } template< class TFeatureImage, class TInputImage, class TSegmentImage > void GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage >::BeforeThreadedGenerateData() { FeatureImageConstPointer input = this->GetInput(); FeatureImageSizeType inputSize = input->GetLargestPossibleRegion().GetSize(); FeatureImageSpacingType spacing = input->GetSpacing(); unsigned int i; for ( i = 0; i < ImageDimension; ++i ) { m_CellExtent[i] = static_cast< FeatureImageSizeValueType > (2 * m_LargestCellRadius / spacing[i]); if ( m_CellExtent[i] % 2 == 1 ) { m_CellExtent[i] += 1; } } // Define a image region to run windowing on FeatureImageIndexType start; FeatureImageSizeType size; for ( i = 0; i < ImageDimension; i++ ) { start[i] = static_cast< FeatureImageSizeValueType >(m_CellExtent[i] / 2); size[i] = inputSize[i] - m_CellExtent[i] + 1; } m_ImageRegion.SetSize (size); m_ImageRegion.SetIndex (start); ImagePointer output = this->GetOutput(); output->FillBuffer(-1.0); // Initialize Gaussian blob m_Blob = InitializeBlob (spacing, m_CellExtent); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage >::AfterThreadedGenerateData() { ImagePointer output = this->GetOutput(); IndexIteratorType outIt( output, output->GetLargestPossibleRegion() ); FeatureImageIndexType idx; outIt.GoToBegin(); while ( !outIt.IsAtEnd() ) { idx = outIt.GetIndex(); if ( !m_ImageRegion.IsInside(idx) ) { outIt.Set(0); } ++outIt; } } template< class TFeatureImage, class TInputImage, class TSegmentImage > void GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage >::ThreadedGenerateData( const ImageRegionType & windowRegion, #ifdef ITKv4 ThreadIdType threadId ) #else int threadId) #endif { (void)threadId; ImagePointer output = this->GetOutput(); //Set window region size and start locations FeatureImageRegionType kernelRegion; kernelRegion.SetSize (m_CellExtent); IndexIteratorType outIt(output, windowRegion); FeatureImageIndexType idx, windowStart; ImagePixelType p; unsigned int i; outIt.GoToBegin(); while ( !outIt.IsAtEnd() ) { idx = outIt.GetIndex(); if ( m_ImageRegion.IsInside(idx) ) { for ( i = 0; i < ImageDimension; ++i ) { windowStart[i] = idx[i] - static_cast< ImageSizeValueType >( m_CellExtent[i] / 2 ); } kernelRegion.SetIndex (windowStart); p = PearsonCorrelation (kernelRegion); outIt.Set(p); } ++outIt; } } template< class TFeatureImage, class TInputImage, class TSegmentImage > void GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage >::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf (os, indent); os << indent << "Class Name: " << GetNameOfClass() << std::endl; os << indent << "SigmaForm: " << GetSigmaForm() << std::endl; os << indent << "Largest cell radius: " << GetLargestCellRadius() << std::endl; } } /* end namespace itk */ #endif GoFigure2-v0.9.0/Code/Filters/itkMultiScaleLoGDistanceImageFilter.h0000644000175000017500000001441211667757442024771 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkMultiScaleLoGDistanceImageFilter_h #define __itkMultiScaleLoGDistanceImageFilter_h #include "itkImageToImageFilter.h" #include #include "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" #include "itkNumericTraits.h" #include "itkPixelTraits.h" namespace itk { /**\class MultiScaleLoGDistanceImageFilter * \brief 3D blob structures detection based on multiscale LoG filter and * distance map information. */ template< class InputImageType, class DistanceMapImageType = InputImageType, class OutputImageType = InputImageType > class MultiScaleLoGDistanceImageFilter: public ImageToImageFilter< InputImageType, OutputImageType > { public: /** Standard class typedefs. */ typedef MultiScaleLoGDistanceImageFilter Self; typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(MultiScaleLoGDistanceImageFilter, ImageToImageFilter); itkStaticConstMacro (ImageDimension, unsigned int, InputImageType::ImageDimension); /** Some convenient typedefs. */ typedef typename InputImageType::Pointer InputImagePointer; typedef typename InputImageType::ConstPointer InputImageConstPointer; typedef typename InputImageType::PixelType InputPixelType; typedef typename DistanceMapImageType::Pointer DistanceMapImagePointer; typedef typename DistanceMapImageType::ConstPointer ConstDistanceMapImagePointer; typedef typename DistanceMapImageType::PixelType DistanceMapPixelType; typedef typename OutputImageType::Pointer OutputImagePointer; typedef typename OutputImageType::PixelType OutputPixelType; typedef ImageRegionConstIterator< InputImageType > ConstInputIteratorType; typedef ImageRegionConstIterator< DistanceMapImageType > ConstDistanceMapIteratorType; typedef ImageRegionIterator< OutputImageType > OutputIteratorType; typedef ImageRegionIterator< OutputImageType > ConstLoGIteratorType; typedef itk::LaplacianRecursiveGaussianImageFilter< InputImageType, OutputImageType > LoGFilterType; typedef typename LoGFilterType::Pointer LoGFilterPointer; /** Set Squared Signed Distance Map(SDM) of the input image to process (mandatory) : * Distances must be expressed in image spacing units, * use SetUseImageSpacing of your distance map filter to 'true' * SDM must be negative inside blobs */ void SetDistanceMap(const DistanceMapImagePointer distanceMap) { m_DistanceMap = distanceMap; } /** Define the minimum sigma of the Guassian filter for scale adapting */ itkSetMacro(SigmaMin, double); /** Define the maximum sigma of the Guassian filter for scale adapting */ itkSetMacro(SigmaMax, double); /** Returns the minimum sigma of the Guassian filter for sgeFilter.h:125:cale adapting */ itkGetMacro(SigmaMin, double); /** Returns the maximum sigma of the Guassian filter for scale adapting */ itkGetMacro(SigmaMax, double); /** Set Number of Scales (Scale steps : the LoG runs for each step)*/ itkSetMacro(NumberOfSigmaSteps, int); /** Get Number of Scales (Scale steps : the LoG runs for each step)*/ itkGetMacro(NumberOfSigmaSteps, int); /** Set if possible to compute outside of objects (in positive SDM regions)*/ itkSetMacro(ComputeOutsideForeground, bool); /** Get if possible to compute outside of objects (in positive SDM regions)*/ itkGetMacro(ComputeOutsideForeground, bool); protected: // constructor destructor, itk functions... MultiScaleLoGDistanceImageFilter(); ~MultiScaleLoGDistanceImageFilter() {} void PrintSelf(std::ostream & os, Indent indent) const; void GenerateData(void); // Variables double m_SigmaMin; double m_SigmaMax; double m_Sigma; int m_NumberOfSigmaSteps; bool m_ComputeOutsideForeground; ConstDistanceMapImagePointer m_DistanceMap; // LoG filter LoGFilterPointer m_LoGFilter; private: //purposely not implemented MultiScaleLoGDistanceImageFilter(const Self &); void operator=(const Self &); //purposely not implemented void UpdateMaximumResponse(const int & scaleLevel); double ComputeSigmaValue(int scaleLevel); }; } /* namespace itk */ #ifndef ITK_MANUAL_INSTANTIATION #include "itkMultiScaleLoGDistanceImageFilter.txx" #endif #endif GoFigure2-v0.9.0/Code/Filters/itkViscousWatershedTransform.txx0000644000175000017500000001157711667757442024344 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkViscousWatershedTransform_txx #define __itkViscousWatershedTransform_txx #include "itkViscousWatershedTransform.h" namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > ViscousWatershedTransform< TFeatureImage, TInputImage, TSegmentImage > ::ViscousWatershedTransform() { this->Superclass::SetNumberOfRequiredInputs (1); this->Superclass::SetNumberOfRequiredOutputs (1); m_InitialLevel = 0; m_FinalLevel = 255; m_Increment = 1; m_LargestRadius = 10; m_Slope = 10; this->Superclass::SetNthOutput ( 0, TFeatureImage::New() ); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void ViscousWatershedTransform< TFeatureImage, TInputImage, TSegmentImage >::GenerateData() { FeatureImageConstPointer m_Input = this->GetInput(); FeatureImageRegionType region = m_Input->GetLargestPossibleRegion(); FeatureImagePointer m_Output; { ThresholdFilterPointer m_threshold = ThresholdFilterType::New(); m_threshold->SetLowerThreshold (0); m_threshold->SetUpperThreshold (m_InitialLevel); m_threshold->SetInsideValue (m_InitialLevel); m_threshold->SetOutsideValue (0); m_threshold->SetInput (m_Input); m_threshold->Update(); m_Output = m_threshold->GetOutput(); m_Output->DisconnectPipeline(); } typename StructuringElementType::SizeType ballSize; FeatureIteratorType oIt(m_Output, region); unsigned int radius; for ( unsigned int i = m_InitialLevel + m_Increment; i <= m_FinalLevel; i = i + m_Increment ) { std::cout << i << std::endl; // Extract levelset of the function ThresholdFilterPointer m_threshold = ThresholdFilterType::New(); m_threshold->SetLowerThreshold (0); m_threshold->SetUpperThreshold (i); m_threshold->SetInsideValue (0); m_threshold->SetOutsideValue (1); m_threshold->SetInput (m_Input); m_threshold->Update(); // Do closing if ( i > m_LargestRadius * m_Slope ) { radius = 1; } else { radius = static_cast< unsigned int >(m_LargestRadius - i / m_Slope); } ballSize.Fill(radius); StructuringElementType structuringElement; structuringElement.SetRadius(ballSize); structuringElement.CreateStructuringElement(); ClosingFilterPointer close = ClosingFilterType::New(); close->SetKernel(structuringElement); close->SetInput( m_threshold->GetOutput() ); close->SetForegroundValue(1); close->Update(); // Iterate over the output image FeatureIteratorType iIt(close->GetOutput(), region); iIt.GoToBegin(); oIt.GoToBegin(); while ( !oIt.IsAtEnd() ) { if ( ( oIt.Get() == 0 ) && ( iIt.Get() == 0 ) ) { oIt.Set(i); } ++oIt; ++iIt; } } this->GraftOutput(m_Output); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void ViscousWatershedTransform< TFeatureImage, TInputImage, TSegmentImage >::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf (os, indent); } } /* end namespace itk */ #endifGoFigure2-v0.9.0/Code/Filters/itkGradientWeightedIntensityImageFilter.h0000644000175000017500000001612711667757442026004 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkGradientWeightedIntensityImageFilter_h #define __itkGradientWeightedIntensityImageFilter_h #if defined( _MSC_VER ) #pragma warning ( disable : 4786 ) #endif #ifdef __BORLANDC__ #define ITK_LEAN_AND_MEAN #endif #include "itkImageToImageFilter.h" #include "itkGradientMagnitudeRecursiveGaussianImageFilter.h" #include "itkSigmoidImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkMultiScaleLoGImageFilter.h" #include "itkRescaleIntensityImageFilter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" #include "itkImageRegion.h" #include "itkRegion.h" #include "itkIndex.h" #include "itkSize.h" #include "itkImageFileWriter.h" namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > class GradientWeightedIntensityImageFilter: public ImageToImageFilter< TFeatureImage, TInputImage > { public: typedef GradientWeightedIntensityImageFilter Self; typedef ImageToImageFilter< TFeatureImage, TInputImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkStaticConstMacro (ImageDimension, unsigned int, TFeatureImage::ImageDimension); /** Method for creation through object factory */ itkNewMacro (Self); /** Run-time type information */ itkTypeMacro (GradientWeightedIntensityImageFilter, ImageToImageFilter); /** Display */ void PrintSelf(std::ostream & os, Indent indent) const; typedef TFeatureImage FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef typename FeatureImageType::ConstPointer FeatureImageConstPointer; typedef typename FeatureImageType::PixelType FeatureImagePixelType; typedef typename FeatureImageType::RegionType FeatureImageRegionType; typedef typename FeatureImageType::SizeType FeatureImageSizeType; typedef typename FeatureImageSizeType::SizeValueType FeatureImageSizeValueType; typedef typename FeatureImageType::SpacingType FeatureImageSpacingType; typedef typename FeatureImageType::IndexType FeatureImageIndexType; typedef typename FeatureImageType::PointType FeatureImagePointType; typedef TInputImage ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::PixelType ImagePixelType; typedef typename ImageType::RegionType ImageRegionType; typedef typename ImageType::SizeType ImageSizeType; typedef typename ImageSizeType::SizeValueType ImageSizeValueType; typedef typename ImageType::SpacingType ImageSpacingType; typedef typename ImageType::IndexType ImageIndexType; typedef typename ImageType::PointType ImagePointType; typedef TSegmentImage SegmentImageType; typedef typename SegmentImageType::Pointer SegmentImagePointer; typedef typename SegmentImageType::ConstPointer SegmentImageConstPointer; typedef typename SegmentImageType::IndexType SegmentImageIndexType; typedef typename SegmentImageType::PixelType SegmentImagePixelType; typedef MultiScaleLoGImageFilter< FeatureImageType, ImageType > MultiScaleLoGFilterType; typedef typename MultiScaleLoGFilterType::Pointer MultiScaleLoGFilterPointer; typedef RescaleIntensityImageFilter< ImageType, ImageType > RescaleFilterType; typedef typename RescaleFilterType::Pointer RescaleFilterPointer; typedef GradientMagnitudeRecursiveGaussianImageFilter< FeatureImageType, ImageType > GradientFilterType; typedef typename GradientFilterType::Pointer GradientFilterPointer; typedef SigmoidImageFilter< ImageType, ImageType > SigmoidFilterType; typedef typename SigmoidFilterType::Pointer SigmoidFilterPointer; typedef ImageRegionConstIterator< FeatureImageType > ConstIteratorType; typedef ImageRegionIterator< FeatureImageType > FIteratorType; typedef ImageRegionIterator< ImageType > IteratorType; typedef ImageRegionIteratorWithIndex< ImageType > IndexIteratorType; void SetBlob(FeatureImagePointer blob) { m_Blob = blob; } void SetForm(ImagePointer form) { m_Form = form; } itkGetConstMacro (LargestCellRadius, double); itkSetMacro (LargestCellRadius, double); itkGetConstMacro (NucleiSigma, double); itkSetMacro (NucleiSigma, double); itkGetConstMacro (Alpha, double); itkSetMacro (Alpha, double); itkGetConstMacro (Beta, double); itkSetMacro (Beta, double); itkGetConstMacro (Gamma, double); itkSetMacro (Gamma, double); protected: GradientWeightedIntensityImageFilter(); ~GradientWeightedIntensityImageFilter() {} void Normalize(); void GenerateData(); double m_LargestCellRadius; double m_NucleiSigma; double m_Alpha; double m_Beta; double m_Gamma; FeatureImagePointer m_Blob; ImagePointer m_Form; private: GradientWeightedIntensityImageFilter (Self &); // intentionally not // implemented void operator=(const Self &); // intentionally not // implemented }; } /* namespace itk */ #include "itkGradientWeightedIntensityImageFilter.txx" #endif GoFigure2-v0.9.0/Code/Filters/itkPreprocessImageFilter.txx0000644000175000017500000000773011667757442023400 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkPreprocessImageFilter_txx #define __itkPreprocessImageFilter_txx #include "itkPreprocessImageFilter.h" namespace itk { template< class TInputImage, class TOutputImage > PreprocessImageFilter< TInputImage, TOutputImage > ::PreprocessImageFilter() : m_LargestCellRadius (4.0) { this->Superclass::SetNumberOfRequiredInputs (1); this->Superclass::SetNumberOfRequiredOutputs (1); this->Superclass::SetNthOutput ( 0, TOutputImage::New() ); } template< class TInputImage, class TOutputImage > void PreprocessImageFilter< TInputImage, TOutputImage >::GenerateData() { InputCastPointer m_CastInput = InputCastType::New(); m_CastInput->SetInput ( this->GetInput() ); m_CastInput->Update(); ImageSpacingType spacing = this->GetInput()->GetSpacing(); ImageSizeType radius; for ( unsigned int j = 0; j < ImageDimension; j++ ) { radius[j] = static_cast< ImageSizeValueType >( 0.3 * m_LargestCellRadius / spacing[j]); } ImagePointer cellImg; { MedianFilterPointer m_Median = MedianFilterType::New(); m_Median = MedianFilterType::New(); m_Median->SetRadius (radius); m_Median->SetInput ( m_CastInput->GetOutput() ); SmoothingFilterPointer m_smooth = SmoothingFilterType::New(); m_smooth->SetInput ( m_Median->GetOutput() ); m_smooth->SetSigma (m_LargestCellRadius / 15); GrayscaleFillholePointer m_fillHole = GrayscaleFillholeFilterType::New(); m_fillHole->SetInput ( m_smooth->GetOutput() ); m_fillHole->SetFullyConnected (0); m_fillHole->Update(); cellImg = m_fillHole->GetOutput(); cellImg->DisconnectPipeline(); } OutputCastPointer m_CastOutput = OutputCastType::New(); m_CastOutput->SetInput (cellImg); m_CastOutput->GraftOutput ( this->GetOutput() ); m_CastOutput->Update(); this->GraftOutput ( m_CastOutput->GetOutput() ); } template< class TInputImage, class TOutputImage > void PreprocessImageFilter< TInputImage, TOutputImage >::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf (os, indent); os << indent << "Class Name: " << GetNameOfClass() << std::endl; os << indent << "Largest cell radius: " << GetLargestCellRadius() << std::endl; } } /* end namespace itk */ #endifGoFigure2-v0.9.0/Code/Filters/itkChanAndVeseSegmentationFilter.h0000644000175000017500000002760411667757442024413 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkChanAndVeseSegmentationFilter_h #define __itkChanAndVeseSegmentationFilter_h #include "itkScalarChanAndVeseSparseLevelSetImageFilter.h" #include "itkScalarChanAndVeseLevelSetFunction.h" #include "itkScalarChanAndVeseLevelSetFunctionData.h" #include "itkConstrainedRegionBasedLevelSetFunctionSharedData.h" #include "itkAtanRegularizedHeavisideStepFunction.h" #include "itkFastMarchingImageFilter.h" #include "itkImageToVTKImageFilter.h" #include "itkImageFileWriter.h" #include "itkPreprocessImageFilter.h" #include "itkRegionOfInterestImageFilter.h" namespace itk { /** * \class ChanAndVeseSegmentationFilter * \brief */ template< class TFeatureImage > class ChanAndVeseSegmentationFilter:public Object { public: typedef ChanAndVeseSegmentationFilter Self; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; typedef Object Superclass; /** Run-time type information (and related methods). */ itkTypeMacro(ChanAndVeseSegmentationFilter, Object); /** New macro for creation of through a Smart Pointer */ itkNewMacro(Self); itkStaticConstMacro(Dimension, unsigned int, TFeatureImage::ImageDimension); typedef Image< float, Dimension > InternalImageType; typedef typename InternalImageType::Pointer InternalImagePointer; typedef typename InternalImageType::PointType InternalPointType; typedef typename InternalPointType::CoordRepType InternalCoordRepType; typedef typename InternalImageType::IndexType InternalIndexType; typedef typename InternalIndexType::IndexValueType InternalIndexValueType; typedef typename InternalImageType::SizeType InternalSizeType; typedef typename InternalSizeType::SizeValueType InternalSizeValueType; typedef typename InternalImageType::RegionType InternalRegionType; typedef typename InternalImageType::PixelType InternalPixelType; typedef typename InternalImageType::SpacingType InternalSpacingType; typedef ImageRegionIteratorWithIndex< InternalImageType > InternalRegionIterator; typedef TFeatureImage FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef typename FeatureImageType::SizeType FeatureSizeType; typedef typename FeatureImageType::SpacingType FeatureSpacingType; typedef TFeatureImage OutputImageType; typedef typename OutputImageType::Pointer OutputImagePointer; typedef ScalarChanAndVeseLevelSetFunctionData< InternalImageType, FeatureImageType > DataHelperType; typedef ConstrainedRegionBasedLevelSetFunctionSharedData< InternalImageType, FeatureImageType, DataHelperType > SharedDataHelperType; typedef ScalarChanAndVeseLevelSetFunction< InternalImageType, FeatureImageType, SharedDataHelperType > FunctionType; typedef ScalarChanAndVeseSparseLevelSetImageFilter< InternalImageType, FeatureImageType, OutputImageType, FunctionType, SharedDataHelperType > MultiLevelSetType; typedef typename MultiLevelSetType::Pointer MultiLevelSetPointer; typedef itk::PreprocessImageFilter< FeatureImageType, FeatureImageType > PreprocessFilterType; typedef typename PreprocessFilterType::Pointer PreprocessFilterPointer; typedef RegionOfInterestImageFilter< FeatureImageType, FeatureImageType > ROIFilterType; typedef typename ROIFilterType::Pointer ROIFilterPointer; typedef AtanRegularizedHeavisideStepFunction< InternalPixelType, InternalPixelType > DomainFunctionType; typedef typename DomainFunctionType::Pointer DomainFunctionPointer; typedef FastMarchingImageFilter< InternalImageType, InternalImageType > FastMarchingFilterType; typedef typename FastMarchingFilterType::NodeContainer NodeContainer; typedef typename FastMarchingFilterType::NodeType NodeType; void SetCenter(const InternalPointType & iC) { m_Center = iC; } InternalPointType GetCenter() const { return m_Center; } void SetRadius(const InternalCoordRepType & iR) { m_Radius = iR; } InternalCoordRepType GetRadius() const { return m_Radius; } void SetFeatureImage(FeatureImageType *iImage) { m_FeatureImage = iImage; } void SetNumberOfIterations(int iNumberOfIterations) { m_NumberOfIterations = iNumberOfIterations; } void SetCurvatureWeight(int iCurvatureWeight) { m_CurvatureWeight = iCurvatureWeight; } void Update() { GenerateData(); } InternalImagePointer GetOutput() { return m_Output; } itkGetConstMacro (Preprocess, bool); itkSetMacro (Preprocess, bool); protected: ChanAndVeseSegmentationFilter():m_FeatureImage(0) { m_Center.Fill(0.); m_Size.Fill(0); m_Radius = 0.; m_Preprocess = false; m_Output = InternalImageType::New(); } ~ChanAndVeseSegmentationFilter() {} FeatureImagePointer m_FeatureImage; // Raw image -- very large in size InternalPointType m_Center; // Center of the cell/nucleus InternalSizeType m_Size; // Level-set image size InternalCoordRepType m_Radius; // Radius of the cell InternalImagePointer m_Output; bool m_Preprocess; int m_NumberOfIterations; int m_CurvatureWeight; void GenerateData() { if ( m_FeatureImage.IsNull() ) { std::cerr << "m_FeatureImage is Null" << std::endl; return; } FeatureSpacingType spacing = m_FeatureImage->GetSpacing(); FeatureSizeType inputSize = m_FeatureImage->GetLargestPossibleRegion().GetSize(); InternalIndexType start2; InternalPointType origin; InternalIndexType cen; if (m_Radius == 0 ) { origin = m_FeatureImage->GetOrigin(); m_Size = inputSize; //node.SetValue( (static_cast(m_Size[0]) *spacing[0])/4.); m_Radius = static_cast(m_Size[0]) *spacing[0] / 2.; for( unsigned int j = 0; j < Dimension; j++ ) { start2[j] = 0; cen[j] = static_cast( m_Size[j] / 2 ); } } else { for ( unsigned int j = 0; j < Dimension; j++ ) { m_Size[j] = 1 + 4. * static_cast< InternalSizeValueType >( m_Radius / spacing[j] ); cen[j] = static_cast< InternalSizeValueType >( 2 * m_Radius / spacing[j] ); origin[j] = m_Center[j] - 2 * m_Radius; start2[j] = 0; } } NodeType node; node.SetValue(-m_Radius / 2); node.SetIndex(cen); std::cout << "Spacing: " << spacing << std::endl; std::cout << "Input Size: " << inputSize << std::endl; std::cout << "Output Size: " << m_Size << std::endl; std::cout << "Origin: " << origin << std::endl; std::cout << "Radius: " << m_Radius << std::endl; std::cout << "Center: " << cen << std::endl; typename NodeContainer::Pointer seeds = NodeContainer::New(); seeds->Initialize(); seeds->InsertElement(0, node); InternalRegionType region2; region2.SetSize(m_Size); region2.SetIndex(start2); /// \todo Allocate image InternalImagePointer image = InternalImageType::New(); image->SetRegions(region2); image->CopyInformation(m_FeatureImage); image->Allocate(); //------------------------------- // not used //------------------------------- InternalRegionIterator r_it(image, region2); r_it.GoToBegin(); InternalIndexType idx; //float or double d; double d; double r = m_Radius / 2; while ( !r_it.IsAtEnd() ) { idx = r_it.GetIndex(); d = 0.; for ( unsigned int dim = 0; dim < Dimension; dim++ ) { d += ( idx[dim] - cen[dim] ) * ( idx[dim] - cen[dim] ) * spacing[dim] * spacing[dim]; } r_it.Set(vcl_sqrt(d) - r); ++r_it; } //------------------------------- //------------------------------- FeatureImagePointer feature; if ( m_Preprocess ) { PreprocessFilterPointer preprocess = PreprocessFilterType::New(); preprocess->SetInput (m_FeatureImage); preprocess->SetLargestCellRadius (m_Radius); // in real coordinates try { preprocess->Update(); } catch ( itk::ExceptionObject & err ) { std::cerr << "preprocess Exception:" << err << std::endl; } feature = preprocess->GetOutput(); feature->SetOrigin(origin); feature->DisconnectPipeline(); } else { feature = m_FeatureImage; } DomainFunctionPointer domainFunction = DomainFunctionType::New(); domainFunction->SetEpsilon(1.); typedef std::vector< unsigned int > VectorType; VectorType lookUp(1, 1); image->CopyInformation(feature); MultiLevelSetPointer LevelSetFilter = MultiLevelSetType::New(); LevelSetFilter->SetFunctionCount(1); LevelSetFilter->SetLookup(lookUp); LevelSetFilter->SetFeatureImage(feature); LevelSetFilter->SetLevelSet(0, image); LevelSetFilter->SetNumberOfIterations(m_NumberOfIterations); LevelSetFilter->SetMaximumRMSError(0); LevelSetFilter->SetUseImageSpacing(1); LevelSetFilter->SetInPlace(false); LevelSetFilter->GetDifferenceFunction(0)->SetDomainFunction(domainFunction); LevelSetFilter->GetDifferenceFunction(0)-> SetCurvatureWeight(m_CurvatureWeight); LevelSetFilter->GetDifferenceFunction(0)->SetAreaWeight(0.); LevelSetFilter->GetDifferenceFunction(0)->SetLambda1(1.); LevelSetFilter->GetDifferenceFunction(0)->SetLambda2(1.); try { LevelSetFilter->Update(); } catch ( itk::ExceptionObject & err ) { std::cerr << "levelsetfilter Exception:" << err << std::endl; } m_Output->Graft( LevelSetFilter->GetLevelSet(0) ); } private: ChanAndVeseSegmentationFilter(const Self &); void operator=(const Self &); }; } #endif GoFigure2-v0.9.0/Code/Filters/itkMultiScaleLoGImageFilter.txx0000644000175000017500000001171111667757442023711 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkMultiScaleLoGImageFilter.txx,v $ Language: C++ Date: $Date: 2007/06/20 16:03:23 $ Version: $Revision: 1.13 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkMultiScaleLoGImageFilter_txx #define __itkMultiScaleLoGImageFilter_txx #include "itkMultiScaleLoGImageFilter.h" #include "vnl/vnl_math.h" #define EPSILON 1e-03 namespace itk { /** * Constructor */ template< typename TInputImage, typename TOutputImage > MultiScaleLoGImageFilter < TInputImage, TOutputImage > ::MultiScaleLoGImageFilter() { m_SigmaMin = 0.2; m_SigmaMax = 2.0; m_NumberOfSigmaSteps = 4; m_LaplacianFilter = LaplacianFilterType::New(); } template< typename TInputImage, typename TOutputImage > void MultiScaleLoGImageFilter < TInputImage, TOutputImage > ::GenerateData() { // Allocate the output this->GetOutput()->SetBufferedRegion( this->GetOutput()->GetRequestedRegion() ); this->GetOutput()->Allocate(); this->GetOutput()->FillBuffer(-1000); InputImageConstPointer input = this->GetInput(); m_LaplacianFilter->SetInput(input); m_LaplacianFilter->SetNormalizeAcrossScale(false); double sigma = m_SigmaMin; int scaleLevel = 1; while ( sigma <= m_SigmaMax ) { m_LaplacianFilter->SetSigma(sigma); m_LaplacianFilter->Update(); this->UpdateMaximumResponse(); sigma = this->ComputeSigmaValue(scaleLevel); scaleLevel++; } } template< typename TInputImage, typename TOutputImage > void MultiScaleLoGImageFilter < TInputImage, TOutputImage > ::UpdateMaximumResponse() { IteratorType oit( this->GetOutput(), this->GetOutput()->GetLargestPossibleRegion() ); oit.GoToBegin(); IteratorType it( m_LaplacianFilter->GetOutput(), m_LaplacianFilter->GetOutput()->GetLargestPossibleRegion() ); it.GoToBegin(); while ( !oit.IsAtEnd() ) { if ( oit.Value() < it.Value() ) { oit.Value() = it.Value(); } ++oit; ++it; } } template< typename TInputImage, typename TOutputImage > double MultiScaleLoGImageFilter < TInputImage, TOutputImage > ::ComputeSigmaValue(int ScaleLevel) { double stepSize = ( vcl_log(m_SigmaMax) - vcl_log(m_SigmaMin) ) / m_NumberOfSigmaSteps; if ( stepSize <= 1e-10 ) { stepSize = 1e-10; } return ( vcl_exp(vcl_log (m_SigmaMin) + stepSize * ScaleLevel) ); } template< typename TInputImage, typename TOutputImage > void MultiScaleLoGImageFilter < TInputImage, TOutputImage > ::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "SigmaMin: " << m_SigmaMin << std::endl; os << indent << "SigmaMax: " << m_SigmaMax << std::endl; } } // end namespace itk #endif GoFigure2-v0.9.0/Code/Filters/itkCellForegroundExtraction.txx0000644000175000017500000002032111667757442024104 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkCellForegroundExtraction_txx #define __itkCellForegroundExtraction_txx #include "itkCellForegroundExtraction.h" namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > CellForegroundExtraction< TFeatureImage, TInputImage, TSegmentImage > ::CellForegroundExtraction() : m_SigmaForm (2.0), m_ThresholdCellmin (10), m_ThresholdCellmax (30), m_ThresholdMembrane (0), m_ThresholdForm (0.15), m_LargestCellRadius (4.0) { m_Sampling = 0; this->Superclass::SetNumberOfRequiredInputs (2); this->Superclass::SetNumberOfRequiredOutputs (1); this->Superclass::SetNthOutput ( 0, TSegmentImage::New() ); } template< class TFeatureImage, class TInputImage, class TSegmentImage > typename CellForegroundExtraction< TFeatureImage, TInputImage, TSegmentImage >::FeatureImagePointer CellForegroundExtraction< TFeatureImage, TInputImage, TSegmentImage > ::ResampleInput (FeatureImageConstPointer input, FeatureImageSpacingType spacing, FeatureImageSizeType size, FeatureImagePointType origin) { // create the resample filter, transform and interpolator TransformPointer transform = TransformType::New(); transform->SetIdentity(); InterpolatorFeaturePointer interp = InterpolatorFeatureType::New(); ResampleFeatureFilterPointer m_resamp = ResampleFeatureFilterType::New(); m_resamp->SetTransform (transform); m_resamp->SetInterpolator (interp); m_resamp->SetInput (input); m_resamp->SetSize (size); m_resamp->SetOutputOrigin (origin); m_resamp->SetOutputSpacing (spacing); m_resamp->SetDefaultPixelValue (0); m_resamp->Update(); return ( m_resamp->GetOutput() ); } template< class TFeatureImage, class TInputImage, class TSegmentImage > typename CellForegroundExtraction< TFeatureImage, TInputImage, TSegmentImage >::ImagePointer CellForegroundExtraction< TFeatureImage, TInputImage, TSegmentImage > ::Resample (ImagePointer input, FeatureImageSpacingType spacing, FeatureImageSizeType size, FeatureImagePointType origin) { // create the resample filter, transform and interpolator TransformPointer transform = TransformType::New(); transform->SetIdentity(); InterpolatorPointer interp = InterpolatorType::New(); ResampleFilterPointer m_resamp = ResampleFilterType::New(); m_resamp->SetTransform (transform); m_resamp->SetInterpolator (interp); m_resamp->SetInput (input); m_resamp->SetSize (size); m_resamp->SetOutputOrigin (origin); m_resamp->SetOutputSpacing (spacing); m_resamp->SetDefaultPixelValue (0); m_resamp->Update(); return ( m_resamp->GetOutput() ); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void CellForegroundExtraction< TFeatureImage, TInputImage, TSegmentImage >::GenerateData() { FeatureImageConstPointer cellImg = this->GetInput(); FeatureImageSpacingType spacing = cellImg->GetSpacing(); FeatureImageSizeType size = cellImg->GetLargestPossibleRegion().GetSize(); FeatureImagePointType origin = cellImg->GetOrigin(); FeatureImageSpacingType subSpacing; FeatureImageSizeType subSize; float t; for ( unsigned int i = 0; i < ImageDimension; i++ ) { if ( m_Sampling ) { t = m_Sampling[i]; } else { t = 1.0; } subSpacing[i] = spacing[i] * t; subSize[i] = static_cast< ImageSizeValueType >(size[i] / t); } { ImagePointer gaussCorrImg; { FeatureImagePointer rawSubsampledImage = ResampleInput ( cellImg, subSpacing, subSize, origin); GaussProfileFilterPointer gaussCorr = GaussProfileFilterType::New(); gaussCorr->SetInput(rawSubsampledImage); gaussCorr->SetSigmaForm(m_SigmaForm); gaussCorr->SetNumberOfThreads( this->GetNumberOfThreads() ); try { gaussCorr->Update(); } catch (itk::ExceptionObject e) { std::cerr << "Error: " << e << std::endl; } gaussCorrImg = Resample (gaussCorr->GetOutput(), spacing, size, origin); } RescaleFilterPointer m_rescale = RescaleFilterType::New(); m_rescale->SetInput (gaussCorrImg); m_rescale->SetOutputMinimum (0); m_rescale->SetOutputMaximum (1); m_rescale->Update(); gauss = m_rescale->GetOutput(); gauss->DisconnectPipeline(); } FeatureImageConstPointer membraneImg = this->GetInput(1); SegmentImagePointer fg = SegmentImageType::New(); fg->SetRegions( cellImg->GetLargestPossibleRegion() ); fg->CopyInformation(cellImg); fg->Allocate(); fg->FillBuffer(0); // We reuse the space allocated in cellImg to now represent the foreground // Fuzzy thresholding operation SegmentIteratorType oIt( fg, fg->GetLargestPossibleRegion() ); IteratorType GaussIt( gauss, gauss->GetLargestPossibleRegion() ); FeatureConstIteratorType mIt( membraneImg, membraneImg->GetLargestPossibleRegion() ); FeatureConstIteratorType It( cellImg, cellImg->GetLargestPossibleRegion() ); oIt.GoToBegin(); It.GoToBegin(); GaussIt.GoToBegin(); mIt.GoToBegin(); while ( !It.IsAtEnd() ) { if ( ( It.Get() > m_ThresholdCellmax ) && ( mIt.Get() < m_ThresholdMembrane ) ) { oIt.Set (1); } else if ( ( It.Get() > m_ThresholdCellmin ) && ( GaussIt.Get() > m_ThresholdForm ) && ( mIt.Get() < m_ThresholdMembrane ) ) { oIt.Set (1); } else { oIt.Set (0); } ++oIt; ++It; ++GaussIt; ++mIt; } this->GraftOutput (fg); } template< class TFeatureImage, class TInputImage, class TSegmentImage > void CellForegroundExtraction< TFeatureImage, TInputImage, TSegmentImage >::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf (os, indent); os << indent << "Class Name: " << GetNameOfClass() << std::endl; os << indent << "SigmaForm: " << GetSigmaForm() << std::endl; os << indent << "ThresholdCellmin: " << GetThresholdCellmin() << std::endl; os << indent << "ThresholdCellmax: " << GetThresholdCellmax() << std::endl; os << indent << "ThresholdMembrane: " << GetThresholdMembrane() << std::endl; os << indent << "ThresholdForm: " << GetThresholdForm() << std::endl; os << indent << "Largest cell radius: " << GetLargestCellRadius() << std::endl; os << indent << "Sampling factors: "; for ( unsigned int i = 0; i < ImageDimension; i++ ) { std::cout << ( this->m_Sampling )[i] << ' '; } std::cout << std::endl; } } /* end namespace itk */ #endifGoFigure2-v0.9.0/Code/Database/0000755000175000017500000000000011667757442015752 5ustar mathieumathieuGoFigure2-v0.9.0/Code/Database/CMakeLists.txt0000644000175000017500000000000011667757442020500 0ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/0000755000175000017500000000000011667757442014672 5ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/CMakeLists.txt0000644000175000017500000000003011667757442017423 0ustar mathieumathieuADD_SUBDIRECTORY( lib ) GoFigure2-v0.9.0/Code/GUI/lib/0000755000175000017500000000000011667757442015440 5ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/lib/QGoTabElementBase.h0000644000175000017500000001341011667757442021032 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTabElementBase_h #define __QGoTabElementBase_h #include #include #include #include "QGoPlugin.h" #include "QGoDockWidgetStatus.h" #include "QGoGUILibConfigure.h" #include "QGoTraceSettingsWidget.h" #include "QGoToolBarStatus.h" class QAction; class QActionGroup; class QMenu; class QToolBar; class QDockWidget; class QGoPluginManager; /** \class QGoTabElementBase \brief Abstract class for one tab element in GoFigure2. \example GUI/lib/qgotabelementbase.cxx */ class QGOGUILIB_EXPORT QGoTabElementBase:public QMainWindow { Q_OBJECT public: /** \brief Constructor */ explicit QGoTabElementBase(QWidget *parent = 0); /** \brief Destructor */ virtual ~QGoTabElementBase(); typedef std::pair< QGoDockWidgetStatus *, QDockWidget * > QGoDockWidgetStatusPair; /** \brief Get the dimension type of the underlying data set.*/ virtual GoFigure::TabDimensionType GetTabDimensionType() const = 0; virtual std::list< QGoToolBarStatus* > GetToolBarsStatus(); /** \brief Get all actions belonging to View Menu and Toolbar.*/ virtual std::vector< QAction * > ViewActions(); /** \brief Get all actions belonging to View Menu only.*/ virtual std::vector< QAction * > ViewNoToolBarActions(); /** \brief Get all actions belonging to Segmentation Menu and Toolbar. */ virtual std::vector< QAction * > SegmentationActions(); /** \brief Get all actions belonging to Tools Menu and Toolbar. */ virtual std::vector< QAction * > ToolsActions(); /** \brief Get all actions belonging to Bookmark Menu and Toolbar. */ virtual std::vector< QAction * > BookmarkActions(); /** \brief Get all actions belonging to Mode Menu and Toolbar.*/ //virtual std::vector< QAction * > ModeActions(); /** \brief Get all actions belonging to the Traces Toolbar.*/ //virtual std::vector< QAction * > TracesActions(); //virtual QGoToolBarStatus* TracesActions(); /** \brief Get the widget for the trace settings to be added in the TraceSettings Toolbar*/ //virtual QGoTraceSettingsWidget* TraceSettingsWidget(); /** \brief Get all the DockWidgets with its status (visibility, location). */ virtual std::list< QGoDockWidgetStatusPair > & DockWidget(); // virtual QStatusBar* StatusBar(); virtual std::list< QAction * > GetPluginActions(); virtual void SetPluginActions(std::list< QAction * > iList); /** \brief Write Settings for the tab element. */ virtual void WriteSettings() = 0; /** \brief Read Settings for the related tab element.*/ virtual void ReadSettings() = 0; /** * \brief Mouse interaction style set as default */ virtual void DefaultInteractorBehavior(bool){} /** * \brief Mouse interaction style allows user to zoom in/out volume with all * buttons */ virtual void ZoomInteractorBehavior(bool){} /** * \brief Mouse interaction style allows user to Translate volume with all buttons */ virtual void TranslateInteractorBehavior(bool){} void SetStatusBarPointer(QStatusBar* iStatusbar); //virtual void SetTraceSettingsToolBar(QToolBar* iToolBar); virtual void CreateModeToolBar(QMenu* iMenu, QToolBar* iToolBar); virtual void CreateViewToolBar(QMenu* iMenu, QToolBar* iToolBar); protected: std::list< QAction * > m_PluginActionList; std::vector< QAction * > m_ViewActions; QGoToolBarStatus* m_ViewActionsMenuToolBar; std::vector< QAction* > m_ViewNoToolBarActions; std::vector< QAction * > m_SegmentationActions; std::vector< QAction * > m_ToolsActions; std::vector< QAction * > m_BookmarkActions; //std::vector< QAction * > m_ModeActions; QGoToolBarStatus* m_ModeToolBar; //std::vector< QAction * > m_TracesActions; //QGoToolBarStatus* m_TracesActions; //QGoTraceSettingsWidget* m_TraceSettingsWidgetForToolBar; //QToolBar* m_TraceSettingsToolBar; std::list< QGoDockWidgetStatusPair > m_DockWidgetList; std::list< QGoToolBarStatus* > m_ToolBarList; QStatusBar* m_StatusBar; private: Q_DISABLE_COPY(QGoTabElementBase); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoLsmToMegaExportDialog.cxx0000644000175000017500000001775311667757442022762 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoLsmToMegaExportDialog.h" #include #include //------------------------------------------------------------------------- QGoLsmToMegaExportDialog::QGoLsmToMegaExportDialog(QWidget *iParent) : QDialog(iParent), m_LsmPath(""), m_LsmName(""), m_MegaPath(""), m_FileFormatIsPNG(true), m_Counter(0) { this->setupUi(this); m_ProgressDialog = new QProgressDialog("Conversion in progress.", "Cancel", 0, 100, this); ConversionLsmToMegaThreadSend = new ConversionLsmToMegaThread; QObject::connect( ConversionLsmToMegaThreadSend, SIGNAL( ConversionTerminatedSent() ), this, SLOT( ConversionTerminatedReceived() ) ); QObject::connect( ConversionLsmToMegaThreadSend, SIGNAL( InitialisationProgressSent() ), this, SLOT( InitialisationProgressReceived() ) ); QObject::connect( ConversionLsmToMegaThreadSend, SIGNAL( ProgressSent() ), this, SLOT( ProgressReceived() ) ); QObject::connect( m_ProgressDialog, SIGNAL( canceled() ), this, SLOT( CanceledReceived() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoLsmToMegaExportDialog:: ~QGoLsmToMegaExportDialog() { delete ConversionLsmToMegaThreadSend; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLsmToMegaExportDialog::on_selectLsmFile_clicked() { m_LsmPath = QFileDialog::getOpenFileName( this, tr("Select the LSM file to convert"), QDir::currentPath(), tr("Image Files (*.lsm)") ); QFileInfo fileInfo(m_LsmPath); m_LsmName = fileInfo.fileName(); m_LsmName.replace( QString(" "), QString("_") ); // Write the lsm file name in the dialog window lsmFileName->setText(m_LsmName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLsmToMegaExportDialog::on_selectMegaPath_clicked() { m_MegaPath = QFileDialog::getExistingDirectory(this, tr("Open Directory"), QDir::homePath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); m_MegaPath.insert( m_MegaPath.size(), QString("/") ); megaFilePath->setText(m_MegaPath); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLsmToMegaExportDialog::on_outputFormat_activated(int index) { if ( index == 0 ) { m_FileFormatIsPNG = true; } else { m_FileFormatIsPNG = false; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLsmToMegaExportDialog::on_convert_clicked() { if ( m_LsmName.isNull() || m_LsmName.isEmpty() || m_LsmPath.isNull() || m_LsmPath.isEmpty() || m_MegaPath.isNull() || m_MegaPath.isEmpty() ) { /// \todo use QMessageBox std::cerr << "Please select good path for lsm and megacapture" << std::endl; } else { // Disable everything this->lsmFileName->setEnabled(false); this->megaFilePath->setEnabled(false); this->selectLsmFile->setEnabled(false); this->selectMegaPath->setEnabled(false); this->outputFormat->setEnabled(false); this->convert->setEnabled(false); this->label->setEnabled(false); this->selectLSMLabel->setEnabled(false); this->megaFilePath_2->setEnabled(false); this->outputFormatLabel->setEnabled(false); this->label_2->setEnabled(false); this->convertLabel->setText( tr("READS LSM READERS") ); // Set conversion parameters GoFigure::FileType filetype = GoFigure::PNG; if ( !m_FileFormatIsPNG ) { filetype = GoFigure::TIFF; } // Remove extension m_LsmName.replace( QString(".lsm"), QString("_lsm") ); // conversion fonction called from there to enable progress bar ConversionLsmToMegaThreadSend->SetBaseName( m_LsmName.toStdString() ); ConversionLsmToMegaThreadSend->SetLsmPath( m_LsmPath.toStdString() ); ConversionLsmToMegaThreadSend->SetOutputFileType(filetype); ConversionLsmToMegaThreadSend->SetMegaPath( m_MegaPath.toStdString() ); ConversionLsmToMegaThreadSend->start(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLsmToMegaExportDialog::ConversionTerminatedReceived() { ConversionLsmToMegaThreadSend->terminate(); ConversionLsmToMegaThreadSend->exit(); m_ProgressDialog->accept(); this->accept(); } //------------------------------------------------------------------------- /** * \todo check values for progress bar...(ubuntu bug..?) */ //------------------------------------------------------------------------- void QGoLsmToMegaExportDialog::InitialisationProgressReceived() { this->convertLabel->setText( tr("CONVERSION in PROGRESS") ); int sizeProgressBar = ConversionLsmToMegaThreadSend->GetNumberOfPoints(); // if starts at 0 strange things happen... m_Counter = 1; // sizeProgressBar because // +1 because m_Counter starts at 1 // +1 to prevent that the dialoProgressWindow automatically close // then re-open when 100% reached m_ProgressDialog->setRange(0, sizeProgressBar + 5); m_ProgressDialog->setValue(m_Counter); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLsmToMegaExportDialog::ProgressReceived() { m_Counter++; m_ProgressDialog->setValue(m_Counter); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLsmToMegaExportDialog::CanceledReceived() { ConversionLsmToMegaThreadSend->terminate(); ConversionLsmToMegaThreadSend->exit(); this->ConversionTerminatedReceived(); } //-------------------------------------------------------------------------GoFigure2-v0.9.0/Code/GUI/lib/QGoTableWidget.cxx0000644000175000017500000011547411667757442021002 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTableWidget.h" #include #include #include #include #include #include #include #include #include QGoTableWidget::QGoTableWidget(QWidget *iParent) : QTableWidget(iParent) { PrevCol = -1; PrevOrder = -1; QObject::connect( this, SIGNAL( cellClicked(int, int) ), this, SLOT( UpdateColumnsWithCheckBoxes(int, int) ) ); this->setContextMenuPolicy(Qt::CustomContextMenu); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoTableWidget::QGoTableWidget(int rows, int columns, QWidget *iParent) : QTableWidget(rows, columns, iParent), PrevCol(-1), PrevOrder(-1) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoTableWidget::~QGoTableWidget() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::sortItems(int iColumn, Qt::SortOrder iOrder) { if ( ( iColumn != PrevCol ) && ( iOrder != PrevOrder ) ) { PrevCol = iColumn; PrevOrder = iOrder; QTableWidget::sortItems(iColumn, iOrder); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int QGoTableWidget::findValueGivenColumn(int iValue, const QString & iColumn) { int ColumnIndex = findColumnName(iColumn); if ( ColumnIndex == -1 ) { std::cout << "The column figureID has not been found"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; std::cout << std::endl; return -1; } else { for ( int i = 0; i < rowCount(); i++ ) { if ( this->item(i, ColumnIndex)->text().toInt() == iValue ) { return i; } } } return -1; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int QGoTableWidget::findColumnName(const QString & iColumnName) { QStringList ColumnsHeader = recordHeaderNamesOrder(); if ( ColumnsHeader.isEmpty() ) { std::cout << "The QStringlist ColumnsHeader is empty"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return -1; } return ColumnsHeader.indexOf(iColumnName, 0); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QStringList QGoTableWidget::recordHeaderNamesOrder() { QStringList ColumnNamesOrder; for ( int i = 0; i < this->columnCount(); i++ ) { ColumnNamesOrder.append( this->horizontalHeaderItem(i)->text() ); } return ColumnNamesOrder; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::SetVisibleStateForTraceID(unsigned int iTraceID, const std::string & iTraceName, Qt::CheckState iState, bool EmitSignal) { unsigned int ColumnIndex = this->findColumnName("Show"); int RowIndex = this->GetRowForTraceID(iTraceID, iTraceName); QTableWidgetItem* temp = this->item(RowIndex, ColumnIndex); if( temp ) { this->setVisibleStateCheckBox( temp, iState, EmitSignal); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::SetVisibleStateForListTraceIDs( const std::list< unsigned int > & iListTraceIDs, Qt::CheckState iState, const std::string & iTraceName) { std::list< unsigned int >::const_iterator iter = iListTraceIDs.begin(); while ( iter != iListTraceIDs.end() ) { this->SetVisibleStateForTraceID(*iter, iTraceName, iState, false); ++iter; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::SetCheckStateForTraceID(unsigned int iTraceID, const std::string & iTraceName, Qt::CheckState iState, bool EmitSignal) { std::cout << "iTraceID: " << iTraceID << std::endl; std::cout << "iTraceName: " << iTraceName << std::endl; std::cout << "EmitSignal: " << EmitSignal << std::endl; unsigned int ColumnIndex = this->findColumnName(""); int RowIndex = this->GetRowForTraceID(iTraceID, iTraceName); std::cout << "ColumnIndex: " << ColumnIndex << std::endl; std::cout << "RowIndex: " << RowIndex << std::endl; std::cout << "this->item(RowIndex, ColumnIndex): " << this->item(RowIndex, ColumnIndex) << std::endl; this->setCheckedUncheckedStateCheckBox( this->item(RowIndex, ColumnIndex), iState, EmitSignal); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int QGoTableWidget::GetRowForTraceID(unsigned int iTraceID, const std::string & iTraceName) { //get the row index based on iTraceName: std::stringstream TraceIDName; TraceIDName << iTraceName; TraceIDName << "ID"; int oRowIndex = this->findValueGivenColumn( iTraceID, TraceIDName.str().c_str() ); if ( oRowIndex == -1 ) { //std::cerr << "The trace " << TraceID << "has not been found in TW"; std::cerr << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cerr << std::endl; return oRowIndex; } return oRowIndex; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QStringList QGoTableWidget::ValuesForSelectedRows(const QString & iColumnName) { QList< QTableWidgetSelectionRange > Selection = this->selectedRanges(); int ColumnIndex = findColumnName(iColumnName); QList< QString > Values; for ( int i = 0; i < Selection.size(); i++ ) { int TopRowSelected = Selection[i].topRow(); int BottomRowSelected = Selection[i].bottomRow(); for ( int j = TopRowSelected; j < BottomRowSelected + 1; j++ ) { Values.append( this->item(j, ColumnIndex)->text() ); } } return Values; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::DisplayColumnNames( const std::list< std::pair< std::string, std::string > >& iColumnNamesAndToolTip) { size_t numberCol = iColumnNamesAndToolTip.size(); this->setColumnCount( static_cast< int >( numberCol ) ); int i = 0; for ( std::list< std::pair< std::string, std::string > >::const_iterator iter = iColumnNamesAndToolTip.begin(); iter != iColumnNamesAndToolTip.end(); ++iter, ++i ) { QTableWidgetItem *HeaderCol = new QTableWidgetItem; std::string NameHeader, ToolTip; NameHeader = iter->first; ToolTip = iter->second; HeaderCol->setText( NameHeader.c_str() ); if ( ToolTip != "None" ) { HeaderCol->setToolTip( ToolTip.c_str() ); } QFont serifFont("Arial", 10, QFont::Bold); HeaderCol->setFont(serifFont); this->setHorizontalHeaderItem(i, HeaderCol); } this->horizontalHeader()->setSortIndicatorShown(true); //Need to disabled the Sorting while printing the values from the database in // the table widget as the sorting is making trouble this->setSortingEnabled(false); this->horizontalHeader()->setMovable(true); QObject::connect( this->horizontalHeader(), SIGNAL( sortIndicatorChanged(int, Qt::SortOrder) ), this, SLOT( sortItems(int, Qt::SortOrder) ) ); // QSettings settings( "MegasonLab", "Gofigure2" ); QSettings settings; QByteArray stateTableWidget = settings.value("StateTableWidget").toByteArray(); //QTabTableName->horizontalHeader()->restoreState(stateTableWidget); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget ::DisplayInitialContent(const TWContainerType & iTWRowContainer, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & iTraceName, const std::string & iCollectionName, const std::list< std::pair< std::string, std::string > > & iColumnNamesAndToolTip, Qt::CheckState iState, int iIndexShowColumn) { this->DisplayColumnNames(iColumnNamesAndToolTip); this->InsertNewRows(iTWRowContainer, iIndexColorTraceRowContainer, iIndexColorCollectionRowContainer, iTraceName, iCollectionName, iState); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::SetSelectedColumn(unsigned int iIndexRow) { int indexCol = findColumnName(""); QTableWidgetItem *Checkbox = new QTableWidgetItem; //Checkbox->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | // Qt::ItemIsSelectable ); Checkbox->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); // Checkbox->setFlags( Qt::ItemIsUserCheckable); QColor WhiteColor(Qt::white); Checkbox->setTextColor(WhiteColor); this->setCheckedUncheckedStateCheckBox(Checkbox, Qt::Unchecked, false); this->setItem(iIndexRow, indexCol, Checkbox); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::SetVisibleColumn(unsigned int iIndexRow, Qt::CheckState iState) { int indexCol = findColumnName("Show"); QTableWidgetItem *Checkbox = new QTableWidgetItem; //Checkbox->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | // Qt::ItemIsUserCheckable); Checkbox->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); QColor WhiteColor(Qt::white); Checkbox->setTextColor(WhiteColor); this->setItem(iIndexRow, indexCol, Checkbox); this->setVisibleStateCheckBox(Checkbox, iState, false); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::SetColorForTable(const TWContainerType & iTWRowContainer, unsigned int iIndexTWRowContainer, const std::vector< int > & iIndexColorRowContainer, const std::string & iNameGroupColor, unsigned int iIndexRowTW) { //for the collection color: std::string ColumnNameID = iNameGroupColor; ColumnNameID += "ID"; int indexGroupIDInTableWidget = findColumnName( ColumnNameID.c_str() ); QColor Color; QColor TextColor; int Alpha = atoi( iTWRowContainer[iIndexColorRowContainer[3]].second[iIndexTWRowContainer].c_str() ); if ( iTWRowContainer[indexGroupIDInTableWidget].second[iIndexTWRowContainer] == "0" || Alpha == 0 ) { Color.setRgb(255, 255, 255, 255); int rgb = 255 - ( 255 * 3 ) / 3; TextColor.setRgb(rgb, rgb, rgb, 255); } else { int Red = atoi( iTWRowContainer[iIndexColorRowContainer[0]].second[iIndexTWRowContainer].c_str() ); int Green = atoi( iTWRowContainer[iIndexColorRowContainer[1]].second[iIndexTWRowContainer].c_str() ); int Blue = atoi( iTWRowContainer[iIndexColorRowContainer[2]].second[iIndexTWRowContainer].c_str() ); Color.setRgb(Red, Green, Blue, Alpha); int rgb = 255 - ( Red + Green + Blue ) / 3; TextColor.setRgb(rgb, rgb, rgb, 255); } this->item(iIndexRowTW, indexGroupIDInTableWidget)->setBackgroundColor(Color); this->item(iIndexRowTW, indexGroupIDInTableWidget)->setTextColor(TextColor); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::DisplayDataForOneRow(const TWContainerType & iTWRowContainer, unsigned int iIndexTWRowContainer, int iIndexTWRow, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & iTraceName, const std::string & iCollectionName) { if ( iIndexTWRow != -1 ) { QTableWidgetItem *t_item = NULL; unsigned int NumberOfRows = iTWRowContainer.size(); int NumberOfColumns = this->columnCount(); for ( unsigned int i = 0; i < NumberOfRows; i++ ) { if ( iTWRowContainer[i].first.ColumnNameTableWidget != "None" && !iTWRowContainer[i].second.empty() ) { for ( int j = 0; j < NumberOfColumns; j++ ) { std::string HeaderCol = this->horizontalHeaderItem(j)->text().toStdString(); if ( HeaderCol == iTWRowContainer[i].first.ColumnNameTableWidget ) { std::string Value = iTWRowContainer[i].second[iIndexTWRowContainer]; t_item = this->item(iIndexTWRow, j); if (!t_item && this->CheckValueToDisplayData(Value, HeaderCol)) { t_item = new QTableWidgetItem; t_item->setTextAlignment(Qt::AlignCenter); this->setItem(iIndexTWRow, j, t_item); } if ( t_item ) { if ( iTWRowContainer[i].first.TypeName == "string" ) { t_item->setData( 0, QString::fromStdString(Value) ); } else { t_item->setData( 0, QString::fromStdString(Value).toDouble() ); } } } //ENDIF } //ENDFOR } //ENDIF } //ENDFOR this->SetColorForTable( iTWRowContainer, iIndexTWRowContainer, iIndexColorTraceRowContainer, iTraceName, iIndexTWRow); if (iCollectionName != "None") //no collection for lineages { this->SetColorForTable( iTWRowContainer, iIndexTWRowContainer, iIndexColorCollectionRowContainer, iCollectionName, iIndexTWRow); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::InsertNewRow(const TWContainerType & iTWRowContainer, unsigned int iIndexTWRowContainer, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & iTraceName, const std::string & iCollectionName, Qt::CheckState iVisible) { int IndexNewRow = this->rowCount(); this->setRowCount(IndexNewRow + 1); this->DisplayDataForOneRow(iTWRowContainer, iIndexTWRowContainer, IndexNewRow, iIndexColorTraceRowContainer, iIndexColorCollectionRowContainer, iTraceName, iCollectionName); this->SetSelectedColumn(IndexNewRow); this->SetVisibleColumn(IndexNewRow, iVisible); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::InsertNewRows(const TWContainerType & iTWRowContainer, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & iTraceName, const std::string & iCollectionName, Qt::CheckState iVisible) { if ( !iTWRowContainer[1].second.empty() ) { this->setSortingEnabled(false); for ( unsigned int i = 0; i < iTWRowContainer[1].second.size(); i++ ) { this->InsertNewRow(iTWRowContainer, i, iIndexColorTraceRowContainer, iIndexColorCollectionRowContainer, iTraceName, iCollectionName, iVisible); } this->setSortingEnabled(true); this->resizeColumnsToContents(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::InsertOnlyOneNewRow(const TWContainerType & iTWRowContainer, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & TraceName, const std::string & CollectionName, Qt::CheckState iVisible) { // no sorting inside for performance issue while import // this->setSortingEnabled(false); if ( iTWRowContainer.size() == 0 || iTWRowContainer[1].second.size() != 1 ) { std::cout << "The New Trace Row Container is totally empty or there is more than 1 trace in it"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } else { this->InsertNewRow(iTWRowContainer, 0, iIndexColorTraceRowContainer, iIndexColorCollectionRowContainer, TraceName, CollectionName, iVisible); } // this->setSortingEnabled(true); // this->resizeColumnsToContents(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool QGoTableWidget::CheckValueToDisplayData(const std::string & iValue, const std::string & iHeaderCol) { if ( iValue == "" ) { return false; } if ( iValue == "-1" && iHeaderCol.compare("T.I.Channel") > 0 ) { return false; } return true; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::UpdateRow(const TWContainerType & iTWRowContainer, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & iTraceName, const std::string & iCollectionName, int iTraceID) { if ( iTraceID != 0 ) { this->setSortingEnabled(false); if ( iTWRowContainer.size() == 0 || iTWRowContainer[1].second.size() != 1 ) { std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; std::cout << "The Update Trace Row Container is totally empty or there is more than 1 trace in it"; std::cout << std::endl; } else { QString TraceNameID = QString("%1ID").arg( iTraceName.c_str() ); int IndexUpdateRow = this->findValueGivenColumn(iTraceID, TraceNameID); if ( IndexUpdateRow != -1 ) { this->DisplayDataForOneRow(iTWRowContainer,0, IndexUpdateRow, iIndexColorTraceRowContainer, iIndexColorCollectionRowContainer, iTraceName, iCollectionName); } else { std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; std::cout << "the row doesn't exist"; std::cout << std::endl; } } this->setSortingEnabled(true); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::DeleteCheckedRows(const std::string & iTraceNameID, const std::list< unsigned int > & iTraceIDs) { this->setSortingEnabled(false); std::list< unsigned int >::const_iterator iter = iTraceIDs.begin(); while ( iter != iTraceIDs.end() ) { int RowToDelete = this->findValueGivenColumn( *iter, iTraceNameID.c_str() ); removeRow(RowToDelete); ++iter; } this->setSortingEnabled(true); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::UpdateColumnsWithCheckBoxes(int iRow, int iColumn) { if ( this->horizontalHeaderItem(iColumn)->text() == "" ) { //force the checkbox to change state, even if the user didn't click //directly in the checkbox but in the cell containing it: if ( this->item(iRow, iColumn)->checkState() == 0 ) { this->setCheckedUncheckedStateCheckBox(this->item(iRow, iColumn), Qt::Checked, true); } else { this->setCheckedUncheckedStateCheckBox(this->item(iRow, iColumn), Qt::Unchecked, true); } } if ( this->horizontalHeaderItem(iColumn)->text() == "Show" ) { if ( this->item(iRow, iColumn)->checkState() == 0 ) { this->setVisibleStateCheckBox(this->item(iRow, iColumn), Qt::Checked, true); } else { this->setVisibleStateCheckBox(this->item(iRow, iColumn), Qt::Unchecked, true); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::CopySelection() { //Get only the first selected Range: QList< QTableWidgetSelectionRange > SelectedRanges = this->selectedRanges(); //QTableWidgetSelectionRange range = SelectedRanges.first(); QString str; for ( int k = 0; k < SelectedRanges.size(); k++ ) { QTableWidgetSelectionRange range = SelectedRanges.at(k); this->PrepareRangeToCopy(range, str); str += "\n"; } QApplication::clipboard()->setText(str); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::CopyTable() { //first, copy the column names: QStringList ColumnsNames = this->recordHeaderNamesOrder(); QString str; str += "IsSelected"; str += "\t"; for ( int i = 1; i < ColumnsNames.size() - 1; i++ ) { str += ColumnsNames.at(i); str += "\t"; } str += ColumnsNames.at(ColumnsNames.size() - 1); str += "\n"; //second, get the range for the total selection: QTableWidgetSelectionRange RangeForAllTableSelected( 0, 0, this->rowCount() - 1, this->columnCount() - 1); //third, copy the range: this->PrepareRangeToCopy(RangeForAllTableSelected, str); QApplication::clipboard()->setText(str); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::PrepareRangeToCopy(const QTableWidgetSelectionRange & iRange, QString & istr) { QTableWidgetItem *t_item = NULL; for ( int i = 0; i < iRange.rowCount(); ++i ) { if ( i > 0 ) { istr += "\n"; } for ( int j = 0; j < iRange.columnCount() - 1; ++j ) { int k = iRange.leftColumn() + j; if ( k == 0 ) { //for the selected column: if ( item(i, 0)->checkState() == 0 ) { istr += "No \t"; } else { istr += "Yes \t"; } } else { t_item = this->item(iRange.topRow() + i, iRange.leftColumn() + j); if ( t_item ) { istr += t_item->text(); } else { istr += "*"; } istr += "\t"; } } t_item = this->item(iRange.topRow() + i, iRange.leftColumn() + iRange.columnCount() - 1); if ( t_item ) { istr += t_item->text(); } else { istr += "*"; } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::ChangeCheckStateSelectedRows(std::string iTraceName, std::string iTraceNameID, Qt::CheckState iState) { QStringList ListSelectedTracesID = this->ValuesForSelectedRows( iTraceNameID.c_str() ); if ( !ListSelectedTracesID.empty() ) { for ( int i = 0; i < ListSelectedTracesID.size(); i++ ) { this->SetCheckStateForTraceID(ListSelectedTracesID.at(i).toUInt(), iTraceName, iState, false); } emit ModifyHighlightListTraces(ListSelectedTracesID, iState); } else { std::cout << "The list of selected Traces ID is empty"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::ChangeVisibilityStateSelectedRows(std::string iTraceName, std::string iTraceNameID, Qt::CheckState iState) { QStringList ListSelectedTracesID = this->ValuesForSelectedRows( iTraceNameID.c_str() ); if ( !ListSelectedTracesID.empty() ) { for ( int i = 0; i < ListSelectedTracesID.size(); i++ ) { this->SetVisibleStateForTraceID(ListSelectedTracesID.at(i).toUInt(), iTraceName, iState, false); } emit ModifyVisibilityListTraces(ListSelectedTracesID, iState); } else { std::cout << "The list of selected Traces ID is empty"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::AddValuesForID(const std::vector< std::string > & iColumnsNames, const std::vector< std::string > & iValues, unsigned int iID, const std::string & iColumnNameForTraceID) { int RowIndex = this->findValueGivenColumn( iID, iColumnNameForTraceID.c_str() ); if ( RowIndex != -1 ) { for ( unsigned int i = 0; i < iColumnsNames.size(); i++ ) { int ColumnIndex = this->findColumnName( iColumnsNames.at(i).c_str() ); if ( ColumnIndex != -1 ) { QTableWidgetItem *CellTable = new QTableWidgetItem; CellTable->setData( 0, QString::fromStdString( iValues.at(i) ).toDouble() ); //QString::fromStdString( iValues.at(i))); CellTable->setTextAlignment(Qt::AlignCenter); this->setItem(RowIndex, ColumnIndex, CellTable); } } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoDBCoordinateRow QGoTableWidget::GetCoordinateCenterBoundingBox( unsigned int iTraceID, const std::string & iTraceName) { GoDBCoordinateRow CenterCoord; int RowIndex = this->GetRowForTraceID(iTraceID, iTraceName); if ( RowIndex != -1 ) { CenterCoord.SetField( "TCoord", this->GetValueForItem("TimePoint", RowIndex) ); CenterCoord.SetField( "XCoord", this->GetMeanValue("XMax", "XMin", RowIndex) ); CenterCoord.SetField( "YCoord", this->GetMeanValue("YMax", "YMin", RowIndex) ); CenterCoord.SetField( "ZCoord", this->GetMeanValue("ZMax", "ZMin", RowIndex) ); } return CenterCoord; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoTableWidget::GetValue(unsigned int iTraceID, const std::string & iTraceName, const std::string & iColumn) { int RowIndex = this->GetRowForTraceID(iTraceID, iTraceName); return this->item( RowIndex, this->findColumnName( iColumn.c_str() ) )->text(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int QGoTableWidget::GetValueForItem(const std::string & iColumnName, int iRowIndex) { return this->item( iRowIndex, this->findColumnName( iColumnName.c_str() ) )->text().toInt(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string QGoTableWidget::GetMeanValue(const std::string & iColumnNameOne, const std::string & iColumnNameTwo, unsigned int iRowIndex) { int ValueOne = this->GetValueForItem(iColumnNameOne, iRowIndex); int ValueTwo = this->GetValueForItem(iColumnNameTwo, iRowIndex); int meanValue = ( ValueOne + ValueTwo ) / 2; return ConvertToString< int >(meanValue); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::setCheckedUncheckedStateCheckBox(QTableWidgetItem *iItem, Qt::CheckState iState, bool EmitSignal) { if( iItem ) { if ( this->setCheckStateCheckBox(iItem, iState) && EmitSignal ) { int Row = iItem->row(); emit CheckedRowsChanged( this->item(Row, 1)->text().toInt() ); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::setVisibleStateCheckBox(QTableWidgetItem *iItem, Qt::CheckState iState, bool EmitSignal) { if( iItem ) { if ( this->setCheckStateCheckBox(iItem, iState) ) { QIcon Icon; if ( iState == Qt::Checked ) { Icon.addPixmap(QPixmap( QString::fromUtf8(":/fig/EyeIcon.png") ), QIcon::Normal, QIcon::Off); } else { Icon.addPixmap(QPixmap( QString::fromUtf8(":/fig/BlankIcon.png") ), QIcon::Normal, QIcon::Off); } if ( EmitSignal ) { int Row = iItem->row(); VisibleRowsChanged( this->item(Row, 1)->text().toInt() ); } iItem->setIcon(Icon); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool QGoTableWidget::setCheckStateCheckBox(QTableWidgetItem *iItem, Qt::CheckState iState) { bool oModification = false; if( iItem ) { if ( iState == Qt::Checked ) { //if the row is already checked, no need to do anything: if ( iItem->checkState() != 2 ) { iItem->setCheckState(Qt::Checked); iItem->setText("1"); oModification = true; } } else { //if the row is already unchecked, no need to do anything: if ( iItem->checkState() != Qt::Unchecked ) { iItem->setCheckState(Qt::Unchecked); iItem->setText("0"); oModification = true; } } } return oModification; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::map< unsigned int, std::string > QGoTableWidget::GetTraceIDAndColumnsValues(const std::string & iTraceIDName, std::string & ioColumnName) { std::map< unsigned int, std::string > oMapValues = std::map< unsigned int, std::string >(); QList< QTableWidgetSelectionRange > Ranges = this->selectedRanges(); if ( Ranges.size() > 1 || Ranges[0].columnCount() > 1 ) { QMessageBox msgBox; msgBox.setText( tr("Please choose only one column to color code") ); msgBox.exec(); return oMapValues; } unsigned int ColumnIndex = Ranges[0].leftColumn(); ioColumnName = this->horizontalHeaderItem(ColumnIndex)->text().toStdString(); int NbOfRows = this->rowCount(); unsigned int IndexTraceID = this->findColumnName( iTraceIDName.c_str() ); for ( int i = 0; i < NbOfRows; i++ ) { if ( this->item(i, ColumnIndex) ) { std::string Text = this->item(i, ColumnIndex)->text().toStdString(); //for // // // // // // test // // // // // // purpose oMapValues[this->item(i, IndexTraceID)->text().toUInt()] = this->item(i, ColumnIndex)->text().toStdString(); } else { oMapValues[this->item(i, IndexTraceID)->text().toUInt()] = ""; } } return oMapValues; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::ShowOnlyRowsForTimePoint(unsigned int iTimePoint) { int ColumnIndex = this->findColumnName("TimePoint"); if ( ColumnIndex == -1 ) { std::cout << "column TimePoint not found in the table widget"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return; } for ( int i = 0; i < this->rowCount(); i++ ) { if ( this->item(i, ColumnIndex)->text().toUInt() != iTimePoint ) { this->hideRow(i); } else { this->showRow(i); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::ShowAllRows() { for ( int i = 0; i < this->rowCount(); i++ ) { this->showRow(i); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget::DeleteRowsWithSpecificTimePoints( const QStringList & iListTPs) { int IndexColumnTime = this->findColumnName("TimePoint"); if (IndexColumnTime != -1) { this->setSortingEnabled(false); for (int i = rowCount()-1; i>=0; --i) { if (iListTPs.contains(this->item(i, IndexColumnTime)->text() ) ) { this->removeRow(i); } } this->setSortingEnabled(true); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTableWidget:: DeleteRowsAndColumns() { for(int i=rowCount()-1; i>=0; --i) { this->removeRow(i); } for(int i=columnCount()-1; i>=0; --i) { this->removeColumn(i); } } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/QTextEditChild.cxx0000644000175000017500000000553611667757442021014 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QTextEditChild.h" #include //-------------------------------------------------------------------------- QTextEditChild::QTextEditChild(QWidget *iParent, int iNumberMaxCharacters) : QTextEdit(iParent), m_MaxCharacters(iNumberMaxCharacters) { QObject::connect( this, SIGNAL( textChanged() ), this, SLOT( RestrainInputCharacters() ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QTextEditChild::~QTextEditChild() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QTextEditChild::RestrainInputCharacters() { QString text; int leftChar = 0; int sizeText = this->toPlainText().size(); leftChar = this->m_MaxCharacters - sizeText; if ( leftChar < 0 ) { text = this->toPlainText().left(this->m_MaxCharacters); this->setText(text); this->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); } }GoFigure2-v0.9.0/Code/GUI/lib/QGoNameDescriptionInputDialog.h0000755000175000017500000000565111667757442023456 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoNameDescriptionInputDialog_h #define __QGoNameDescriptionInputDialog_h #include #include "ui_QNameDescriptionInputDialog.h" #include "QTextEditChild.h" /** \class QNameDescriptionInputDialog \brief for the creation of several entities in the database, the name and the description are asked to the user. */ class QGoNameDescriptionInputDialog:public QDialog, private Ui::QNameDescriptionInputDialog { Q_OBJECT public: explicit QGoNameDescriptionInputDialog(QWidget *iParent = 0, QString iEntityName = ""); virtual ~QGoNameDescriptionInputDialog(); /** \brief open a messagebox to tell the user that the name he choose already exists*/ void NameAlreadyExists(); signals: void NewNameDescription(std::string, std::string); //void CancelRequested(); protected: QTextEditChild *m_DescriptionTextEdit; QString m_EntityName; std::string GetInputTextForName(); std::string GetInputTextForDescription(); protected slots: /** \brief check that the qlineEdit for the name is not empty, if so, tell the user he needs to enter a name*/ void ValidationRequested(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoTabImageView2D.cxx0000644000175000017500000003125611667757442021274 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTabImageView2D.h" #include "QGoImageView2D.h" #include "QGoLUTDialog.h" #include "QGoNavigationDockWidget.h" #include "vtkLookupTable.h" #include "vtkEventQtSlotConnect.h" #include "vtkRenderWindow.h" #include "vtkRendererCollection.h" #include "vtkImageData.h" #include "vtkTextProperty.h" #include "vtkImageExtractComponents.h" #include "vtkProperty.h" #include "vtkContourWidget.h" #include "vtkOrientedGlyphContourRepresentation.h" #include "vtkImageActorPointPlacer.h" #include "QGoImageFilterPluginBase.h" #include #include #include #include #include #include //-------------------------------------------------------------------------- QGoTabImageView2D::QGoTabImageView2D(QWidget *iParent) : QGoTabImageViewNDBase(iParent) { m_Image = 0; setupUi(this); this->m_ContourRepresentation.push_back( vtkSmartPointer< vtkOrientedGlyphContourRepresentation >::New() ); this->m_ContourRepresentation.back()->GetProperty()->SetColor(0., 1., 1.); this->m_ContourRepresentation.back()->GetLinesProperty()->SetColor(1., 0., 1.); this->m_ContourRepresentation.back()->GetActiveProperty()->SetColor(1., 1., 0.); this->m_ContourWidget.push_back( vtkSmartPointer< vtkContourWidget >::New() ); this->m_ContourWidget.back()->SetPriority(10.0); this->m_ContourWidget.back()->SetInteractor( m_ImageView->GetInteractor() ); this->m_ContourWidget.back()->Off(); m_NavigationDockWidget = new QGoNavigationDockWidget(this, GoFigure::TWO_D); m_NavigationDockWidget->resize(120, 300); this->m_DockWidgetList.push_front( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus(m_NavigationDockWidget, Qt::LeftDockWidgetArea, true, true), m_NavigationDockWidget) ); QAction *LookupTableAction = new QAction(tr("Lookup Table"), this); LookupTableAction->setStatusTip( tr(" Change the associated lookup table") ); QIcon luticon; luticon.addPixmap(QPixmap( QString::fromUtf8(":/fig/LookupTable.png") ), QIcon::Normal, QIcon::Off); LookupTableAction->setIcon(luticon); // Here write the connection QObject::connect( LookupTableAction, SIGNAL( triggered() ), this, SLOT( ChangeLookupTable() ) ); this->m_ViewActions.push_back(LookupTableAction); QAction *ScalarBarAction = new QAction(tr("Display Scalar Bar"), this); ScalarBarAction->setCheckable(true); QIcon scalarbaricon; scalarbaricon.addPixmap(QPixmap( QString::fromUtf8(":/fig/scalarbar.png") ), QIcon::Normal, QIcon::Off); ScalarBarAction->setIcon(scalarbaricon); this->m_ViewActions.push_back(ScalarBarAction); QObject::connect( ScalarBarAction, SIGNAL( toggled(bool) ), this, SLOT( ShowScalarBar(bool) ) ); QPixmap Pix(16, 16); Pix.fill(Qt::black); m_BackgroundColorAction = new QAction(Pix, tr("Set Background Color"), this); this->m_ViewActions.push_back(m_BackgroundColorAction); QObject::connect( m_BackgroundColorAction, SIGNAL( triggered() ), this, SLOT( ChangeBackgroundColor() ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( ShowAllChannelsChanged(bool) ), this, SLOT( ShowAllChannels(bool) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( ShowOneChannelChanged(int) ), this, SLOT( ShowOneChannel(int) ) ); QAction *separator2 = new QAction(this); separator2->setSeparator(true); this->m_ViewActions.push_back(separator2); this->m_ViewActions.push_back( m_NavigationDockWidget->toggleViewAction() ); //CreateModeActions(); ReadSettings(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoTabImageView2D:: ~QGoTabImageView2D() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoFigure::TabDimensionType QGoTabImageView2D::GetTabDimensionType() const { return GoFigure::TWO_D; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::setupUi(QWidget *iParent) { if ( iParent->objectName().isEmpty() ) { iParent->resize(800, 800); } m_ImageView = new QGoImageView2D(this); this->setCentralWidget(m_ImageView); m_ImageView->SetBackgroundColor(m_BackgroundColor); retranslateUi(iParent); QMetaObject::connectSlotsByName(iParent); } // setupUi //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::retranslateUi(QWidget *iParent) { iParent->setWindowTitle( tr("QGoTabImageView2D") ); Q_UNUSED(iParent); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::Update() { m_ImageView->Update(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::SetBackgroundColorToImageViewer() { m_ImageView->SetBackgroundColor(this->m_BackgroundColor); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::GetBackgroundColorFromImageViewer() { double r(0.), g(0.), b(0.); m_ImageView->GetBackgroundColor(r, g, b); this->m_BackgroundColor.setRgbF(r, g, b); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::ChangeLookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->DeepCopy( QGoLUTDialog::GetLookupTable( this, tr("Choose one look-up table") ) ); m_ImageView->SetLookupTable(lut); lut->Delete(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::ShowScalarBar(const bool & iShow) { m_ImageView->ShowScalarBar(iShow); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::WriteSettings() { QGoTabImageViewElementBase::WriteSettings(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::ReadSettings() { QGoTabImageViewElementBase::ReadSettings(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::SetImageToImageViewer(vtkImageData *iImage) { m_ImageView->SetImage(iImage); m_ImageView->Update(); vtkImageActorPointPlacer *point_placer = vtkImageActorPointPlacer::New(); point_placer->SetImageActor( m_ImageView->GetImageActor(0) ); this->m_ContourRepresentation.back()->SetPointPlacer(point_placer); point_placer->Delete(); this->m_ContourWidget.back()->SetRepresentation( this->m_ContourRepresentation.back() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int * QGoTabImageView2D::GetImageCoordinatesFromWorldCoordinates(double iPos[3]) { return m_ImageView->GetImageCoordinatesFromWorldCoordinates(iPos); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // std::vector< vtkQuadricLODActor* > std::vector< vtkActor * > QGoTabImageView2D::AddContour(vtkPolyData *dataset, vtkProperty *iProperty) { return m_ImageView->AddContour(dataset, iProperty); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::RemoveActorFromViewer(const int & iId, vtkActor *iActor) { m_ImageView->RemoveActor(iId, iActor); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::DisplayActorInViewer(const int & iId, vtkActor *iActor) { m_ImageView->AddActor(iId, iActor); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView2D::SetSlice(int iDir, int *iIdx) { (void)iDir; (void)iIdx; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView2D::ChangeBackgroundColor() { double r(0.), g(0.), b(0.); m_ImageView->GetBackgroundColor(r, g, b); m_BackgroundColor.setRgbF(r, g, b); QColor temp = QColorDialog::getColor( m_BackgroundColor, this, tr("Choose Background Color") ); if ( temp != m_BackgroundColor ) { m_BackgroundColor = temp; m_ImageView->SetBackgroundColor(m_BackgroundColor); QPixmap Pix(16, 16); Pix.fill(temp); m_BackgroundColorAction->setIcon(Pix); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView2D::CreateModeToolBar(QMenu*iMenu, QToolBar* iToolBar) { //QActionGroup *group = new QActionGroup(this); // Call superclass //QGoTabElementBase::CreateModeActions(group); QGoTabElementBase::CreateModeToolBar(iMenu, iToolBar); this->m_ToolBarList.push_back(this->m_ModeToolBar); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView2D::TakeSnapshot() { m_ImageView->SnapshotViewXY(GoFigure::PNG, "snapshot_"); } //------------------------------------------------------------------------- void QGoTabImageView2D::DefaultInteractorBehavior(bool iEnable) { (void)iEnable; m_ImageView->DefaultMode(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView2D::ZoomInteractorBehavior(bool iEnable) { (void)iEnable; m_ImageView->ZoomMode(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView2D::PanInteractorBehavior(bool iEnable) { (void)iEnable; m_ImageView->PanMode(); } GoFigure2-v0.9.0/Code/GUI/lib/QGoImageView3D.cxx0000644000175000017500000012076711667757442020654 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoImageView3D.h" #include "QDebug" #include "vtkImageData.h" #include "vtkViewImage2D.h" #include "vtkViewImage3D.h" #include "vtkViewImage2DCollection.h" /////////////////////////////////////////////////////////////// #include "vtkRenderWindowInteractor.h" #include "vtkRenderWindow.h" #include "vtkRendererCollection.h" #include "vtkRenderer.h" /////////////////////////////////////////////////////////////// #include "vtkTextProperty.h" #include "vtkProperty.h" #include "vtkImageClip.h" #include "vtkImagePermute.h" #include "vtkImageResample.h" #include "vtkWindowToImageFilter.h" #include "vtkBMPWriter.h" #include "vtkPostScriptWriter.h" #include "vtkJPEGWriter.h" #include "vtkPNGWriter.h" #include "vtkTIFFWriter.h" #include "vtkCamera.h" #include "vtkEventQtSlotConnect.h" #include "QSplitterChild.h" #include "QVTKWidget.h" #include #include #include "vtkViewImage2DCommand.h" #include "vtkViewImage2DCollectionCommand.h" #include "vtkViewImage3DCommand.h" #include "vtkImageActorPointPlacer.h" #include "vtkCellArray.h" #include "vtkMath.h" #include "vtkPolyData.h" #include "vtkImplicitPlaneWidget.h" #include "vtkPlane.h" #include "vtkLookupTable.h" #include "vtkPiecewiseFunction.h" #include //------------------------------------------------------------------------- QGoImageView3D::QGoImageView3D(QWidget *iParent) : QGoImageView(iParent), IsFullScreen(0), m_FirstRender(true), m_Initialized(false), m_ShowCube(true), m_BoxWidget(0), m_PlaneWidget(0) { VtkEventQtConnector = vtkEventQtSlotConnect::New(); m_HighlightedContourProperty = vtkProperty::New(); m_HighlightedContourProperty->SetColor(1., 0., 0.); m_HighlightedContourProperty->SetLineWidth(3.); setupUi(this); QObject::connect( this->SliderXY, SIGNAL( valueChanged(int) ), this, SLOT( SetSliceViewXY(int) ) ); QObject::connect( this->SliderXZ, SIGNAL( valueChanged(int) ), this, SLOT( SetSliceViewXZ(int) ) ); QObject::connect( this->SliderYZ, SIGNAL( valueChanged(int) ), this, SLOT( SetSliceViewYZ(int) ) ); QObject::connect( this->HtSplitter, SIGNAL( splitterMoved(int, int) ), this->HbSplitter, SLOT( moveSplitter(int, int) ) ); QObject::connect( this->HbSplitter, SIGNAL( splitterMoved(int, int) ), this->HtSplitter, SLOT( moveSplitter(int, int) ) ); vtkViewImage2D *View1 = vtkViewImage2D::New(); SetupViewGivenQVTKWidget(View1, this->QvtkWidget_XY); this->m_Pool->AddItem(View1); View1->Delete(); vtkViewImage2D *View2 = vtkViewImage2D::New(); SetupViewGivenQVTKWidget(View2, this->QvtkWidget_XZ); this->m_Pool->AddItem(View2); View2->Delete(); vtkViewImage2D *View3 = vtkViewImage2D::New(); SetupViewGivenQVTKWidget(View3, this->QvtkWidget_YZ); this->m_Pool->AddItem(View3); View3->Delete(); vtkRenderWindow *renwin4 = this->QvtkWidget_XYZ->GetRenderWindow(); this->m_View3D = vtkViewImage3D::New(); this->m_View3D->SetRenderWindow(renwin4); this->m_View3D->SetupInteractor( this->QvtkWidget_XYZ->GetInteractor() ); this->m_Pool->SetExtraRenderWindow(renwin4); // Initialize widget which doesn't require information about the input image QGoImageView::InitializeSeedWidget(); QGoImageView::InitializeDistanceWidget(); QGoImageView::InitializeAngleWidget(); QGoImageView::InitializeContourWidget(); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoImageView3D:: ~QGoImageView3D() { delete HtSplitter; delete HbSplitter; // note m_Pool is supposed to be deleted in QGoImageView, but due to a bug // it has to be deleted in this order... if ( m_Pool ) { m_Pool->Delete(); m_Pool = NULL; } m_View3D->Delete(); m_View3D = NULL; VtkEventQtConnector->Delete(); m_HighlightedContourProperty->Delete(); if ( m_BoxWidget ) { m_BoxWidget->Delete(); m_BoxWidget = NULL; } if ( m_PlaneWidget ) { m_PlaneWidget->Delete(); m_PlaneWidget = NULL; } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::setupUi(QWidget *iParent) { if ( iParent->objectName().isEmpty() ) { iParent->resize(800, 800); } QList< int > list_size; list_size.push_back(400); list_size.push_back(400); this->VSplitter = new QSplitter(Qt::Vertical, iParent); this->HtSplitter = new QSplitterChild(this->VSplitter); this->HbSplitter = new QSplitterChild(this->VSplitter); this->VSplitter->addWidget(this->HtSplitter); this->VSplitter->addWidget(this->HbSplitter); this->VSplitter->setSizes(list_size); this->VSplitter->resize(800, 800); this->QvtkWidget_XY = new QVTKWidget; this->SliderXY = new QSlider(Qt::Vertical); this->LayOut1 = new QHBoxLayout; this->LayOut1->addWidget(this->QvtkWidget_XY); this->LayOut1->addWidget(this->SliderXY); this->LayOutWidget1 = new QWidget; this->LayOutWidget1->setLayout(this->LayOut1); this->HtSplitter->addWidget(this->LayOutWidget1); this->QvtkWidget_XZ = new QVTKWidget; this->SliderXZ = new QSlider(Qt::Vertical); this->LayOut2 = new QHBoxLayout; this->LayOut2->addWidget(this->QvtkWidget_XZ); this->LayOut2->addWidget(this->SliderXZ); this->LayOutWidget2 = new QWidget; this->LayOutWidget2->setLayout(this->LayOut2); this->HbSplitter->addWidget(this->LayOutWidget2); this->QvtkWidget_YZ = new QVTKWidget; this->SliderYZ = new QSlider(Qt::Vertical); this->LayOut3 = new QHBoxLayout; this->LayOut3->addWidget(this->QvtkWidget_YZ); this->LayOut3->addWidget(this->SliderYZ); this->LayOutWidget3 = new QWidget; this->LayOutWidget3->setLayout(this->LayOut3); this->HtSplitter->addWidget(this->LayOutWidget3); this->QvtkWidget_XYZ = new QVTKWidget; this->LayOut4 = new QHBoxLayout; this->LayOut4->addWidget(this->QvtkWidget_XYZ); this->LayOut4->addSpacing(27); this->LayOutWidget4 = new QWidget; this->LayOutWidget4->setLayout(this->LayOut4); this->HbSplitter->addWidget(this->LayOutWidget4); this->HtSplitter->setSizes(list_size); this->HtSplitter->resize(800, 400); this->HbSplitter->setSizes(list_size); this->HbSplitter->resize(800, 400); retranslateUi(iParent); QMetaObject::connectSlotsByName(iParent); } // setupUi //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::retranslateUi(QWidget *iParent) { iParent->setWindowTitle( tr("QGoImageView3D") ); Q_UNUSED(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::Update() { int extent[6]; this->m_Image->GetExtent(extent); vtkViewImage2D *View1 = this->m_Pool->GetItem(0); View1->SetInput(this->m_Image); View1->SetIntersectionLineWidth(this->m_IntersectionLineWidth); this->m_View3D->Add2DPhantom( 0, View1->GetImageActor(), View1->GetSlicePlane() ); this->SliderXY->setMinimum(extent[4]); this->SliderXY->setMaximum(extent[5]); vtkViewImage2D *View2 = this->m_Pool->GetItem(1); View2->SetInput(this->m_Image); View2->SetIntersectionLineWidth(this->m_IntersectionLineWidth); this->m_View3D->Add2DPhantom( 1, View2->GetImageActor(), View2->GetSlicePlane() ); this->SliderXZ->setMinimum(extent[2]); this->SliderXZ->setMaximum(extent[3]); vtkViewImage2D *View3 = this->m_Pool->GetItem(2); View3->SetInput(this->m_Image); View3->SetIntersectionLineWidth(this->m_IntersectionLineWidth); this->m_View3D->Add2DPhantom( 2, View3->GetImageActor(), View3->GetSlicePlane() ); this->SliderYZ->setMinimum(extent[0]); this->SliderYZ->setMaximum(extent[1]); this->m_View3D->SetInput(this->m_Image); this->m_View3D->SetIntersectionLineWidth(this->m_IntersectionLineWidth); if ( m_FirstRender ) { UpdateOnFirstRender(); } else { this->m_Pool->SyncRender(); } QGoImageView::Update(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::UpdateOnFirstRender() { vtkViewImage2D *View1 = this->m_Pool->GetItem(0); View1->SetViewOrientation(vtkViewImage2D::VIEW_ORIENTATION_AXIAL); View1->SetViewConvention(vtkViewImage2D::VIEW_CONVENTION_NEUROLOGICAL); vtkViewImage2D *View2 = this->m_Pool->GetItem(1); View2->SetViewOrientation (vtkViewImage2D::VIEW_ORIENTATION_CORONAL); View2->SetViewConvention(vtkViewImage2D::VIEW_CONVENTION_NEUROLOGICAL); vtkViewImage2D *View3 = this->m_Pool->GetItem(2); View3->SetViewOrientation(vtkViewImage2D::VIEW_ORIENTATION_SAGITTAL); View3->SetViewConvention(vtkViewImage2D::VIEW_CONVENTION_NEUROLOGICAL); this->m_View3D->SetVolumeRenderingOff(); this->m_View3D->SetTriPlanarRenderingOn(); this->m_View3D->SetShowScalarBar(false); this->SliderXY->setValue( ( this->SliderXY->minimum() + this->SliderXY->maximum() ) / 2 ); this->SliderXZ->setValue( ( this->SliderXZ->minimum() + this->SliderXZ->maximum() ) / 2 ); this->SliderYZ->setValue( ( this->SliderYZ->minimum() + this->SliderYZ->maximum() ) / 2 ); this->m_Pool->SyncSetBackground( this->m_Pool->GetItem(0)->GetBackground() ); this->m_Pool->SyncSetShowAnnotations(m_ShowAnnotations); this->m_Pool->SetSplinePlaneActorsVisibility(m_ShowSplinePlane); this->m_View3D->SetBoundsActorsVisibility(m_ShowSplinePlane); this->m_View3D->SetCubeVisibility(m_ShowCube); // should not be there // setCollectionFontToArial for ( int i = 0; i < 3; i++ ) { this->m_Pool->GetItem(i)->GetTextProperty()->SetFontFamilyToArial(); this->m_Pool->GetItem(i)->GetTextProperty()->SetFontSize(14); } this->m_Pool->SyncReset(); this->m_Pool->InitializeAllObservers(); this->m_Pool->Initialize(); // share bounds between all interactors styles, to prevent picking planes, // wire mode on planes, surface mode on planes vtkInteractorStyleImage2D *t0 = static_cast< vtkInteractorStyleImage2D * >( this->m_Pool->GetItem(0)->GetInteractorStyle()); t0->SetPlanesActors(m_Pool->GetPlanesActors()); vtkInteractorStyleImage2D *t1 = static_cast< vtkInteractorStyleImage2D * >( this->m_Pool->GetItem(1)->GetInteractorStyle()); t1->SetPlanesActors(m_Pool->GetPlanesActors()); vtkInteractorStyleImage2D *t2 = static_cast< vtkInteractorStyleImage2D * >( this->m_Pool->GetItem(2)->GetInteractorStyle()); t2->SetPlanesActors(m_Pool->GetPlanesActors()); this->m_View3D->GetInteractorStyle3D() ->SetPlanesActors(this->m_View3D->GetPlanesActors()); // Rotate the camera to show that the view is 3d vtkCamera *camera = this->m_View3D->GetRenderer()->GetActiveCamera(); camera->Roll(-135); camera->Azimuth(-45); this->m_View3D->GetRenderer()->SetActiveCamera(camera); this->m_View3D->ResetCamera(); SetupVTKtoQtConnections(); // Initialize widgets which requiere information about the input image InitializeBoxWidget(); InitializePlaneWidget(); m_FirstRender = false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::SetupVTKtoQtConnections() { vtkViewImage2D *View1 = this->m_Pool->GetItem(0); vtkViewImage2D *View2 = this->m_Pool->GetItem(1); vtkViewImage2D *View3 = this->m_Pool->GetItem(2); vtkViewImage3D *View3D = this->m_View3D; // Event connection between vtk and qt // when RequestedPositionEvent occurs in the XY View (double-click), // SliderXZ and SliderYZ move. VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View1->GetInteractorStyle() ), vtkViewImage2DCommand::RequestedPositionEvent, this, SLOT( MoveSliderXZ() ) ); VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View1->GetInteractorStyle() ), vtkViewImage2DCommand::RequestedPositionEvent, this, SLOT( MoveSliderYZ() ) ); // Event connection between vtk and qt // when RequestedPositionEvent occurs in the XY View (double-click), // SliderXZ and SliderYZ move. VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View2->GetInteractorStyle() ), vtkViewImage2DCommand::RequestedPositionEvent, this, SLOT( MoveSliderXY() ) ); VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View2->GetInteractorStyle() ), vtkViewImage2DCommand::RequestedPositionEvent, this, SLOT( MoveSliderYZ() ) ); // Event connection between vtk and qt // when SliceMoveEvent occurs in the XY View, SliderXY moves. VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View3->GetInteractorStyle() ), vtkViewImage2DCommand::EndSliceMoveEvent, this, SLOT( MoveSliderYZ() ) ); // Event connection between vtk and qt // when RequestedPositionEvent occurs in the XY View (double-click), // SliderXZ and SliderYZ move. VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View3->GetInteractorStyle() ), vtkViewImage2DCommand::RequestedPositionEvent, this, SLOT( MoveSliderXY() ) ); VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View3->GetInteractorStyle() ), vtkViewImage2DCommand::RequestedPositionEvent, this, SLOT( MoveSliderXZ() ) ); // Event connection between vtk and qt // when SliceMoveEvent occurs in the XY View, SliderXY moves. VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View2->GetInteractorStyle() ), vtkViewImage2DCommand::EndSliceMoveEvent, this, SLOT( MoveSliderXZ() ) ); // Event connection between vtk and qt // when SliceMoveEvent occurs in the XY View, SliderXY moves. VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View1->GetInteractorStyle() ), vtkViewImage2DCommand::EndSliceMoveEvent, this, SLOT( MoveSliderXY() ) ); ///////////////////////////////////////////////////////////////////////// // Event connection between vtk and qt // when contours picked, send a signal VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View1->GetInteractorStyle() ), vtkViewImage2DCommand::ContourPickingEvent, this, SLOT( UpdateCurrentActorSelection(vtkObject *) ) ); VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View2->GetInteractorStyle() ), vtkViewImage2DCommand::ContourPickingEvent, this, SLOT( UpdateCurrentActorSelection(vtkObject *) ) ); VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View3->GetInteractorStyle() ), vtkViewImage2DCommand::ContourPickingEvent, this, SLOT( UpdateCurrentActorSelection(vtkObject *) ) ); // Event connection between vtk and qt // when contours picked, send a signal VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View3D->GetInteractorStyle3D() ), vtkViewImage3DCommand::MeshPickingEvent, this, SLOT( UpdateCurrentActorSelection(vtkObject *) ) ); ///////////////////////////////////////////////////////////////////////// // Event connection between vtk and qt // when contours picked, send a signal VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View1->GetInteractorStyle() ), vtkCommand::WindowLevelEvent, this, SLOT( UpdateLUT() ) ); VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View2->GetInteractorStyle() ), vtkCommand::WindowLevelEvent, this, SLOT( UpdateLUT() ) ); VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View3->GetInteractorStyle() ), vtkCommand::WindowLevelEvent, this, SLOT( UpdateLUT() ) ); //////////////////////////////////////////////////////////////////////////// // Event connection between vtk and qt // when contours picked, send a signal VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View3D ), vtkViewImage3DCommand::VisibilityUpdatedEvent, this, SLOT( UpdateCurrentActorVisibility(vtkObject *) ) ); // Event connection between vtk and qt // when contours picked, send a signal VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( View3D ), vtkViewImage3DCommand::UpdateRenderEvent, this, SLOT( UpdateRenderWindows() ) ); //////////////////////////////////////////////////////////////////////////// } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::SetImage(vtkImageData *input) { if ( !input ) { vtkSmartPointer test = vtkSmartPointer::New(); this->m_Image->ShallowCopy(test); } else { int dim[3]; input->GetDimensions(dim); assert ( dim[0] + dim[1] + dim[2] > 0 ); m_Initialized = true; this->m_Image->ShallowCopy(input); } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- QVTKInteractor * QGoImageView3D::GetInteractor(const int & iId) { if ( ( iId < 0 ) || ( iId > 3 ) ) { return NULL; } else { switch ( iId ) { default: case 0: { return this->QvtkWidget_XY->GetInteractor(); } case 1: { return this->QvtkWidget_XZ->GetInteractor(); } case 2: { return this->QvtkWidget_YZ->GetInteractor(); } case 3: { return this->QvtkWidget_XYZ->GetInteractor(); } } } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoImageView3D::SnapshotViewXY(const GoFigure::FileType & iType, const QString & iBaseName) { QString filename = SnapshotView(QvtkWidget_XY, iType, iBaseName, m_SnapshotId); m_SnapshotId++; return filename; } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoImageView3D::SnapshotViewXZ(const GoFigure::FileType & iType, const QString & iBaseName) { QString filename = SnapshotView(QvtkWidget_XZ, iType, iBaseName, m_SnapshotId); m_SnapshotId++; return filename; } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoImageView3D::SnapshotViewYZ( const GoFigure::FileType & iType, const QString & iBaseName) { QString filename = SnapshotView(QvtkWidget_YZ, iType, iBaseName, m_SnapshotId); m_SnapshotId++; return filename; } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoImageView3D::SnapshotViewXYZ( const GoFigure::FileType & iType, const QString & iBaseName) { QString filename = SnapshotView(QvtkWidget_XYZ, iType, iBaseName, m_SnapshotId); m_SnapshotId++; return filename; } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::SetFullScreenView(const int & iS) { if ( IsFullScreen != iS ) { IsFullScreen = iS; switch ( IsFullScreen ) { default: case 0: { Quadview(); break; } case 1: { FullScreenViewXY(); break; } case 2: { FullScreenViewXZ(); break; } case 3: { FullScreenViewYZ(); break; } case 4: { FullScreenViewXYZ(); break; } } emit FullScreenViewChanged(IsFullScreen); } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::Quadview() { IsFullScreen = 0; LayOutWidget1->show(); LayOutWidget2->show(); LayOutWidget3->show(); LayOutWidget4->show(); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::FullScreenViewXY() { IsFullScreen = 1; LayOutWidget1->show(); LayOutWidget2->hide(); LayOutWidget3->hide(); LayOutWidget4->hide(); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::FullScreenViewXZ() { IsFullScreen = 2; LayOutWidget1->hide(); LayOutWidget2->show(); LayOutWidget3->hide(); LayOutWidget4->hide(); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::FullScreenViewYZ() { IsFullScreen = 3; LayOutWidget1->hide(); LayOutWidget2->hide(); LayOutWidget3->show(); LayOutWidget4->hide(); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::FullScreenViewXYZ() { IsFullScreen = 4; LayOutWidget1->hide(); LayOutWidget2->hide(); LayOutWidget3->hide(); LayOutWidget4->show(); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoImageView3D::GetFullScreenView() const { return IsFullScreen; } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::resizeEvent(QResizeEvent *iEvent) { QWidget::resizeEvent(iEvent); VSplitter->resize( iEvent->size() ); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::SetSliceViewXY(const int & iSlice) { if ( m_Initialized ) { int s = GetSliceViewXY(); if ( iSlice != s ) { vtkViewImage2D *viewer = this->m_Pool->GetItem(0); viewer->SetSlice(iSlice); viewer->Render(); this->m_Pool->SyncRender(viewer); // move slider and emit signal this->SliderXY->setValue(iSlice); // emit signal to navigation widget emit SliceViewXYChanged(iSlice); } } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoImageView3D::GetSliceViewXY() const { return this->m_Pool->GetItem(0)->GetSlice(); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::SetSliceViewXZ(const int & iSlice) { if ( m_Initialized ) { int s = GetSliceViewXZ(); if ( s != iSlice ) { vtkViewImage2D *viewer = this->m_Pool->GetItem(1); viewer->SetSlice(iSlice); viewer->Render(); this->m_Pool->SyncRender(viewer); // move slider and emit signal this->SliderXZ->setValue(iSlice); // emit signal to navigation widget emit SliceViewXZChanged(iSlice); } } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoImageView3D::GetSliceViewXZ() const { return this->m_Pool->GetItem(1)->GetSlice(); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::SetSliceViewYZ(const int & iSlice) { if ( m_Initialized ) { int s = GetSliceViewYZ(); if ( s != iSlice ) { vtkViewImage2D *viewer = this->m_Pool->GetItem(2); viewer->SetSlice(iSlice); viewer->Render(); this->m_Pool->SyncRender(viewer); // move slider and emit signal this->SliderYZ->setValue(iSlice); // emit signal to navigation widget emit SliceViewYZChanged(iSlice); } } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoImageView3D::GetSliceViewYZ() const { return this->m_Pool->GetItem(2)->GetSlice(); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::MoveSliderXY() { if ( m_Initialized ) { int s = GetSliceViewXY(); if ( s != this->SliderXY->value() ) { this->SliderXY->setValue(s); emit SliceViewXYChanged(s); } } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::MoveSliderXZ() { if ( m_Initialized ) { int s = GetSliceViewXZ(); if ( s != this->SliderXZ->value() ) { this->SliderXZ->setValue(s); emit SliceViewXZChanged(s); } } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::MoveSliderYZ() { if ( m_Initialized ) { int s = GetSliceViewYZ(); if ( s != this->SliderYZ->value() ) { this->SliderYZ->setValue(s); emit SliceViewYZChanged(s); } } } //------------------------------------------------------------------------- void QGoImageView3D::SaveStateSplitters() { QSettings settings; settings.setValue( "VSplitterSizes", VSplitter->saveState() ); settings.setValue( "HtSplitterSizes", HtSplitter->saveState() ); settings.setValue( "HbSplitterSizes", HbSplitter->saveState() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkViewImage3D * QGoImageView3D::GetImageViewer3D() { return m_View3D; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< vtkActor * > QGoImageView3D::AddContour(vtkPolyData *iDataset, vtkProperty *iProperty) { std::vector< vtkActor * > oList = QGoImageView::AddContour(iDataset, iProperty); vtkActor *temp = m_View3D->AddDataSet( (vtkDataSet *)iDataset, iProperty, false, false ); oList.push_back(temp); return oList; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoImageView3D::RemoveActor(const int & iId, vtkActor *iActor) { if ( iId == 3 ) { // remove from renderer // should be add/remove view property m_View3D->GetRenderer()->RemoveActor(iActor); } else { // remove from renderer QGoImageView::RemoveActor(iId, iActor); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoImageView3D::AddActor(const int & iId, vtkActor *iActor) { if ( iId == 3 ) { // add to renderer m_View3D->GetRenderer()->AddActor(iActor); } else { // add to renderer QGoImageView::AddActor(iId, iActor); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoImageView3D::SetLookupTable(vtkLookupTable *iLut) { m_View3D->SetLookupTable(iLut); QGoImageView::SetLookupTable(iLut); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoImageView3D::ShowScalarBar(const bool & iShow) { if ( this->m_Image->GetNumberOfScalarComponents() == 1 ) { m_View3D->SetShowScalarBar(iShow); m_View3D->Render(); } QGoImageView::ShowScalarBar(iShow); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoImageView3D::ShowSplinePlane() { QGoImageView::ShowSplinePlane(); this->m_View3D->SetBoundsActorsVisibility(m_ShowSplinePlane); QGoImageView::UpdateRenderWindows(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoImageView3D::ShowCube3D() { // Invert state of m_ShowCubes m_ShowCube = !m_ShowCube; this->m_View3D->SetCubeVisibility(m_ShowCube); QGoImageView::UpdateRenderWindows(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::SetCamera(int iView) { //Strange behaviour.... vtkCamera *camera = vtkCamera::New(); this->m_View3D->GetRenderer()->SetActiveCamera(camera); // Dorsal view camera->Roll(180); // Posterior view if ( iView == 1 ) { camera->SetRoll(0); camera->Elevation(90); } // Left view if ( iView == 3 ) { camera->Azimuth(-90); } this->m_View3D->ResetCamera(); this->m_View3D->Render(); camera->Delete(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::DefaultMode() { // Call superclass default mode QGoImageView::DefaultMode(); // Update behavior in 3d view vtkInteractorStyleImage3D *t = m_View3D->GetInteractorStyle3D(); t->EnableDefaultMode(); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::ZoomMode() { // Call superclass default mode QGoImageView::ZoomMode(); // Update behavior in 3d view vtkInteractorStyleImage3D *t = m_View3D->GetInteractorStyle3D(); t->EnableZoomMode(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::PanMode() { // Call superclass default mode QGoImageView::PanMode(); // Update behavior in 3d view vtkInteractorStyleImage3D *t = m_View3D->GetInteractorStyle3D(); t->EnablePanMode(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::ActorPickingMode() { QGoImageView::EnableContourPickingMode(); // Update behavior in 3d view to pick mode vtkInteractorStyleImage3D *t = m_View3D->GetInteractorStyle3D(); t->EnablePickMode(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::EnableSeedWidget(bool iActivate) { // Enable widget in each slice QGoImageView::EnableSeedWidget(iActivate); // Update behavior to default mode in 3d view to default mode vtkInteractorStyleImage3D *t = m_View3D->GetInteractorStyle3D(); t->EnableDefaultMode(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::EnableBoxWidget(bool iValue) { //qDebug() << "Box ---Widget---"; DefaultMode(); m_BoxWidget->SetEnabled(iValue); // if widget is enabled, update meshes visibility according to the widget if ( iValue ) { this->m_BoxWidget->InvokeEvent(vtkViewImage2DCommand::InteractionEvent); m_View3D->Render(); m_Pool->SyncRender(); } } //------------------------------------------------------------------------- void QGoImageView3D::EnablePlaneWidget(bool iValue) { //qDebug() << "Plane ---Widget---"; DefaultMode(); m_PlaneWidget->SetEnabled(iValue); // if widget is enabled, update meshes visibility according to the widget if ( iValue ) { this->m_PlaneWidget->InvokeEvent(vtkViewImage2DCommand::InteractionEvent); m_View3D->Render(); m_Pool->SyncRender(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::UpdateLUT() { if(m_Pool->GetItem(0)->GetIsColor()) { return; } // update tf function by modifying the widget double window = m_Pool->GetItem(0)->GetWindow(); double color = m_Pool->GetItem(0)->GetLevel(); emit NewWindowLevel(window, color); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::ChangeCursorShape(QCursor iCursorShape) { //Change cursor QvtkWidget_XY->setCursor(iCursorShape); QvtkWidget_XZ->setCursor(iCursorShape); QvtkWidget_YZ->setCursor(iCursorShape); QvtkWidget_XYZ->setCursor(iCursorShape); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::InitializeBoxWidget() { m_BoxWidget = vtkOrientedBoxWidget::New(); vtkImageData *imageData = this->m_Image; int extent[6]; double spacing[3]; imageData->GetExtent(extent); imageData->GetSpacing(spacing); m_BoxWidget->SetInput(imageData); m_BoxWidget->SetInteractor( m_View3D->GetInteractor() ); m_BoxWidget->SetPlaceFactor(1); m_BoxWidget->PlaceWidget(extent[0] * spacing[0], extent[1] * spacing[0], extent[2] * spacing[1], extent[3] * spacing[1], extent[4] * spacing[2], extent[5] * spacing[2]); //m_BoxWidget->RotationEnabledOff(); m_BoxWidget->SetKeyPressActivationValue ('b'); m_BoxWidget->InsideOutOff(); // has observer to be removed manually?? m_BoxWidget->AddObserver( vtkViewImage2DCommand::InteractionEvent, m_View3D->GetCommand() ); // update 2d views m_BoxWidget->AddObserver( vtkCommand::EndInteractionEvent, m_Pool->GetCommand() ); m_View3D->GetCommand()->SetBoxWidget(m_BoxWidget); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::InitializePlaneWidget() { m_PlaneWidget = vtkImplicitPlaneWidget::New(); vtkImageData *imageData = this->m_Image; int extent[6]; double spacing[3]; imageData->GetExtent(extent); imageData->GetSpacing(spacing); m_PlaneWidget->SetInteractor( m_View3D->GetInteractor() ); m_PlaneWidget->SetInput(imageData); m_PlaneWidget->SetPlaceFactor(1); m_PlaneWidget->PlaceWidget( extent[0] * spacing[0], extent[1] * spacing[0], extent[2] * spacing[1], extent[3] * spacing[1], extent[4] * spacing[2], extent[5] * spacing[2]); m_PlaneWidget->SetOrigin( ( extent[0] + extent[1] ) * spacing[0] / 2, ( extent[2] + extent[3] ) * spacing[1] / 2, ( extent[4] + extent[5] ) * spacing[2] / 2); m_PlaneWidget->ScaleEnabledOff(); m_PlaneWidget->OutlineTranslationOff(); m_PlaneWidget->GetPlaneProperty()->SetOpacity(0.5); m_PlaneWidget->UpdatePlacement(); // has observer to be removed manually?? m_PlaneWidget->AddObserver( vtkCommand::InteractionEvent, m_View3D->GetCommand() ); // update 2d views m_PlaneWidget->AddObserver( vtkCommand::EndInteractionEvent, m_Pool->GetCommand() ); m_View3D->GetCommand()->SetPlaneWidget(m_PlaneWidget); } //------------------------------------------------------------------------- /// \todo Add button to enable/disable tri planar rendering //------------------------------------------------------------------------- void QGoImageView3D:: EnableVolumeRendering(const std::vector& iImages, const std::vector& iOpacities) { m_View3D->SetVolumeRenderingOn(iImages, iOpacities); m_View3D->Render(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void QGoImageView3D:: DisableVolumeRendering() { m_View3D->SetVolumeRenderingOff(); m_View3D->Render(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void QGoImageView3D::UpdateCurrentActorSelection(vtkObject *caller) { vtkInteractorStyleImage2D *t = static_cast< vtkInteractorStyleImage2D * >( caller ); if( t->GetCurrentProp() ) { m_CurrentActor = vtkActor::SafeDownCast ( t->GetCurrentProp() ); emit SelectionChanged(); } } //--------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView3D::UpdateCurrentActorVisibility(vtkObject *caller) { vtkViewImage3D *t = static_cast< vtkViewImage3D * >( caller ); m_CurrentActor = vtkActor:: SafeDownCast( t->GetInteractorStyle3D()->GetCurrentProp() ); m_CurrentState = t->GetInteractorStyle3D()->GetCurrentState(); emit VisibilityChanged(); } //------------------------------------------------------------------------- //--------------------------------------------------------------------------- vtkActor * QGoImageView3D::GetCurrentActor() { return m_CurrentActor; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- bool QGoImageView3D::GetCurrentState() { return m_CurrentState; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void QGoImageView3D::SynchronizeViews( bool iSynchronize) { int n = m_Pool->GetNumberOfItems(); for ( int i = 0; i < n; i++ ) { vtkViewImage2D *viewer = m_Pool->GetItem(i); m_Pool->SynchronizeViews( iSynchronize ); viewer->SynchronizeViews( iSynchronize ); } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void QGoImageView3D::ShowPlanes(bool iShow) { if(iShow) { m_View3D->SetTriPlanarRenderingOn(); } else { m_View3D->SetTriPlanarRenderingOff(); } m_View3D->Render(); } GoFigure2-v0.9.0/Code/GUI/lib/QGoDeleteFromListDialog.h0000755000175000017500000001004711667757442022227 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDeleteFromListDialog_h #define __QGoDeleteFromListDialog_h #include #include #include #include //#include "vtkMySQLDatabase.h" #include "QGoGUILibConfigure.h" /** \class QGoDeleteFromListDialog \brief this class displays a list of entities and return the list of the ones selected by the user. class based on Qt \ingroup GUI */ class QGOGUILIB_EXPORT QGoDeleteFromListDialog:public QDialog { Q_OBJECT public: typedef std::pair< std::string, QColor > ItemColorComboboxData; typedef std::list< ItemColorComboboxData > ListOfItemColorComboboxData; explicit QGoDeleteFromListDialog(std::vector< std::string > iVectorEntities, QWidget *iParent = 0, std::string iEntityName = ""); explicit QGoDeleteFromListDialog( ListOfItemColorComboboxData iDataListWithColor, QWidget *iParent = 0, std::string iEntityName = ""); virtual ~QGoDeleteFromListDialog(); protected: std::string m_EntityName; QListWidget *m_ListWidget; /** \brief set the layout with all the objects, the connections and the entity name \param[in] iEntityName name of the entity to be deleted */ void SetUpUi(std::string iEntityName); /** \brief emit a signal which sends vector with the names of the entities the user selected to be deleted \param[in] iListEntitiesToDelete list of the items selected by the user */ void DeleteSelection( QList< QListWidgetItem * > iListEntitiesToDelete); /** \brief create the corresponding QListWidgetItems \param[in] iVectorItems vector with the names of the entities to be displayed */ void SetItemsFromTheVector(std::vector< std::string > iVectorItems); /** \brief create the corresponding QListWidgetItems with a QColor \param[in] iDataList list with the names of the entities and their color to be displayed */ void SetItemsInTheListWithColor(std::list< ItemColorComboboxData > iDataList); protected slots: /** \brief ask the user to select at least one item if nothying has been selected and ask the user confirmation if the selection is not null */ void SelectionValidation(); signals: void CancelRequested(); void ListEntitiesToDelete(std::vector< std::string > ); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoColorComboBox.cxx0000644000175000017500000001377311667757442021315 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoColorComboBox.h" #include #include #include #include #include #include #include #include #include QGoColorComboBox::QGoColorComboBox(std::string iTextToAddANewOne, QWidget *iparent, std::string iTextToDelete) : QGoComboBox(iTextToAddANewOne, iparent, iTextToDelete) { QObject::connect( this, SIGNAL( AddANewOneActivated() ), this, SLOT( ActionWhenNewOneRequested() ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoColorComboBox::~QGoColorComboBox() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoColorComboBox::InitializeTheListWithColor( std::list< ItemColorComboboxData > iDataFromList) { this->SetItemsFromListWithColor(iDataFromList); //if it is the 1rst time for the list to be displayed, there has to be an // activated //item: //by default, the one selected by the combobox is the one to stick to: this->EmitActivatedItem( this->currentIndex() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoColorComboBox::SetItemsFromListWithColor( std::list< ItemColorComboboxData > iDataFromList) { this->clear(); if ( !iDataFromList.empty() ) { std::list< ItemColorComboboxData >::iterator iter = iDataFromList.begin(); while ( iter != iDataFromList.end() ) { this->AddItemWithColor(*iter, false); //we don't want the signal emitted // for each added item, //only the currentIndex one at the end of the added list. ++iter; } this->AddItemsEndOfList(); } else { this->SetAddText(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoColorComboBox::AddItemWithColor(ItemColorComboboxData iNewItemData, bool SelectTheAddedItem) { QPixmap pix(12, 12); QPainter painter(&pix); if ( iNewItemData.second.isValid() ) { painter.setPen(Qt::gray); painter.setBrush( QBrush(iNewItemData.second) ); painter.drawRect(0, 0, 12, 12); } QIcon Icon; Icon.addPixmap(pix); //we want to insert the item before the "add new item"/"delete items...": //if the index is 0 or negative,the new item is prepended to the list of // existing items: int Index = this->count() - this->m_NumberOfItemsAfterList; if ( this->GetTheItemColorComboBoxData(this->count() - 1).second.isValid() ) { this->addItem(Icon, iNewItemData.first.c_str(), iNewItemData.second); } else { this->insertItem(Index, Icon, iNewItemData.first.c_str(), iNewItemData.second); } //this->addItem(Icon,iNewItemData.first.c_str(),iNewItemData.second); if ( SelectTheAddedItem ) { this->setCurrentIndex(Index); this->EmitActivatedItem(Index); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoColorComboBox::EmitActivatedItem(int iIndexActivatedItem) { ItemColorComboboxData ItemActivated = this->GetTheItemColorComboBoxData(iIndexActivatedItem); emit ItemSelected(ItemActivated); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoColorComboBox::ItemColorComboboxData QGoColorComboBox::GetTheItemColorComboBoxData(int iIndex) { ItemColorComboboxData Item; QVariant variant = this->itemData(iIndex); Item.second = variant.value< QColor >(); Item.first = this->itemText(iIndex).toStdString(); return Item; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/QGoTabImageView3D.cxx0000644000175000017500000006607311667757442021302 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTabImageView3D.h" #include "QGoImageView3D.h" #include "QGoLUTDialog.h" #include "QGoNavigationDockWidget.h" #include "vtkImageData.h" #include "vtkLookupTable.h" #include "vtkContourWidget.h" #include "vtkOrientedGlyphContourRepresentation.h" #include "vtkImageActorPointPlacer.h" #include "vtkProperty.h" // #include "vtkQuadricLODActor.h" #include "vtkActor.h" #include "vtkImageExtractComponents.h" #include #include #include #include #include //-------------------------------------------------------------------------- /** * \brief Constructor * @param iParent */ QGoTabImageView3D::QGoTabImageView3D(QWidget *iParent) : QGoTabImageViewNDBase(iParent) { setupUi(this); for ( int i = 0; i < 3; i++ ) { this->m_ContourRepresentation.push_back( vtkSmartPointer< vtkOrientedGlyphContourRepresentation >::New() ); this->m_ContourRepresentation.back()->GetProperty()->SetColor(0., 1., 1.); this->m_ContourRepresentation.back()->GetLinesProperty()->SetColor(1., 0., 1.); this->m_ContourRepresentation.back()->GetActiveProperty()->SetColor(1., 1., 0.); this->m_ContourWidget.push_back( vtkSmartPointer< vtkContourWidget >::New() ); this->m_ContourWidget.back()->SetPriority(10.0); this->m_ContourWidget.back()->SetInteractor( m_ImageView->GetInteractor(i) ); this->m_ContourWidget.back()->Off(); } m_NavigationDockWidget = new QGoNavigationDockWidget(this, GoFigure::THREE_D); m_NavigationDockWidget->resize(120, 300); QObject::connect( m_NavigationDockWidget, SIGNAL( XSliceChanged(int) ), this, SLOT( SetSliceViewYZ(int) ) ); QObject::connect( this, SIGNAL( SliceViewYZChanged(int) ), m_NavigationDockWidget, SLOT( SetXSlice(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( YSliceChanged(int) ), this, SLOT( SetSliceViewXZ(int) ) ); QObject::connect( this, SIGNAL( SliceViewXZChanged(int) ), m_NavigationDockWidget, SLOT( SetYSlice(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( ZSliceChanged(int) ), this, SLOT( SetSliceViewXY(int) ) ); QObject::connect( this, SIGNAL( SliceViewXYChanged(int) ), m_NavigationDockWidget, SLOT( SetZSlice(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( ShowAllChannelsChanged(bool) ), this, SLOT( ShowAllChannels(bool) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( ShowOneChannelChanged(int) ), this, SLOT( ShowOneChannel(int) ) ); this->m_DockWidgetList.push_front( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus(m_NavigationDockWidget, Qt::LeftDockWidgetArea, true, true), m_NavigationDockWidget) ); CreateAllViewActions(); //CreateModeActions(); ReadSettings(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * */ void QGoTabImageView3D::CreateAllViewActions() { QActionGroup *group = new QActionGroup(this); QAction *QuadViewAction = new QAction(tr("Quad-View"), this); QuadViewAction->setCheckable(true); QuadViewAction->setChecked(true); QIcon quadviewicon; quadviewicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/4views.png") ), QIcon::Normal, QIcon::Off); QuadViewAction->setIcon(quadviewicon); group->addAction(QuadViewAction); this->m_ViewActions.push_back(QuadViewAction); QObject::connect( QuadViewAction, SIGNAL( triggered() ), this, SLOT( Quadview() ) ); QAction *FullScreenXYAction = new QAction(tr("Full-Screen XY"), this); FullScreenXYAction->setCheckable(true); QIcon xyicon; xyicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/xy.png") ), QIcon::Normal, QIcon::Off); FullScreenXYAction->setIcon(xyicon); group->addAction(FullScreenXYAction); this->m_ViewActions.push_back(FullScreenXYAction); QObject::connect( FullScreenXYAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewXY() ) ); QAction *FullScreenXZAction = new QAction(tr("Full-Screen XZ"), this); FullScreenXZAction->setCheckable(true); QIcon xzicon; xzicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/zx.png") ), QIcon::Normal, QIcon::Off); FullScreenXZAction->setIcon(xzicon); group->addAction(FullScreenXZAction); this->m_ViewActions.push_back(FullScreenXZAction); QObject::connect( FullScreenXZAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewXZ() ) ); QAction *FullScreenYZAction = new QAction(tr("Full-Screen YZ"), this); FullScreenYZAction->setCheckable(true); QIcon yzicon; yzicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/yz.png") ), QIcon::Normal, QIcon::Off); FullScreenYZAction->setIcon(yzicon); group->addAction(FullScreenYZAction); this->m_ViewActions.push_back(FullScreenYZAction); QObject::connect( FullScreenYZAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewYZ() ) ); QAction *FullScreenXYZAction = new QAction(tr("Full-Screen XYZ"), this); FullScreenXYZAction->setCheckable(true); QIcon xyzicon; xyzicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/xyz.png") ), QIcon::Normal, QIcon::Off); FullScreenXYZAction->setIcon(xyzicon); group->addAction(FullScreenXYZAction); this->m_ViewActions.push_back(FullScreenXYZAction); QObject::connect( FullScreenXYZAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewXYZ() ) ); QAction *separator = new QAction(this); separator->setSeparator(true); this->m_ViewActions.push_back(separator); QAction *LookupTableAction = new QAction(tr("Lookup Table"), this); LookupTableAction->setStatusTip( tr(" Change the associated lookup table") ); QIcon luticon; luticon.addPixmap(QPixmap( QString::fromUtf8(":/fig/LookupTable.png") ), QIcon::Normal, QIcon::Off); LookupTableAction->setIcon(luticon); // Here write the connection QObject::connect( LookupTableAction, SIGNAL( triggered() ), this, SLOT( ChangeLookupTable() ) ); this->m_ViewActions.push_back(LookupTableAction); QAction *ScalarBarAction = new QAction(tr("Display Scalar Bar"), this); ScalarBarAction->setCheckable(true); QIcon scalarbaricon; scalarbaricon.addPixmap(QPixmap( QString::fromUtf8(":/fig/scalarbar.png") ), QIcon::Normal, QIcon::Off); ScalarBarAction->setIcon(scalarbaricon); this->m_ViewActions.push_back(ScalarBarAction); QObject::connect( ScalarBarAction, SIGNAL( toggled(bool) ), this, SLOT( ShowScalarBar(bool) ) ); QPixmap Pix(16, 16); Pix.fill(Qt::black); m_BackgroundColorAction = new QAction(Pix, tr("Set Background Color"), this); this->m_ViewActions.push_back(m_BackgroundColorAction); QObject::connect( m_BackgroundColorAction, SIGNAL( triggered() ), this, SLOT( ChangeBackgroundColor() ) ); QAction *separator2 = new QAction(this); separator2->setSeparator(true); this->m_ViewActions.push_back(separator2); this->m_ViewActions.push_back( m_NavigationDockWidget->toggleViewAction() ); QAction *separator3 = new QAction(this); separator3->setSeparator(true); this->m_ViewActions.push_back(separator3); QAction *DisplayAnnotationsAction = new QAction(tr("Display annotations"), this); DisplayAnnotationsAction->setCheckable(true); DisplayAnnotationsAction->setChecked(true); DisplayAnnotationsAction->setStatusTip( tr(" Display or not annotations in each 2d view") ); QIcon displayannotationsicon; displayannotationsicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/2D_VIEWS_INFOS.png") ), QIcon::Normal, QIcon::Off); DisplayAnnotationsAction->setIcon(displayannotationsicon); QObject::connect( DisplayAnnotationsAction, SIGNAL( triggered() ), this, SLOT( DisplayAnnotations() ) ); this->m_ViewActions.push_back(DisplayAnnotationsAction); QAction *DisplaySplinePlanesAction = new QAction(tr("Display spline planes"), this); DisplaySplinePlanesAction->setCheckable(true); DisplaySplinePlanesAction->setChecked(true); DisplaySplinePlanesAction->setStatusTip( tr(" Display or not spline planes on each view") ); QIcon displaysplineplaneicon; displaysplineplaneicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/C_M_L.png") ), QIcon::Normal, QIcon::Off); DisplaySplinePlanesAction->setIcon(displaysplineplaneicon); QObject::connect( DisplaySplinePlanesAction, SIGNAL( triggered() ), this, SLOT( DisplaySplinePlanes() ) ); this->m_ViewActions.push_back(DisplaySplinePlanesAction); QAction *DisplayCube3D = new QAction(tr("Display 3D cube"), this); DisplayCube3D->setCheckable(true); DisplayCube3D->setChecked(true); DisplayCube3D->setStatusTip( tr(" Display or not cube in 3d") ); QIcon cube3dicon; cube3dicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/cube.png") ), QIcon::Normal, QIcon::Off); DisplayCube3D->setIcon(cube3dicon); QObject::connect( DisplayCube3D, SIGNAL( triggered() ), this, SLOT( DisplayCube() ) ); this->m_ViewActions.push_back(DisplayCube3D); QAction *Change3DPerspectiveToAxialAction = new QAction(tr("Change 3D view to Posterior "), this); this->m_ViewActions.push_back(Change3DPerspectiveToAxialAction); QIcon axialicon; axialicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/PosteriorView.png") ), QIcon::Normal, QIcon::Off); Change3DPerspectiveToAxialAction->setIcon(axialicon); QObject::connect( Change3DPerspectiveToAxialAction, SIGNAL( triggered() ), this, SLOT( Change3DPerspectiveToAxial() ) ); QAction *Change3DPerspectiveToCoronalAction = new QAction(tr("Change 3D view to Dorsal "), this); this->m_ViewActions.push_back(Change3DPerspectiveToCoronalAction); QIcon coronalicon; coronalicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/DorsalView.png") ), QIcon::Normal, QIcon::Off); Change3DPerspectiveToCoronalAction->setIcon(coronalicon); QObject::connect( Change3DPerspectiveToCoronalAction, SIGNAL( triggered() ), this, SLOT( Change3DPerspectiveToCoronal() ) ); QAction *Change3DPerspectiveToSagittalAction = new QAction(tr("Change 3D view to Left "), this); this->m_ViewActions.push_back(Change3DPerspectiveToSagittalAction); QIcon sagittalicon; sagittalicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/LeftView.png") ), QIcon::Normal, QIcon::Off); Change3DPerspectiveToSagittalAction->setIcon(sagittalicon); QObject::connect( Change3DPerspectiveToSagittalAction, SIGNAL( triggered() ), this, SLOT( Change3DPerspectiveToSagittal() ) ); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3D::CreateModeToolBar(QMenu* iMenu, QToolBar* iToolBar) { //QActionGroup *group = new QActionGroup(this); // Call superclass //QGoTabElementBase::CreateModeActions(group); QGoTabElementBase::CreateModeToolBar(iMenu, iToolBar); this->m_ToolBarList.push_back(this->m_ModeToolBar); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoTabImageView3D::~QGoTabImageView3D() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iParent */ void QGoTabImageView3D::setupUi(QWidget *iParent) { if ( iParent->objectName().isEmpty() ) { iParent->resize(800, 800); } m_ImageView = new QGoImageView3D(this); this->setCentralWidget(m_ImageView); m_ImageView->SetBackgroundColor(m_BackgroundColor); QObject::connect( m_ImageView, SIGNAL( SliceViewXYChanged(int) ), this, SIGNAL( SliceViewXYChanged(int) ) ); QObject::connect( m_ImageView, SIGNAL( SliceViewXZChanged(int) ), this, SIGNAL( SliceViewXZChanged(int) ) ); QObject::connect( m_ImageView, SIGNAL( SliceViewYZChanged(int) ), this, SIGNAL( SliceViewYZChanged(int) ) ); QObject::connect( m_ImageView, SIGNAL( FullScreenViewChanged(int) ), this, SIGNAL( FullScreenViewChanged(int) ) ); retranslateUi(iParent); QMetaObject::connectSlotsByName(iParent); } // setupUi //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iParent */ void QGoTabImageView3D::retranslateUi(QWidget *iParent) { iParent->setWindowTitle( tr("QGoTabImageView3D") ); Q_UNUSED(iParent); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @return */ GoFigure::TabDimensionType QGoTabImageView3D::GetTabDimensionType() const { return GoFigure::THREE_D; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * */ void QGoTabImageView3D::Update() { m_ImageView->Update(); int extent[6]; m_Image->GetExtent(extent); m_NavigationDockWidget->SetXSlice( ( extent[0] + extent[1] ) / 2 ); m_NavigationDockWidget->SetYSlice( ( extent[2] + extent[3] ) / 2 ); m_NavigationDockWidget->SetZSlice( ( extent[4] + extent[5] ) / 2 ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * */ void QGoTabImageView3D::ChangeLookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->DeepCopy( QGoLUTDialog::GetLookupTable( this, tr("Choose one look-up table") ) ); m_ImageView->SetLookupTable(lut); lut->Delete(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iShow */ void QGoTabImageView3D::ShowScalarBar(const bool & iShow) { m_ImageView->ShowScalarBar(iShow); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iType * @param iBaseName * @return */ QString QGoTabImageView3D::SnapshotViewXY( const GoFigure::FileType & iType, const QString & iBaseName) { return m_ImageView->SnapshotViewXY(iType, iBaseName); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iType * @param iBaseName * @return */ QString QGoTabImageView3D::SnapshotViewXZ( const GoFigure::FileType & iType, const QString & iBaseName) { return m_ImageView->SnapshotViewXZ(iType, iBaseName); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iType * @param iBaseName * @return */ QString QGoTabImageView3D::SnapshotViewYZ( const GoFigure::FileType & iType, const QString & iBaseName) { return m_ImageView->SnapshotViewYZ(iType, iBaseName); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iType * @param iBaseName * @return */ QString QGoTabImageView3D::SnapshotViewXYZ( const GoFigure::FileType & iType, const QString & iBaseName) { return m_ImageView->SnapshotViewXYZ(iType, iBaseName); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iS */ void QGoTabImageView3D::SetSliceViewXY(const int & iS) { m_ImageView->SetSliceViewXY(iS); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iS */ void QGoTabImageView3D::SetSliceViewXZ(const int & iS) { m_ImageView->SetSliceViewXZ(iS); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iS */ void QGoTabImageView3D::SetSliceViewYZ(const int & iS) { m_ImageView->SetSliceViewYZ(iS); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iS */ void QGoTabImageView3D::SetFullScreenView(const int & iS) { m_ImageView->SetFullScreenView(iS); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * */ void QGoTabImageView3D::Quadview() { m_ImageView->SetFullScreenView(0); m_TakeSnapshotAction->setEnabled(false); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * */ void QGoTabImageView3D::FullScreenViewXY() { m_ImageView->SetFullScreenView(1); m_TakeSnapshotAction->setEnabled(true); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * */ void QGoTabImageView3D::FullScreenViewXZ() { m_ImageView->SetFullScreenView(2); m_TakeSnapshotAction->setEnabled(true); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * */ void QGoTabImageView3D::FullScreenViewYZ() { m_ImageView->SetFullScreenView(3); m_TakeSnapshotAction->setEnabled(true); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * */ void QGoTabImageView3D::FullScreenViewXYZ() { m_ImageView->SetFullScreenView(4); m_TakeSnapshotAction->setEnabled(true); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * */ void QGoTabImageView3D::GetBackgroundColorFromImageViewer() { double r(0.), g(0.), b(0.); m_ImageView->GetBackgroundColor(r, g, b); this->m_BackgroundColor.setRgbF(r, g, b); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * */ void QGoTabImageView3D::SetBackgroundColorToImageViewer() { m_ImageView->SetBackgroundColor(this->m_BackgroundColor); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param image */ void QGoTabImageView3D::SetImageToImageViewer(vtkImageData *image) { m_ImageView->SetImage(image); // create LUT for the image vtkSmartPointer bwLut = vtkSmartPointer::New(); double* range = image->GetScalarRange(); bwLut->SetTableRange (0, range[1]); bwLut->SetValueRange (0, 1); bwLut->SetSaturationRange(0.0, 0.0); bwLut->Build(); m_ImageView->SetLookupTable(bwLut); m_ImageView->Update(); for ( unsigned int i = 0; i < this->m_ContourWidget.size(); i++ ) { vtkImageActorPointPlacer *point_placer = vtkImageActorPointPlacer::New(); point_placer->SetImageActor( m_ImageView->GetImageActor(i) ); this->m_ContourRepresentation[i]->SetPointPlacer(point_placer); point_placer->Delete(); this->m_ContourWidget[i]->SetRepresentation(this->m_ContourRepresentation[i]); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int * QGoTabImageView3D::GetImageCoordinatesFromWorldCoordinates(double iPos[3]) { return m_ImageView->GetImageCoordinatesFromWorldCoordinates(iPos); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // std::vector< vtkQuadricLODActor* > std::vector< vtkActor * > QGoTabImageView3D::AddContour(vtkPolyData *dataset, vtkProperty *iProperty) { return this->m_ImageView->AddContour(dataset, iProperty); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView3D::RemoveActorFromViewer(const int & iId, vtkActor *iActor) { m_ImageView->RemoveActor(iId, iActor); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView3D::DisplayActorInViewer(const int & iId, vtkActor *iActor) { m_ImageView->AddActor(iId, iActor); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView3D::SetSlice(int iDir, int *iIdx) { switch ( iDir ) { default: case 0: { this->SetSliceViewXY(iIdx[2]); break; } case 1: { this->SetSliceViewXZ(iIdx[1]); break; } case 2: { this->SetSliceViewXY(iIdx[0]); break; } } } //-------------------------------------------------------------------------- void QGoTabImageView3D::ChangeBackgroundColor() { double r(0.), g(0.), b(0.); m_ImageView->GetBackgroundColor(r, g, b); m_BackgroundColor.setRgbF(r, g, b); QColor temp = QColorDialog::getColor( m_BackgroundColor, this, tr("Choose Background Color") ); if ( temp != m_BackgroundColor ) { m_BackgroundColor = temp; m_ImageView->SetBackgroundColor(m_BackgroundColor); QPixmap Pix(16, 16); Pix.fill(temp); m_BackgroundColorAction->setIcon(Pix); } } //------------------------------------------------------------------------- void QGoTabImageView3D::DisplayAnnotations() { this->m_ImageView->ShowAnnotations(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3D::DisplaySplinePlanes() { this->m_ImageView->ShowSplinePlane(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3D::DisplayCube() { this->m_ImageView->ShowCube3D(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3D::Change3DPerspectiveToAxial() { this->m_ImageView->SetCamera(1); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3D::Change3DPerspectiveToCoronal() { this->m_ImageView->SetCamera(2); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3D::Change3DPerspectiveToSagittal() { this->m_ImageView->SetCamera(3); } //------------------------------------------------------------------------- void QGoTabImageView3D::DefaultInteractorBehavior(bool iEnable) { (void)iEnable; this->m_ImageView->DefaultMode(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3D::ZoomInteractorBehavior(bool iEnable) { (void)iEnable; this->m_ImageView->ZoomMode(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3D::PanInteractorBehavior(bool iEnable) { (void)iEnable; this->m_ImageView->PanMode(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void QGoTabImageView3D::TakeSnapshot() { // Get the current view displayed in full screen int FullScreenView = m_ImageView->GetFullScreenView(); QString filename = QDir::toNativeSeparators( QDir::homePath() ); switch ( FullScreenView ) { case 1: filename.append("snapshot-xy-"); m_ImageView->SnapshotViewXY(GoFigure::PNG, filename); break; case 2: filename.append("snapshot-xz-"); m_ImageView->SnapshotViewXZ(GoFigure::PNG, filename); break; case 3: filename.append("snapshot-yz-"); m_ImageView->SnapshotViewYZ(GoFigure::PNG, filename); break; default: filename.append("snapshot-xyz-"); m_ImageView->SnapshotViewXYZ(GoFigure::PNG, filename); break; } } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/QGoImageView.cxx0000644000175000017500000004640711667757442020463 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoImageView.h" #include "QDebug" #include "QVTKWidget.h" #include "vtkEventQtSlotConnect.h" #include "vtkLookupTable.h" #include "vtkRenderWindow.h" #include "vtkRendererCollection.h" #include "vtkImageData.h" #include "vtkTextProperty.h" #include "vtkViewImage2DCollection.h" #include "vtkViewImage2DCollectionCommand.h" #include "vtkViewImage2D.h" // For the seed widget #include "vtkIntArray.h" #include "vtkConstrainedPointHandleRepresentation.h" #include "vtkSeedWidget.h" #include "vtkImageActorPointPlacer.h" #include "vtkProperty.h" #include "vtkWidgetEvent.h" #include "vtkWidgetEventTranslator.h" #include "vtkEvent.h" // For the distance widget... #include "vtkDistanceWidget.h" // For the angle widget... #include "vtkAngleWidget.h" // For the contour widget... #include "vtkContourWidget.h" #include "vtkOrientedGlyphContourRepresentation.h" #include "vtkPolyData.h" //-------------------------------------------------------------------------- /** * \brief Default Constructor. * \param iParent */ QGoImageView::QGoImageView(QWidget *iParent) : QWidget(iParent), m_Pool(0), m_Image(0), m_IntersectionLineWidth(1.), m_SnapshotId(0), m_ShowAnnotations(true), m_ShowSplinePlane(true) { m_Image = vtkImageData::New(); m_Pool = vtkViewImage2DCollection::New(); } //-------------------------------------------------------------------------- QGoImageView:: ~QGoImageView() { if(m_Image) { m_Image->Delete(); m_Image = 0; } if ( m_Pool ) { m_Pool->Delete(); m_Pool = 0; } } //-------------------------------------------------------------------------- void QGoImageView::SetIntersectionLineWidth(const float & iWidth) { m_IntersectionLineWidth = iWidth; } //-------------------------------------------------------------------------- void QGoImageView::GetBackgroundColor(double & r, double & g, double & b) { double *rgb = this->GetBackgroundColor(); r = rgb[0]; g = rgb[1]; b = rgb[2]; } //------------------------------------------------------------------------- double * QGoImageView::GetBackgroundColor() { return m_Pool->GetItem(0)->GetBackground(); } //------------------------------------------------------------------------- void QGoImageView::SetBackgroundColor(const double & r, const double & g, const double & b) { double *current_rgb = this->GetBackgroundColor(); if ( !(( current_rgb[0] == r ) && ( current_rgb[1] == g ) && ( current_rgb[2] == b )) ) { double textcolor[3]; if ( ( r != 0.5 ) && ( g != 0.5 ) && ( b != 0.5 ) ) { textcolor[0] = 1. - r; textcolor[1] = 1. - g; textcolor[2] = 1. - b; } else { textcolor[0] = 1.; textcolor[1] = 1.; textcolor[2] = 0.; } double rgb[3] = { r, g, b }; m_Pool->SyncSetBackground(rgb); int n = m_Pool->GetNumberOfItems(); for ( int i = 0; i < n; i++ ) { vtkTextProperty *tproperty = m_Pool->GetItem(i)->GetTextProperty(); tproperty->SetFontFamilyToArial(); tproperty->SetFontSize(14); tproperty->SetColor(textcolor); } m_Pool->SyncRender(); } } //-------------------------------------------------------------------------- void QGoImageView::SetBackgroundColor(double rgb[3]) { this->SetBackgroundColor(rgb[0], rgb[1], rgb[2]); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoImageView::SetBackgroundColor(const QColor & iColor) { qreal r, g, b; iColor.getRgbF(&r, &g, &b); this->SetBackgroundColor( static_cast< double >( r ), static_cast< double >( g ), static_cast< double >( b ) ); } //-------------------------------------------------------------------------- int * QGoImageView::GetImageCoordinatesFromWorldCoordinates(double iPos[3]) { vtkViewImage2D *View = m_Pool->GetItem(0); return View->GetImageCoordinatesFromWorldCoordinates(iPos); } //-------------------------------------------------------------------------- vtkViewImage2D * QGoImageView::GetImageViewer(const int & iId) { return m_Pool->GetItem(iId); } //-------------------------------------------------------------------------- int QGoImageView::GetNumberOfImageViewers() { return m_Pool->GetNumberOfItems(); } //-------------------------------------------------------------------------- std::vector< vtkActor * > QGoImageView::AddContour(vtkPolyData *iDataset, vtkProperty *iProperty) { int n = m_Pool->GetNumberOfItems(); std::vector< vtkActor * > oActorVector(n, (vtkActor *)NULL); if ( iDataset ) { #ifdef HAS_OPENMP #pragma omp for #endif for ( int i = 0; i < n; i++ ) { vtkViewImage2D *viewer = m_Pool->GetItem(i); vtkActor * temp = viewer->AddDataSet(iDataset, iProperty); oActorVector[i] = temp; } } return oActorVector; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoImageView::RemoveActor(const int & iId, vtkActor *iActor) { if ( ( iId >= 0 ) && ( iId < m_Pool->GetNumberOfItems() ) ) { vtkViewImage2D *viewer = m_Pool->GetItem(iId); viewer->GetRenderer()->RemoveActor(iActor); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoImageView::AddActor(const int & iId, vtkActor *iActor) { if ( ( iId >= 0 ) && ( iId < m_Pool->GetNumberOfItems() ) ) { vtkViewImage2D *viewer = m_Pool->GetItem(iId); viewer->GetRenderer()->AddActor(iActor); } } //-------------------------------------------------------------------------- void QGoImageView::DefaultMode() { //qDebug() << "Default Mode"; //Change cursor ChangeCursorShape(Qt::ArrowCursor); // Change mode in the collection m_Pool->EnableDefaultInteractionMode(); } //-------------------------------------------------------------------------- void QGoImageView::ZoomMode() { //qDebug() << "Zoom Mode"; //Change cursors QCursor zoomCursor(QPixmap( QString::fromUtf8(":/fig/zoom.png") ), -1, -1); ChangeCursorShape(zoomCursor); // Change mode in the collection m_Pool->EnableZoomInteractionMode(); } //-------------------------------------------------------------------------- void QGoImageView::PanMode() { //qDebug() << "Pan Mode"; //Change cursor ChangeCursorShape(Qt::OpenHandCursor); // Change mode in the collection m_Pool->EnablePanInteractionMode(); } //------------------------------------------------------------------------- void QGoImageView::ResetWindowLevel() { m_Pool->SyncResetWindowLevel(); } //------------------------------------------------------------------------- void QGoImageView::SetLookupTable(vtkLookupTable *iLut) { if ( this->m_Image->GetNumberOfScalarComponents() == 1 ) { m_Pool->SyncSetLookupTable(iLut); m_Pool->SyncUpdateWindowLevel(); m_Pool->SyncRender(); } } //------------------------------------------------------------------------- void QGoImageView::ShowScalarBar(const bool & iShow) { if ( this->m_Image->GetNumberOfScalarComponents() == 1 ) { m_Pool->SyncSetShowScalarBar(iShow); m_Pool->SyncRender(); } } //------------------------------------------------------------------------- void QGoImageView::UpdateRenderWindows() { this->m_Pool->SyncRender(); } //------------------------------------------------------------------------- void QGoImageView::ShowAnnotations() { m_ShowAnnotations = !m_ShowAnnotations; this->m_Pool->SyncSetShowAnnotations(m_ShowAnnotations); UpdateRenderWindows(); } //------------------------------------------------------------------------- vtkImageActor * QGoImageView::GetImageActor(const int & iId) { int N = this->m_Pool->GetNumberOfItems(); if ( ( iId < 0 ) || ( iId >= N ) ) { return NULL; } else { return m_Pool->GetItem(iId)->GetImageActor(); } } //------------------------------------------------------------------------- void QGoImageView::ShowSplinePlane() { // Invert state of m_ShowPlane m_ShowSplinePlane = !m_ShowSplinePlane; m_Pool->SetSplinePlaneActorsVisibility(m_ShowSplinePlane); } //-------------------------------------------------------------------------- void QGoImageView::SetInterpolate(const int & val) { m_Pool->SyncSetInterpolate(val); } //------------------------------------------------------------------------- void QGoImageView::EnableContourPickingMode() { //Change cursor ChangeCursorShape(Qt::ArrowCursor); // Change mode in the collection m_Pool->EnableContourPickingMode(); } //------------------------------------------------------------------------- vtkImageData * QGoImageView::GetImage() { return m_Image; } //------------------------------------------------------------------------- void QGoImageView::InitializeSeedWidget() { int N = this->m_Pool->GetNumberOfItems(); for ( int i = 0; i < N; ++i ) { this->m_Handle.push_back(vtkSmartPointer< vtkConstrainedPointHandleRepresentation >::New()); this->m_Handle.back()->GetProperty()->SetColor(1, 0, 0); this->m_SeedRep.push_back(vtkSmartPointer< vtkSeedRepresentation >::New()); this->m_SeedRep.back()->SetHandleRepresentation(this->m_Handle.back()); this->m_SeedWidget.push_back(vtkSmartPointer< vtkSeedWidget >::New()); this->m_SeedWidget.back()->SetRepresentation(this->m_SeedRep.back()); this->m_SeedWidget.back()->SetInteractor( this->m_Pool->GetItem(i)->GetInteractor() ); // to remove right click interaction in the one click widget this->m_SeedWidget[i]->GetEventTranslator()->RemoveTranslation( vtkCommand::RightButtonPressEvent); this->m_SeedWidget[i]->GetEventTranslator()->SetTranslation( vtkCommand::KeyPressEvent, vtkEvent::NoModifier, 100, 0, "d", vtkWidgetEvent::Delete); } } //------------------------------------------------------------------------- void QGoImageView::EnableSeedWidget(bool iEnable) { //qDebug() << "Seed ---Widget---" << iEnable; if ( iEnable ) { DefaultMode(); } std::vector< vtkSmartPointer< vtkSeedWidget > >::iterator it = m_SeedWidget.begin(); while ( it != m_SeedWidget.end() ) { ( *it )->SetEnabled(iEnable); ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView:: GetSeeds(std::vector& iPoints) { for ( unsigned int i = 0; i < 3; i++ ) { double worldPosition[3]; int N = this->m_SeedRep[i]->GetNumberOfSeeds(); for ( int j = 0; j < N; j++ ) { // Get World position (may be not accurate if we are between 8 pixels // (3D)) this->m_SeedRep[i]->GetSeedWorldPosition(j, worldPosition); iPoints[i]->InsertNextPoint(worldPosition); } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoImageView::ClearAllSeeds() { for ( unsigned int i = 0; i < this->m_SeedWidget.size(); i++ ) { for ( int k = this->m_SeedRep[i]->GetNumberOfSeeds() - 1; k >= 0; --k ) { this->m_SeedWidget[i]->DeleteSeed(k); this->m_SeedRep[i]->RemoveHandle(k); } } // automatically remove seeds from the visualization this->UpdateRenderWindows(); } //------------------------------------------------------------------------- void QGoImageView::InitializeDistanceWidget() { int N = this->m_Pool->GetNumberOfItems(); m_DistanceWidget.resize(N); for ( int i = 0; i < N; ++i ) { this->m_DistanceWidget[i] = vtkSmartPointer< vtkDistanceWidget >::New(); this->m_DistanceWidget[i]->SetInteractor( this->m_Pool->GetItem(i)->GetInteractor() ); this->m_DistanceWidget[i]->CreateDefaultRepresentation(); this->m_DistanceWidget[i]->Off(); } } //------------------------------------------------------------------------- void QGoImageView::EnableDistanceWidget(bool iActive) { //qDebug() << "Distance ---Widget---" << iActive; if ( iActive ) { DefaultMode(); } int N = this->m_Pool->GetNumberOfItems(); for ( int i = 0; i < N; i++ ) { this->m_DistanceWidget[i]->SetEnabled(iActive); } } //------------------------------------------------------------------------- void QGoImageView::InitializeAngleWidget() { int N = this->m_Pool->GetNumberOfItems(); m_AngleWidget.resize(N); for ( int i = 0; i < N; ++i ) { this->m_AngleWidget[i] = vtkSmartPointer< vtkAngleWidget >::New(); this->m_AngleWidget[i]->SetInteractor( this->m_Pool->GetItem(i)->GetInteractor() ); this->m_AngleWidget[i]->CreateDefaultRepresentation(); this->m_AngleWidget[i]->Off(); } } //------------------------------------------------------------------------- void QGoImageView::EnableAngleWidget(bool iActive) { //qDebug() << "Angle ---Widget---" << iActive; if ( iActive ) { DefaultMode(); } int N = this->m_Pool->GetNumberOfItems(); for ( int i = 0; i < N; i++ ) { if ( iActive ) { this->m_AngleWidget[i]->On(); } else { this->m_AngleWidget[i]->Off(); } } } //------------------------------------------------------------------------- void QGoImageView::InitializeContourWidget() { int N = this->m_Pool->GetNumberOfItems(); m_ContourWidget.resize(N); m_ContourRepresentation.resize(N); // use while iterator for ( int i = 0; i < N; ++i ) { // Contour widget m_ContourRepresentation[i] = vtkSmartPointer< vtkOrientedGlyphContourRepresentation >::New(); m_ContourRepresentation[i]->GetProperty()->SetColor(0., 1., 1.); m_ContourRepresentation[i]->GetLinesProperty()->SetColor(1., 0., 1.); m_ContourRepresentation[i]->GetActiveProperty()->SetColor(1., 1., 0.); m_ContourWidget[i] = vtkSmartPointer< vtkContourWidget >::New(); m_ContourWidget[i]->SetPriority(10.0); m_ContourWidget[i]->SetInteractor( this->m_Pool->GetItem(i)->GetInteractor() ); m_ContourWidget[i]->Off(); m_ContourWidget[i]->SetRepresentation(this->m_ContourRepresentation[i]); } } //------------------------------------------------------------------------- void QGoImageView::EnableContourWidget(bool iActivate) { if ( iActivate ) { DefaultMode(); } std::vector< vtkSmartPointer< vtkContourWidget > >::iterator it = m_ContourWidget.begin(); while ( it != m_ContourWidget.end() ) { ( *it )->SetEnabled(iActivate); ++it; } } //------------------------------------------------------------------------- void QGoImageView::InitializeContourWidgetNodes(int iDir, vtkPolyData *iNodes) { if ( ( iDir >= 0 ) && ( iDir < m_Pool->GetNumberOfItems() ) ) { m_ContourWidget[iDir]->SetEnabled(1); m_ContourWidget[iDir]->Initialize(iNodes); } } //------------------------------------------------------------------------- void QGoImageView::ReinitializeContourWidget() { int N = static_cast< int >( m_ContourWidget.size() ); #ifdef HAS_OPENMP #pragma omp for #endif for ( int i = 0; i < N; i++ ) { InitializeContourWidgetNodes(i, NULL); } } //------------------------------------------------------------------------- void QGoImageView::UpdateContourRepresentationProperties(float linewidth, QColor linecolor, QColor nodecolor, QColor activenodecolor) { m_LinesWidth = linewidth; m_LinesColor = linecolor; m_NodesColor = nodecolor; m_ActiveNodesColor = activenodecolor; qreal rl, gl, bl; linecolor.getRgbF(&rl, &gl, &bl); qreal rn, gn, bn; nodecolor.getRgbF(&rn, &gn, &bn); qreal ra, ga, ba; activenodecolor.getRgbF(&ra, &ga, &ba); std::vector< vtkSmartPointer< vtkOrientedGlyphContourRepresentation > >::iterator it = m_ContourRepresentation.begin(); while ( it != m_ContourRepresentation.end() ) { ( *it )->GetLinesProperty()->SetLineWidth(linewidth); ( *it )->GetLinesProperty()->SetColor( static_cast< double >( rl ), static_cast< double >( gl ), static_cast< double >( bl ) ); ( *it )->GetProperty()->SetColor( static_cast< double >( rn ), static_cast< double >( gn ), static_cast< double >( bn ) ); ( *it )->GetActiveProperty()->SetColor( static_cast< double >( ra ), static_cast< double >( ga ), static_cast< double >( ba ) ); ++it; } } //------------------------------------------------------------------------- vtkPolyData * QGoImageView::GetContourRepresentationAsPolydata(int iDir) { return m_ContourRepresentation[iDir]->GetContourRepresentationAsPolyData(); } //------------------------------------------------------------------------- vtkPolyData * QGoImageView::GetContourRepresentationNodePolydata(int iDir) { vtkPolyData *contour_nodes = vtkPolyData::New(); m_ContourRepresentation[iDir]->GetNodePolyData(contour_nodes); return contour_nodes; } //------------------------------------------------------------------------- void QGoImageView::Update() { std::vector< vtkSmartPointer< vtkOrientedGlyphContourRepresentation > >::iterator it = m_ContourRepresentation.begin(); int i = 0; while ( it != m_ContourRepresentation.end() ) { vtkSmartPointer< vtkImageActorPointPlacer > point_placer = vtkSmartPointer< vtkImageActorPointPlacer >::New(); point_placer->SetImageActor( GetImageActor(i) ); ( *it )->SetPointPlacer(point_placer); ++it; ++i; } } GoFigure2-v0.9.0/Code/GUI/lib/QGoTableWidget.h0000755000175000017500000004705311667757442020427 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTableWidget_h #define __QGoTableWidget_h #include #include #include #include "MegaVTK2Configure.h" #include "GoDBTraceInfoForVisu.h" #include "GoDBTraceInfoForTableWidget.h" #include "GoDBTableWidgetContainer.h" #include "QGoGUILibConfigure.h" #include "GoDBCoordinateRow.h" /** \class QGoTableWidget \brief inherits from the Qt class QTableWidget, manages all the interactions between the user and the data related to the traces \ingroup GUI */ class QGOGUILIB_EXPORT QGoTableWidget:public QTableWidget { Q_OBJECT public: explicit QGoTableWidget(QWidget *parent = 0); explicit QGoTableWidget(int rows, int columns, QWidget *parent = 0); virtual ~QGoTableWidget(); typedef GoDBTableWidgetContainer::TWContainerType TWContainerType; /** \todo Lydie: check if code reduction with a class member variable Tracename and a method to return TraceNameID from TraceName*/ /** \brief display the columns names and the content of iTWRowContainer in the table \param[in] iTWRowContainer contains the data to be displayed and the corresponding info to know how to display them \param[in] iIndexColorTraceRowContainer index to know where to find the color of the trace in the iTWRowContainer \param[in] iIndexColorCollectionRowContainer index to know where to find the color of the collection in the iTWRowContainer \param[in] iTraceName name of the trace \param[in] iCollectionName name of the collection \param[in] iColumnNames list of the column names to be displayed \param[in] iState if true, the isvisible is checked \param[in] iIndexShowColumn index of the show column in the TW Container( for contour and mesh) */ void DisplayInitialContent(const TWContainerType & iTWRowContainer, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & iTraceName, const std::string & iCollectionName, const std::list< std::pair< std::string, std::string > > & iColumnNames, Qt::CheckState iState, int iIndexShowColumn = 0); void InsertNewRows(const TWContainerType & iTWRowContainer, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & iTraceName, const std::string & iCollectionName, Qt::CheckState iVisible = Qt::Checked); /** \brief Insert a new row and fill the cells with the data contained in the RowContainer \param[in] iTWRowContainer contains the data to be displayed and the corresponding info to know how to display them for one row only \param[in] iIndexColorTraceRowContainer index to know where to find the color of the trace in the iTWRowContainer \param[in] iIndexColorCollectionRowContainer index to know where to find the color of the collection in the iTWRowContainer \param[in] iTraceName name of the trace \param[in] iCollectionName name of the collection */ void InsertOnlyOneNewRow(const TWContainerType & iTWRowContainer, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & iTraceName, const std::string & iCollectionName, Qt::CheckState iVisible = Qt::Checked); /** \brief Replace the data in the cells corresponding to the traceID with the new data contained in the RowContainer \param[in] iTWRowContainer contains the data to be displayed and the corresponding info to know how to display them for one row only \param[in] iIndexColorTraceRowContainer index to know where to find the color of the trace in the iTWRowContainer \param[in] iIndexColorCollectionRowContainer index to know where to find the color of the collection in the iTWRowContainer \param[in] iTraceName name of the trace \param[in] iCollectionName name of the collection \param[in] iTraceID ID of the trace to be updated */ void UpdateRow(const TWContainerType & iTWRowContainer, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & iTraceName, const std::string & iCollectionName, int iTraceID); void DeleteRowsWithSpecificTimePoints(const QStringList & iListTPs); /** \brief delete the rows previously checked by the user \param[in] iTraceNameID name of the traceID displayed in the table \param[in] iTraceIDs list of the traceIDs for which the rows need to be deleted */ void DeleteCheckedRows(const std::string & iTraceNameID, const std::list< unsigned int > & iTraceIDs); /** \brief add values in the table for the corresponding traceID and column names \param[in] iColumnsNames names of the columns to display the values \param[in] iValues vector containing the values in the same order as the column names \param[in] iID ID of the trace where to display the values \param[in] iColumnNameForTraceID name of the traceID */ void AddValuesForID(const std::vector< std::string > & iColumnsNames, const std::vector< std::string > & iValues, unsigned int iID, const std::string & iColumnNameForTraceID); /** \brief calculate the center of the bounding box for the only selected trace and return it as a GoDBCoordinateRow \param[in] iTraceID ID for the trace the center of bounding box needs to be calculated \param[in] iTraceName name of the trace \return GoDBCoordinateRow corresponds to the center of the bounding box for the trace */ GoDBCoordinateRow GetCoordinateCenterBoundingBox(unsigned int iTraceID, const std::string & iTraceName); /** \brief set the state of the checkbox for the check/uncheck column and the TraceID row to iState \param[in] iTraceID traceID for which the checkbox state needs to be set \param[in] iTraceName name of the trace \param[in] iState state to which the checkbox needs to be set \param[in] EmitSignal if set to true, will emit a signal to tell if the state has changed, if set to false will not emit,set to true by default */ void SetCheckStateForTraceID(unsigned int iTraceID, const std::string & iTraceName, Qt::CheckState iState, bool EmitSignal = true); /** \brief set the state and icon of the checkbox for the IsVisible column and the TraceID row to iState \param[in] iTraceID traceID for which the IsVisible checkbox state needs to be set \param[in] iTraceName name of the trace \param[in] iState state to which the checkbox and the icon need to be set \param[in] EmitSignal if set to true, will emit a signal to tell if the state has changed, if set to false will not emit,set to true by default */ void SetVisibleStateForTraceID(unsigned int iTraceID, const std::string & iTraceName, Qt::CheckState iState, bool EmitSignal = true); /** \brief \return a map with all the traceIDs and the values of the column for which a cell of a column is selected \param[in] iTraceIDName name of the column for TraceID \param[in,out] ioColumnName name of the column of the values */ std::map GetTraceIDAndColumnsValues( const std::string & iTraceIDName, std::string &ioColumnName); /** \brief update the checkboxes and icon of the visible column for the iListTraceIDs following iState \param[in] iListTraceIDs list of the IDs for the traces with visiblity to be set to iState \param[in] iState state to which the column IsVisible needs to be modified for iListTraceIDs \param[in] iTraceName name of the trace */ void SetVisibleStateForListTraceIDs( const std::list & iListTraceIDs, Qt::CheckState iState, const std::string & iTraceName); /** \brief hide all rows who have a timepoint different than iTimePoint \param[in] iTimePoint current timepoint */ void ShowOnlyRowsForTimePoint(unsigned int iTimePoint); void ShowAllRows(); /** \brief create the table widget items for the columns Header and set the corresponding tooltips for them \param[in] iColumnNamesAndToolTip list of all the names of the columns to be displayed in the table with their tooltips */ void DisplayColumnNames( const std::list< std::pair >& iColumnNamesAndToolTip); QString GetValue(unsigned int iTraceID, const std::string & iTraceName, const std::string & iColumn); void DeleteRowsAndColumns(); public slots: /** \brief uncheck/check the boxes in the check/uncheck column for the rows where at least one cell is selected \param[in] iTraceName name of the trace \param[in] iTraceNameID name of the traceID \param[in] iState state to which the checkboxes need to be modified */ void ChangeCheckStateSelectedRows(std::string iTraceName, std::string iTraceNameID, Qt::CheckState iState); /** \brief check/uncheck the visible boxes for the rows where at least one cell is selected \param[in] iTraceName name of the trace \param[in] iTraceNameID name of the traceID \param[in] iState state to which the visibility need to be modified */ void ChangeVisibilityStateSelectedRows(std::string iTraceName, std::string iTraceNameID, Qt::CheckState iState); /** \brief convert the text in the selection to a QString with anti slash n and anti slash t and put it in the Clipboard to be pasted in other applications */ void CopySelection(); /** \brief convert the text in the all table and the columns namse to a QString with anti slash n and anti slash t and put it in the Clipboard to be pasted in other applications */ void CopyTable(); signals: void CheckedRowsChanged(int iTraceID); void VisibleRowsChanged(int iTraceID); void ModifyHighlightListTraces(QStringList,Qt::CheckState); void ModifyVisibilityListTraces(QStringList,Qt::CheckState); protected: int PrevCol; int PrevOrder; /** \brief get the value in the table for the given iRowIndex and for the given column name \param[in] iColumnName name of the column for which the value is needed \param[in] iRowIndex index of the row for which the value is needed \return corresponding value for the item */ int GetValueForItem(const std::string & iColumnName, int iRowIndex); /** \brief calculate the mean value for both columns in the given row \param[in] iColumnNameOne name of the first column \param[in] iColumnNameTwo name of the second column \param[in] iRowIndex index of the row for which the mean value is needed \return the mean value of both columns in the given row */ std::string GetMeanValue(const std::string & iColumnNameOne, const std::string & iColumnNameTwo, unsigned int iRowIndex); /** \brief return the row index where the given value is located when specifying the column name. \param[in] iValue value to be look for \param[in] iColumn name of the column in which to look for \return the row index where the value was found */ int findValueGivenColumn(int iValue, const QString & iColumn); /** \brief return the column index who has a column header matching ColumnName \param[in] iColumnName name of the column the index is needed \return index of the column */ int findColumnName(const QString & iColumnName); /** \brief put the text in the cells which are part of the range in a QString and insert antislash n and antislash t to be read by other applications \param[in] iRange selected cells \param[in,out] istr text of the selected cells */ void PrepareRangeToCopy(const QTableWidgetSelectionRange & iRange, QString & istr); /** \brief return the RowIndex corresponding to the TraceID \param[in] iTraceID ID of the Trace \param[in] iTraceName name of the trace \return the index of the row where the traceID was found */ int GetRowForTraceID(unsigned int iTraceID, const std::string & iTraceName); /** \brief change the state for the check/uncheck checkbox to iState and emit a signal if EmitSignal = true \param[in] iItem item in the tablewidget where there is a checkbox in the "Checked/Unchecked" column \param[in] iState state to which the Checkbox needs to be set \param[in] EmitSignal if true, a signal will be emitted with the corresponding TraceID */ void setCheckedUncheckedStateCheckBox(QTableWidgetItem *iItem, Qt::CheckState iState, bool EmitSignal); /** \brief change the state and the icon for the "IsVisible" checkbox depending on iState and emit a signal if EmitSignal = true \param[in] iItem item in the tablewidget where there is a checkbox in the "IsVisible" column \param[in] iState state to which the Checkbox and the icon need to be set \param[in] EmitSignal if true, a signal will be emitted with the corresponding TraceID */ void setVisibleStateCheckBox(QTableWidgetItem *iItem, Qt::CheckState iState, bool EmitSignal = true); /** \brief change the state for the checkbox to iState and return true if the state has been changed \param[in] iItem item with a checkbox \param[in] iState state to which the checkbox needs to be set */ bool setCheckStateCheckBox(QTableWidgetItem *iItem, Qt::CheckState iState); /** \brief return a list of the values of a specific column for the rows where the user has selected at least one cell. \param[in] iColumnName name of the column to look for value \return QStringList of the values for the column where the user has selected at least once cell in the same row */ QStringList ValuesForSelectedRows(const QString & iColumnName); /** \brief Put checkboxes in the column "check/uncheck" \param[in] iNbOfRows number of rows for which to put a checkbox \param[in] iStartedRow index of the first row where to put a checkbox */ void SetSelectedColumn(unsigned int iIndexRow); /** \brief Put checkboxes and icons in the column "Show" \param[in] iNbOfRows number of rows for which to put a checkbox and an icon \param[in] iStartedRow index of the first row where to put a checkbox and an icon \param[in] iState state to which the checkboxes need to be set */ void SetVisibleColumn( unsigned int iIndexRow, Qt::CheckState iState = Qt::Checked); /** \brief get the rgba values from the iTWRowContainer and display them in the column NameGroupColorID \param[in] iTWRowContainer contains the data to be displayed \param[in] iIndexColorRowContainer index of the iTWRowContainer to find the rgba values \param[in] iNameGroupColor name of the trace for which the color needs to be displayed \param[in] iStartRow index of the first row where to display the color */ void SetColorForTable(const TWContainerType & iTWRowContainer, unsigned int iIndexTWRowContainer, const std::vector< int > & iIndexColorRowContainer, const std::string & iNameGroupColor, unsigned int iIndexRowTW); QStringList recordHeaderNamesOrder(); /** \brief check if the value is suitable to be displayed, if yes, return true, if not return false so the QTableWidgetChildItem is not created for it \param[in] iValue value to be checked \param[in] iHeaderCol name of the column \return true if the value needs to be displayed, false if not */ bool CheckValueToDisplayData(const std::string & iValue, const std::string & iHeaderCol); void InsertNewRow(const TWContainerType & iTWRowContainer, unsigned int iIndexTWRowContainer, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & iTraceName, const std::string & iCollectionName, Qt::CheckState iVisible = Qt::Checked); void DisplayDataForOneRow(const TWContainerType & iTWRowContainer, unsigned int iIndexTWRowContainer, int iIndexTWRow, const std::vector< int > & iIndexColorTraceRowContainer, const std::vector< int > & iIndexColorCollectionRowContainer, const std::string & iTraceName, const std::string & iCollectionName); protected slots: /** \brief sort items given one column and one sort order. \param[in] iColumn index of the column to be sorted \param[in] iOrder order for the column to be sorted */ void sortItems(int iColumn, Qt::SortOrder iOrder); /** \brief check if the cell clicked is from the check/uncheck column or the "Show" column,change the state of the boxes correspondingly and emit the corresponding signal \param[in] iRow index of the row clicked \param[in] iColumn index of the column clicked */ void UpdateColumnsWithCheckBoxes(int iRow, int iColumn); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoLsmToMegaExportDialog.h0000644000175000017500000000670011667757442022375 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoLsmToMegaExportDialog_h #define __QGoLsmToMegaExportDialog_h #include "ui_LsmToMegaExportDialog.h" #include #include #include "ConversionLsmToMegaThread.h" #include #include #include #include "QGoGUILibConfigure.h" class QGOGUILIB_EXPORT QGoLsmToMegaExportDialog: public QDialog, private Ui::LsmToMegaExportDialog { Q_OBJECT public: /** * \brief Constructor */ explicit QGoLsmToMegaExportDialog(QWidget *parent = 0); /** * \brief Desctructor */ ~QGoLsmToMegaExportDialog(); ConversionLsmToMegaThread *ConversionLsmToMegaThreadSend; protected slots: /** * \brief Get the name of the lsm file selected */ void on_selectLsmFile_clicked(); /** * \brief Get the location to store MegaCapture file */ void on_selectMegaPath_clicked(); /** * \brief Select the output format * \param[in] index 0: PNG, 1:TIFF */ void on_outputFormat_activated(int index); /** * \brief Disable buttons and send thread to launch conversion */ void on_convert_clicked(); /** * \brief Catch thread, close progress bar and dialog box */ void ConversionTerminatedReceived(); /** * \brief Catch thread, initialize the progress bar */ void InitialisationProgressReceived(); /** * \brief Catch thread, update the progress bar content */ void ProgressReceived(); /** * \brief Catch thread, cancel the conversion */ void CanceledReceived(); private: QString m_LsmPath; QString m_LsmName; QString m_MegaPath; bool m_FileFormatIsPNG; QProgressDialog *m_ProgressDialog; int m_Counter; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoTabImageView3D.h0000644000175000017500000001226111667757442020715 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTabImageView3D_h #define __QGoTabImageView3D_h #include "QGoTabImageViewNDBase.h" #include "SnapshotHelper.h" #include #include class vtkImageData; class vtkActor; // class vtkQuadricLODActor; class QAction; class QToolBar; class QDockWidget; class QGoImageView3D; #include "QGoGUILibConfigure.h" /** \class QGoTabImageView3D \brief \example GUI/lib/qgotabimageview3d.cxx */ class QGOGUILIB_EXPORT QGoTabImageView3D:public QGoTabImageViewNDBase { Q_OBJECT public: explicit QGoTabImageView3D(QWidget *parent = 0); virtual ~QGoTabImageView3D(); typedef QGoTabImageViewNDBase::QGoDockWidgetStatusPair QGoDockWidgetStatusPair; GoFigure::TabDimensionType GetTabDimensionType() const; virtual void Update(); void setupUi(QWidget *parent); void retranslateUi(QWidget *parent); virtual void WriteSettings() {} virtual void ReadSettings() {} void CreateModeToolBar(QMenu* iMenu, QToolBar* iToolBar); signals: void SliceViewXYChanged(int Slice); void SliceViewXZChanged(int Slice); void SliceViewYZChanged(int Slice); void FullScreenViewChanged(int View); public slots: QString SnapshotViewXY( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xy-") ); QString SnapshotViewXZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xz-") ); QString SnapshotViewYZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-yz-") ); QString SnapshotViewXYZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xyz-") ); void SetSliceViewXY(const int &); void SetSliceViewXZ(const int &); void SetSliceViewYZ(const int &); void SetFullScreenView(const int & iS); void Quadview(); void FullScreenViewXY(); void FullScreenViewXZ(); void FullScreenViewYZ(); void FullScreenViewXYZ(); void ChangeLookupTable(); void ShowScalarBar(const bool &); void ChangeBackgroundColor(); void DisplayAnnotations(); void DisplaySplinePlanes(); void DisplayCube(); void Change3DPerspectiveToAxial(); void Change3DPerspectiveToCoronal(); void Change3DPerspectiveToSagittal(); /** * \brief Mouse interaction style set as default */ virtual void DefaultInteractorBehavior(bool); /** * \brief Mouse interaction style allows user to zoom in/out volume with all * buttons */ virtual void ZoomInteractorBehavior(bool); /** * \brief Mouse interaction style allows user to pan volume with all buttons */ virtual void PanInteractorBehavior(bool); void TakeSnapshot(); protected: QGoImageView3D *m_ImageView; QAction *m_BackgroundColorAction; void GetBackgroundColorFromImageViewer(); void SetBackgroundColorToImageViewer(); void CreateAllViewActions(); void SetImageToImageViewer(vtkImageData *image); int *GetImageCoordinatesFromWorldCoordinates(double pos[3]); virtual void RemoveActorFromViewer(const int & iId, vtkActor *iActor); virtual void DisplayActorInViewer(const int & iId, vtkActor *iActor); // virtual std::vector< vtkQuadricLODActor* > virtual std::vector< vtkActor * > AddContour(vtkPolyData *dataset, vtkProperty *property = NULL); virtual void SetSlice(int iDir, int *iIdx); private: Q_DISABLE_COPY(QGoTabImageView3D); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoTrackEditingWidget.cxx0000644000175000017500000006345711667757442022326 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTrackEditingWidget.h" #include "ContourMeshStructure.h" #include "vtkSphereSource.h" #include "vtkPolyDataMapper.h" #include "vtkLabeledDataMapper.h" #include "vtkPoints.h" #include "vtkPolyLine.h" #include "vtkCellArray.h" #include "vtkPolyData.h" #include "vtkPointData.h" #include "vtkActor2D.h" #include "vtkProperty.h" // visu #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRendererCollection.h" #include "vtkViewImage3DCommand.h" #include "itkMacro.h" #include "vtkMath.h" #include //------------------------------------------------------------------------- QGoTrackEditingWidget::QGoTrackEditingWidget(MeshContainer *imeshContainer, QWidget *iParent) : QDialog(iParent), m_MeshContainer(imeshContainer), m_MaxTrackID(0), m_NumberOfTracks(0), m_SecondClick(false) { this->setupUi(this); renderer = vtkSmartPointer< vtkRenderer >::New(); m_InteractorStyle3D = vtkInteractorStyleImage3D::New(); m_VtkEventQtConnector = vtkSmartPointer< vtkEventQtSlotConnect >::New(); m_VtkEventQtConnector->Connect( reinterpret_cast< vtkObject * >( m_InteractorStyle3D ), vtkViewImage3DCommand::MeshPickingEvent, this, SLOT( updateCurrentActorSelection(vtkObject *) ) ); m_MinimalDistance = std::numeric_limits< double >::max(); // ADD A STATUS BAR m_StatusBar = new QStatusBar; this->gridLayout_2->addWidget(m_StatusBar, 1, 0, 1, 1); m_StatusBar->showMessage("No track selected"); QObject::connect ( this->buttonBox, SIGNAL( accepted() ), this, SLOT( restoreTrackIDs() ) ); QObject::connect ( this->realMeshes, SIGNAL( toggled(bool) ), this, SLOT( updateMeshesActors(bool) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoTrackEditingWidget:: ~QGoTrackEditingWidget() { m_InteractorStyle3D->Delete(); LineActor2MeshIDIterator it = m_Line2MeshID.begin(); while ( it != m_Line2MeshID.end() ) { renderer->RemoveActor(it->first); it->first->Delete(); ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- vtkActor * QGoTrackEditingWidget::createPolylineActor(double *iCenter1, double *iCenter2, const double *iColor1, const double *iColor2) { // Might be useful at some point (void)iColor1; (void)iColor2; //create a vtkPoints object and storevtkRenderWindow the points in it vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New(); points->InsertNextPoint(iCenter1); points->InsertNextPoint(iCenter2); vtkSmartPointer< vtkPolyLine > polyLine = vtkSmartPointer< vtkPolyLine >::New(); polyLine->GetPointIds()->SetNumberOfIds(2); polyLine->GetPointIds()->SetId(0, 0); polyLine->GetPointIds()->SetId(1, 1); //Create a cell array to store the lines in and add the lines to it vtkSmartPointer< vtkCellArray > cells = vtkSmartPointer< vtkCellArray >::New(); cells->InsertNextCell(polyLine); //Create a polydata to store everything in vtkSmartPointer< vtkPolyData > polyData = vtkSmartPointer< vtkPolyData >::New(); //add the points to the dataset polyData->SetPoints(points); //add the lines to the dataset polyData->SetLines(cells); //setup actor and mapper vtkSmartPointer< vtkPolyDataMapper > mapper = vtkSmartPointer< vtkPolyDataMapper >::New(); mapper->SetInput(polyData); vtkActor *actor = vtkActor::New(); actor->SetMapper(mapper); return actor; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::updateCurrentActorSelection(vtkObject *caller) { vtkInteractorStyleImage3D *t = static_cast< vtkInteractorStyleImage3D * >( caller ); m_CurrentActor = vtkActor:: SafeDownCast( t->GetCurrentProp() ); // if we click on the background if ( !m_CurrentActor ) { return; } LineActor2MeshIDIterator polyToMeshID = m_Line2MeshID.find(m_CurrentActor); if ( polyToMeshID != m_Line2MeshID.end() ) { if ( m_CurrentActor->GetProperty()->GetOpacity() == 1 ) { //Update track IDs - CUT cutTrack(m_CurrentActor); } } /*else { MeshContainer::MultiIndexContainerTraceIDIterator iter; vtkIntArray* testArray = static_cast(m_CurrentActor->GetMapper()->GetInput() ->GetPointData()->GetArray("MESH")); iter = m_MeshContainer->m_Container.get< TraceID >().find( testArray->GetValue(0) ); assert(iter != m_MeshContainer->m_Container.get< TraceID >().end() ); merge(iter); }*/ } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::merge(MeshContainer::MultiIndexContainerTraceIDIterator iBegin) { if ( m_SecondClick ) { mergeTrack(m_FirstMeshID, iBegin->TraceID); } else { m_FirstMeshID = iBegin->TraceID; m_FirstMeshActor = m_CurrentActor; m_StatusBar->showMessage("Select another mesh to merge tracks"); } highlightFirstActor(!m_SecondClick); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::reassignTrackIDs() { MeshContainer::MultiIndexContainerCollectionIDIterator c_it, c_end; c_it = m_MeshContainer->m_Container.get< CollectionID >().begin(); unsigned int collection = std::numeric_limits< unsigned int >::max(); c_end = m_MeshContainer->m_Container.get< CollectionID >().end(); unsigned int current_track = 0; while ( c_it != c_end ) { unsigned int temp_collection = c_it->CollectionID; unsigned int traceID = c_it->TraceID; ++c_it; if ( temp_collection != collection ) { collection = temp_collection; current_track = m_NumberOfTracks; TrackInformation track(collection, UPDATED_TRACK); m_TrackMapping[current_track] = track; ++m_NumberOfTracks; } if ( temp_collection > m_MaxTrackID ) { m_MaxTrackID = temp_collection; } modifyMeshCollectionID(traceID, current_track); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::initializeVisualization() { reassignTrackIDs(); getClosestPoints(); computeMeshActors(); this->updateMeshesActors( false ); computeLineActors(); computeLabelActor(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::computeMeshActors() { // Create the actors for ( unsigned int i = 0; i < m_NumberOfTracks; ++i ) { MeshContainer::MultiIndexContainerCollectionIDIterator it0, it1; boost::tuples::tie(it0, it1) = m_MeshContainer->m_Container.get< CollectionID >().equal_range(i); while ( it0 != it1 ) { ContourMeshStructure tempStructure(*it0); // Get the polydata vtkPolyData *nodes = tempStructure.Nodes; double * rgba = tempStructure.rgba; // add trace info in the polydata vtkSmartPointer trackIDArray = vtkSmartPointer::New(); trackIDArray->SetNumberOfComponents(1); trackIDArray->SetNumberOfValues(1); trackIDArray->SetName("MESH"); trackIDArray->SetValue(0,tempStructure.TraceID); nodes->GetPointData()->AddArray(trackIDArray); //setup actor and mapper vtkSmartPointer< vtkPolyDataMapper > mapper = vtkSmartPointer< vtkPolyDataMapper >::New(); mapper->SetInput(nodes); vtkActor *actor = vtkActor::New(); actor->SetMapper(mapper); actor->GetProperty()->SetColor(rgba); tempStructure.ActorXY = actor; // real mesh // generate sphere based on the minimal distance between 2 points in a // track // actors are invisible vtkActor *sphereActor = computeSphere(tempStructure.TraceID, actor->GetCenter(), m_MinimalDistance / 3); tempStructure.ActorXZ = sphereActor; // Add actor to visu renderer->AddActor(actor); renderer->AddActor(sphereActor); m_MeshContainer->m_Container.get< CollectionID >().replace(it0, tempStructure); ++it0; } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::computeLabelActor() { vtkSmartPointer< vtkDoubleArray > randomScalars = vtkSmartPointer< vtkDoubleArray >::New(); randomScalars->SetNumberOfComponents(1); randomScalars->SetName("TimePoint"); vtkSmartPointer< vtkPoints > pts = vtkSmartPointer< vtkPoints >::New(); // Create the actors for ( unsigned int i = 0; i < m_NumberOfTracks; ++i ) { MeshContainer::MultiIndexContainerCollectionIDIterator it0, it1; boost::tuples::tie(it0, it1) = m_MeshContainer->m_Container.get< CollectionID >().equal_range(i); while ( it0 != it1 ) { // Get the polydata vtkPolyData *nodes = it0->Nodes; unsigned int time = it0->TCoord; randomScalars->InsertNextTuple1(time); pts->InsertNextPoint( nodes->GetCenter() ); ++it0; } } vtkSmartPointer< vtkPolyData > labelData = vtkSmartPointer< vtkPolyData >::New(); labelData->GetPointData()->SetScalars(randomScalars); labelData->SetPoints(pts); // The labeled data mapper will place labels at the points vtkSmartPointer< vtkLabeledDataMapper > labelMapper = vtkSmartPointer< vtkLabeledDataMapper >::New(); labelMapper->SetFieldDataName("TimePoint"); labelMapper->SetInput(labelData); labelMapper->SetLabelModeToLabelScalars(); labelMapper->SetLabelFormat("%6.0f"); vtkSmartPointer< vtkActor2D > isolabels = vtkSmartPointer< vtkActor2D >::New(); isolabels->SetMapper(labelMapper); renderer->AddActor(isolabels); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::cutTrack(vtkActor *iActor) { LineActor2MeshIDIterator it = m_Line2MeshID.find(iActor); // Find the mesh ID if ( it != m_Line2MeshID.end() ) { MeshContainer::MultiIndexContainerTraceIDIterator it0; it0 = m_MeshContainer->m_Container.get< TraceID >().find(it->second); unsigned int collectionID = it0->CollectionID; unsigned int tLimit = it0->TCoord; MeshContainer::MultiIndexContainerCollectionIDIterator it2, it3; boost::tuples::tie(it2, it3) = m_MeshContainer->m_Container.get< CollectionID >().equal_range(collectionID); while ( it2 != it3 ) { unsigned int time = it2->TCoord; unsigned int traceID = it2->TraceID; ++it2; // change track ID if we are before the mesh if ( time < tLimit ) { modifyMeshCollectionID(traceID, m_NumberOfTracks); TrackInformation track(0, NEW_TRACK); m_TrackMapping[m_NumberOfTracks] = track; } } ++m_NumberOfTracks; if ( m_NumberOfTracks > m_MaxTrackID ) { m_MaxTrackID = m_NumberOfTracks; } // update visu removeLineActors(); computeLineActors(); } m_StatusBar->showMessage("Track splitted"); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::removeLineActors() { LineActor2MeshIDIterator it = m_Line2MeshID.begin(); while ( it != m_Line2MeshID.end() ) { renderer->RemoveActor(it->first); it->first->Delete(); ++it; } m_Line2MeshID.clear(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::computeLineActors() { std::map< unsigned int, unsigned int > m_Time2MeshID; // For each track, create the actors for ( unsigned int i = 0; i < m_NumberOfTracks; ++i ) { m_Time2MeshID.clear(); MeshContainer::MultiIndexContainerCollectionIDIterator it0, it1; boost::tuples::tie(it0, it1) = m_MeshContainer->m_Container.get< CollectionID >().equal_range(i); while ( it0 != it1 ) { m_Time2MeshID[it0->TCoord] = ( it0->TraceID ); ++it0; } // Go through map to create polylines std::map< unsigned int, unsigned int >::iterator polyLIt = m_Time2MeshID.begin(); if ( polyLIt != m_Time2MeshID.end() ) { vtkActor *firstActor = ( m_MeshContainer->GetActorGivenTraceID(polyLIt->second) )[0]; vtkActor *secondActor = NULL; ++polyLIt; while ( polyLIt != m_Time2MeshID.end() ) { secondActor = ( m_MeshContainer->GetActorGivenTraceID(polyLIt->second) )[0]; vtkActor *polyLine = createPolylineActor( firstActor->GetCenter(), secondActor->GetCenter() ); ///\todo should color be hard coded? hoew to define it? - Nicolas double color[3] = { 1, 1, 1 }; polyLine->GetProperty()->SetColor(color); // Add actor to visu renderer->AddActor(polyLine); // key is actor m_Line2MeshID[polyLine] = polyLIt->second; firstActor = secondActor; ++polyLIt; } } else { std::cout << "List is empty" << std::endl; } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::restoreTrackIDs() { TrackMapping::iterator it = m_TrackMapping.begin(); unsigned int collection = 0; m_ListOfNewTrack.clear(); m_ListOfUpdatedTracks.clear(); m_ListOfDeletedTracks.clear(); while ( it != m_TrackMapping.end() ) { collection = it->first; switch ( it->second.Status ) { case NEW_TRACK: { std::list< unsigned int > list_meshid = getMeshIDsInTrack(collection); m_ListOfNewTrack.push_back(list_meshid); break; } case UPDATED_TRACK: { std::list< unsigned int > list_meshid = getMeshIDsInTrack(collection); m_ListOfUpdatedTracks[it->second.RealID] = list_meshid; break; } case DELETED_TRACK: { // if real ID > 0 if ( it->second.RealID ) { m_ListOfDeletedTracks.push_back(it->second.RealID); } break; } } ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoTrackEditingWidget::getMeshIDsInTrack(unsigned int iCollection) { std::list< unsigned int > list_meshid; MeshContainer::MultiIndexContainerCollectionIDIterator it0, it1; boost::tuples::tie(it0, it1) = m_MeshContainer->m_Container.get< CollectionID >().equal_range(iCollection); while ( it0 != it1 ) { list_meshid.push_back(it0->TraceID); ++it0; } return list_meshid; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< std::list< unsigned int > > QGoTrackEditingWidget::GetListOfTracksToBeCreated() { return this->m_ListOfNewTrack; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::map< unsigned int, std::list< unsigned int > > QGoTrackEditingWidget::GetListOfTracksToBeUpdated() { return this->m_ListOfUpdatedTracks; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoTrackEditingWidget::GetListOfTracksToBeDeleted() { return this->m_ListOfDeletedTracks; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoTrackEditingWidget::mergeTrack(const unsigned int & iFirstMesh, const unsigned int & iSecondMesh) { unsigned int FirstCollectionID = 0; unsigned int SecondCollectionID = 0; try { FirstCollectionID = m_MeshContainer->GetCollectionIDOfGivenTraceID(iFirstMesh); } catch ( const itk::ExceptionObject & e ) { std::cout << "caught an exception: " << std::endl; e.Print(std::cout); return false; } try { SecondCollectionID = m_MeshContainer->GetCollectionIDOfGivenTraceID(iSecondMesh); } catch ( const itk::ExceptionObject & e ) { std::cout << "caught an exception: " << std::endl; e.Print(std::cout); return false; } if ( FirstCollectionID != SecondCollectionID ) { //Check if actors are border of track std::pair< std::pair< unsigned int, unsigned int >, std::pair< unsigned int, unsigned int > > border1 = getTrackBorders(FirstCollectionID); std::pair< std::pair< unsigned int, unsigned int >, std::pair< unsigned int, unsigned int > > border2 = getTrackBorders(SecondCollectionID); // Check for overlap if ( ( border2.first.second <= border1.second.second ) && ( border1.first.second <= border2.second.second ) ) { m_StatusBar->showMessage("Can't merge tracks: overlap"); return false; } //Get Highest time to know which meshes we should update unsigned int trackToUpdate = 0; unsigned int trackToDelete = 0; if ( border1.first.first < border2.first.first ) { trackToDelete = FirstCollectionID; trackToUpdate = SecondCollectionID; } else { trackToUpdate = FirstCollectionID; trackToDelete = SecondCollectionID; } m_TrackMapping[trackToDelete].Status = DELETED_TRACK; // Change the ID of the track by the other one updateTracksIDs(trackToDelete, trackToUpdate); // update visu removeLineActors(); computeLineActors(); m_StatusBar->showMessage("Tracks merged"); return true; } m_StatusBar->showMessage("Meshes belong to same track"); return false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::pair< std::pair< unsigned int, unsigned int >, std::pair< unsigned int, unsigned int > > QGoTrackEditingWidget::getTrackBorders(const unsigned int & iCollectionID) { MeshContainer::MultiIndexContainerCollectionIDIterator it0, it1; boost::tuples::tie(it0, it1) = m_MeshContainer->m_Container.get< CollectionID >().equal_range(iCollectionID); std::pair< unsigned int, unsigned int > minBorder( 0, std::numeric_limits< unsigned int >::max() ); std::pair< unsigned int, unsigned int > maxBorder(0, 0); unsigned int time = 0; while ( it0 != it1 ) { time = it0->TCoord; if ( minBorder.second > time ) { minBorder.first = it0->TraceID; minBorder.second = time; } if ( maxBorder.second < time ) { maxBorder.first = it0->TraceID; maxBorder.second = time; } ++it0; } return std::make_pair(minBorder, maxBorder); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::updateTracksIDs(const unsigned int & iIDToDelete, const unsigned int & iIDToUpdate) { MeshContainer::MultiIndexContainerCollectionIDIterator it0, it1; boost::tuples::tie(it0, it1) = m_MeshContainer->m_Container.get< CollectionID >().equal_range(iIDToDelete); while ( it0 != it1 ) { unsigned int traceID = it0->TraceID; ++it0; modifyMeshCollectionID(traceID, iIDToUpdate); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::init() { initializeVisualization(); //setup render window, renderer, and interactor this->qvtkWidget->GetRenderWindow()->AddRenderer(renderer); this->qvtkWidget->GetInteractor()->SetInteractorStyle(m_InteractorStyle3D); m_InteractorStyle3D->EnablePickMode(); this->qvtkWidget->GetRenderWindow()->Render(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::modifyMeshCollectionID(unsigned int iMeshID, unsigned int iCollectionID) { MeshContainer::MultiIndexContainerTraceIDIterator it = m_MeshContainer->m_Container.get< TraceID >().find(iMeshID); ContourMeshStructure tempStructure(*it); tempStructure.CollectionID = iCollectionID; m_MeshContainer->m_Container.get< TraceID >().replace(it, tempStructure); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::highlightFirstActor(bool iHighlight) { m_FirstMeshActor->GetProperty()->SetSpecular(iHighlight); m_FirstMeshActor->GetProperty()->SetAmbient(iHighlight); m_SecondClick = iHighlight; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::updateMeshesActors(bool iRealMeshes) { // Go through container and update visibility MeshContainer::MultiIndexContainerTraceIDIterator iter, c_end; iter = m_MeshContainer->m_Container.get< TraceID >().begin(); c_end = m_MeshContainer->m_Container.get< TraceID >().end(); while ( iter != c_end ) { iter->ActorXY->SetVisibility(iRealMeshes); iter->ActorXZ->SetVisibility(!iRealMeshes); ++iter; } // update visu this->qvtkWidget->update(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- vtkActor * QGoTrackEditingWidget::computeSphere(unsigned int iTraceID, double *iCenter, double iRadius) { // Sphere vtkSmartPointer< vtkSphereSource > sphereSource = vtkSmartPointer< vtkSphereSource >::New(); sphereSource->SetCenter(iCenter); sphereSource->SetRadius(iRadius); sphereSource->Update(); // add trace ID into the polydata vtkSmartPointer trackIDArray = vtkSmartPointer::New(); trackIDArray->SetNumberOfComponents(1); trackIDArray->SetNumberOfValues(1); trackIDArray->SetName("MESH"); trackIDArray->SetValue(0,iTraceID); sphereSource->GetOutput()->GetPointData()->AddArray(trackIDArray); vtkSmartPointer< vtkPolyDataMapper > sphereMapper = vtkSmartPointer< vtkPolyDataMapper >::New(); sphereMapper->SetInput( sphereSource->GetOutput() ); vtkActor *sphereActor = vtkActor::New(); sphereActor->SetMapper(sphereMapper); sphereActor->SetVisibility(false); return sphereActor; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackEditingWidget::getClosestPoints() { MeshContainer::MultiIndexContainerTraceIDIterator it, it2, end; it = m_MeshContainer->m_Container.get< TraceID >().begin(); end = m_MeshContainer->m_Container.get< TraceID >().end(); it2 = it; while ( it != end ) { it2 = it; it2++; while ( it2 != end ) { double distance = sqrt( vtkMath::Distance2BetweenPoints( it->Nodes->GetCenter(), it2->Nodes->GetCenter() ) ); if ( it->TraceID != it2->TraceID ) { m_MinimalDistance = std::min(m_MinimalDistance, distance); } ++it2; } it2 = m_MeshContainer->m_Container.get< TraceID >().begin(); ++it; } } GoFigure2-v0.9.0/Code/GUI/lib/ConversionLsmToMegaThread.h0000644000175000017500000001045111667757442022640 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __ConversionLsmToMegaThread_h #define __ConversionLsmToMegaThread_h #include #include #include #include "fstream" #include "GoFigureGlobalDefinition.h" #include "QGoGUILibConfigure.h" class vtkLSMReader; class QGOGUILIB_EXPORT ConversionLsmToMegaThread:public QThread { Q_OBJECT public: /** * \brief Constructor */ ConversionLsmToMegaThread(); /** * \brief Destructor */ virtual ~ConversionLsmToMegaThread(); /** * \brief Set the base name of the LSM file to convert * \param[in] iBaseName Name of the LSM file */ void SetBaseName(std::string iBaseName); /** * \brief Set the path to the LSM file to convert and initialise LSM reader * \param[in] iLsmPath Path of the LSM file */ void SetLsmPath(std::string iLsmPath); /** * \brief Set the path of the MegaCapture file to create * \param[in] iMegaPath Path of the MegaCapture file */ void SetMegaPath(std::string iMegaPath); /** * \brief Set the output file type * \param[in] iFileType File type: PNG or TIFF */ void SetOutputFileType(const GoFigure::FileType & iFileType); /** * \brief Start the conversion to MegaCapture * \param[in] iMegaPath path of the output MegaCapture file */ void ExportWithReimplemented(std::string iMegaPath); /** * \brief Returns the number of signals to be sent for the progress bar */ int GetNumberOfPoints(); public slots : signals: void ConversionTerminatedSent(); void InitialisationProgressSent(); void ProgressSent(); protected: /** * \brief Start multithread process (call when parameters are set up properly) */ void run(); private: ConversionLsmToMegaThread(const ConversionLsmToMegaThread &); ConversionLsmToMegaThread operator=(const ConversionLsmToMegaThread &); std::string m_BaseName; std::string m_LsmPath; std::string m_MegaPath; GoFigure::FileType m_FileType; std::vector< vtkLSMReader * > m_LSMReaders; unsigned int m_Plaque; unsigned int m_Row; unsigned int m_Column; unsigned int m_XTile; unsigned int m_YTile; unsigned int m_ZTile; double m_XOverlap; double m_YOverlap; double m_ZOverlap; unsigned int m_NumberOfChannels; unsigned int m_NumberOfTimePoints; unsigned int m_Dim; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoColorComboBox.h0000755000175000017500000001004111667757442020726 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoColorComboBox_h #define __QGoColorComboBox_h #include "QGoGUILibConfigure.h" #include "QGoComboBox.h" /** \class QGoColorComboBox \brief inherits from QGoComboBox, display not ony the names but also the QColor of the items as an Icon in the combobox \ingroup GUI */ class QGOGUILIB_EXPORT QGoColorComboBox:public QGoComboBox { Q_OBJECT public: explicit QGoColorComboBox(std::string iTextToAddANewOne, QWidget *iparent = 0, std::string iTextToDelete = ""); virtual ~QGoColorComboBox(); typedef std::pair< std::string, QColor > ItemColorComboboxData; /** \brief call the method setItemsWithColorFromList and send a signal with the current index. \param[in] iDataFromList contains the names and the QColor of the items to be displayed in the combobox */ void InitializeTheListWithColor( std::list< ItemColorComboboxData > iDataFromList); /** \brief add an item with color at the end of the list befor the "add new..." if they have already been added to the list and select it if selectetheaddeditem is set to true. \param[in] iNewItemData name and QColor of the new item to be added \param[in] SelectTheAddedItem if true, the new added item will be the selectedone in the combobox */ void AddItemWithColor(ItemColorComboboxData iNewItemData, bool SelectTheAddedItem = true); /** \brief clear the items already in the combobox,displayed the one in the iDataFromList and the items to add/delete \param[in] iDataFromList contains the names and QColor of the items to be displayed in the combobox */ void SetItemsFromListWithColor( std::list< ItemColorComboboxData > iDataFromList); signals: void ItemSelected(ItemColorComboboxData); protected: /** \brief get the name and the QColor of the item located at the index iIndex \param[in] iIndex index for which the name and QColor are wanted \return ItemColorComboboxData contains the name and QColor of the item located at index iIndex */ ItemColorComboboxData GetTheItemColorComboBoxData(int iIndex); protected slots: /** \brief slot linked to the signal AddANewOneActivated() */ virtual void ActionWhenNewOneRequested() = 0; //mother class method virtual void EmitActivatedItem(int iIndexActivatedItem); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoToolBarStatus.h0000644000175000017500000000762511667757442021000 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoToolBarStatus_h #define __QGoToolBarStatus_h #include #include #include #include #include #include "QGoGUILibConfigure.h" class QGOGUILIB_EXPORT QGoToolBarStatus:public QObject { Q_OBJECT public: explicit QGoToolBarStatus(QWidget* iParent = 0); explicit QGoToolBarStatus(const QGoToolBarStatus & iS); explicit QGoToolBarStatus( Qt::ToolBarArea iArea, const bool & iVisibility, const bool & iAttached, QWidget* iParent = 0); explicit QGoToolBarStatus(QToolBar* iToolBar, QMenu* iMenu, Qt::ToolBarArea iArea, const bool & iVisibility, const bool & iAttached, QWidget* iParent = 0, QWidget* iWidget = 0); virtual ~QGoToolBarStatus(); void InitializeToolBarAndMenu(QToolBar* iToolBar, QMenu* iMenu); /** \brief clear the toolbar and disconnect all the slots inside this class connected to the toolbar*/ void ClearToolBar(); /** \brief add all the actions coontained in the m_VectorAction into the toolbar and connect the slots*/ void SetUpToolBar(); /*\\todo Nicolas why public?? */ // variables - why public....? QToolBar * m_ToolBar; QMenu * m_Menu; /** \brief Position */ Qt::ToolBarArea m_Area; Qt::ToolBarArea m_DefaultArea; /** \brief is Visible */ bool m_Visibility; /** \brief Attached to QGoMainWindow*/ bool m_Attached; std::vector< QAction* > m_VectorAction; public slots: /** \brief set the area of the m_ToolBar*/ void SetArea(Qt::ToolBarArea iArea); /** \brief set the visibility of the m_ToolBar*/ void SetVisibility(bool iVisibility); /** \brief set the floated status of the m_ToolBar*/ void SetAttached(bool iAttached); protected: QWidget* m_Widget; /** \brief set the signal slots connections to update m_visibility, m_Attached and m_Area with the toolbar */ //void Connect(); /** \brief disconnect all the signal slots with the toolbar*/ //void Disconnect(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoTraceSettingsWidget.cxx0000644000175000017500000005672611667757442022536 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTraceSettingsWidget.h" #include #include #include #include #include #include QGoTraceSettingsWidget::QGoTraceSettingsWidget(QWidget *iParent) : QWidget(iParent) { this->SetUpUi(); this->setObjectName("TraceSettingsWidget"); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoTraceSettingsWidget:: ~QGoTraceSettingsWidget() { if ( this->m_SelectedCollectionData ) { delete this->m_SelectedCollectionData; } if ( this->m_SelectedCellType ) { delete this->m_SelectedCellType; } if ( this->m_SelectedSubCellType ) { delete this->m_SelectedSubCellType; } if ( this->m_SelectedColorData ) { delete this->m_SelectedColorData; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetUpUi() { //QWidget* TraceSettingsWidget = new QWidget(this); QHBoxLayout* MainLayout = new QHBoxLayout; QLabel* Blank = new QLabel(this); SetTraceCollectionColorComboBox(MainLayout, Blank); MainLayout->addWidget(Blank); SetSelectedColorComboBox(MainLayout); MainLayout->addWidget(Blank); SetCellTypeComboBox(MainLayout); SetSubCellTypeComboBox(MainLayout); this->SetWidgetFont(); //this->UpdateTraceAndCollection("contour", "mesh"); this->SetCurrentTraceName("contour"); this->setLayout(MainLayout); this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); //m_IsToolBarVisible = false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetListCollectionID( std::list< ItemColorComboboxData > iListExistingID, std::string iCollectionIDtoSelect) { if (this->m_CollectionName->text() == "lineage" || this->m_CollectionName->text() == "") { return; } if ( !iCollectionIDtoSelect.empty() ) { this->m_CollectionColorComboBox-> SetItemsFromListWithColor( iListExistingID, this->m_CollectionName->text().toStdString() ); this->m_CollectionColorComboBox-> SetCurrentItemAndActivate(iCollectionIDtoSelect); } else { this->m_CollectionColorComboBox-> InitializeTheListWithColor( iListExistingID, this->m_CollectionName->text().toStdString() ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetListColors( std::list< ItemColorComboboxData > iListColors, std::string iColorToSelect) { this->SetListItemAndSelect< QGoSelectedColorComboBox >(this->m_SelectedColorComboBox, iListColors, iColorToSelect); this->m_SelectedColorComboBox->SetCurrentItemAndActivate(iColorToSelect); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetListColorsWithSelectedOne( std::list< ItemColorComboboxData > iListColors) { this->SetListColors(iListColors, this->m_SelectedColorData->first); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetListCellTypes(NamesDescrContainerType iCellTypesData, std::string iCellTypeToSelect) { this->SetListItemAndSelect< QGoComboBox >(this->m_ChoseCellType, iCellTypesData, iCellTypeToSelect); this->m_ChoseCellType->SetCurrentItemAndActivate(iCellTypeToSelect); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetListCellTypeWithSelectedOne( NamesDescrContainerType iCellTypesData) { this->SetListCellTypes(iCellTypesData, *this->m_SelectedCellType); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetListSubCellTypes(NamesDescrContainerType iSubCellTypesData, std::string iSubCellTypeToSelect) { this->SetListItemAndSelect< QGoComboBox >(this->m_ChoseSubCellType, iSubCellTypesData, iSubCellTypeToSelect); this->m_ChoseSubCellType->SetCurrentItemAndActivate(iSubCellTypeToSelect); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetListSubCellTypeWithSelectedOne( NamesDescrContainerType iSubCellTypesData) { this->SetListSubCellTypes(iSubCellTypesData, *this->m_SelectedSubCellType); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetSelectedColorComboBox( QHBoxLayout* iColorLayout) { QString Tooltip(tr("Color to be applied to your new traces") ); this->m_SelectedColorComboBox = new QGoSelectedColorComboBox; this->m_SelectedColorComboBox->setToolTip(Tooltip); QLabel* ColorLbl = new QLabel(tr("Color:"), this); ColorLbl->setToolTip(Tooltip); iColorLayout->addWidget(ColorLbl); iColorLayout->addWidget(this->m_SelectedColorComboBox); this->m_SelectedColorData = new ItemColorComboboxData; QObject::connect( this->m_SelectedColorComboBox, SIGNAL( ItemSelected(ItemColorComboboxData) ), this, SLOT( UpdateValueSelectedColor(ItemColorComboboxData) ) ); QObject::connect( this->m_SelectedColorComboBox, SIGNAL( AddNewColorActivated() ), this, SIGNAL( AddNewColor() ) ); QObject::connect( this->m_SelectedColorComboBox, SIGNAL( DeleteActivated() ), this, SIGNAL( DeleteColor() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetTraceCollectionColorComboBox( QHBoxLayout* iLayoutTraceCollection, QLabel* iLabel) { QString Tooltip(tr("Current trace you are working on") ); this->m_SelectedTrace = new QComboBox(this); this->m_SelectedTrace->setToolTip(Tooltip); QStringList ListTraces; ListTraces.append("contour"); ListTraces.append("mesh"); ListTraces.append("track"); ListTraces.append("lineage"); this->m_SelectedTrace->addItems(ListTraces); //QHBoxLayout *HLayoutForTrace = new QHBoxLayout; //this->m_TraceLbl = new QLabel(tr("Trace:"), this); //HLayoutForTrace->addWidget(this->m_TraceLbl); //HLayoutForTrace->addWidget(this->m_TraceName); //this->m_CollectionLbl = new QLabel( tr("Collection:") ); QString Tooltip2(tr("Corresponding collection for the selected trace") ); this->m_CollectionName = new QLabel ( tr("mesh") ); this->m_CollectionName->setToolTip(Tooltip2); QString Tooltip3(tr("ID of the collection your new traces will belong to") ); this->m_CollectionColorComboBox = new QGoCollectionColorComboBox; this->m_CollectionColorComboBox->setToolTip(Tooltip3); //QHBoxLayout *HLayoutForCollection = new QHBoxLayout; //HLayoutForCollection->addWidget(this->m_CollectionName); //HLayoutForCollection->addWidget(this->m_CollectionColorComboBox); //iLayoutTraceCollection->addLayout(HLayoutForTrace); //iLayoutTraceCollection->addWidget(this->m_CollectionLbl); iLayoutTraceCollection->addWidget(this->m_SelectedTrace); iLayoutTraceCollection->addWidget(iLabel); iLayoutTraceCollection->addWidget(this->m_CollectionName); iLayoutTraceCollection->addWidget(this->m_CollectionColorComboBox); //iLayoutTraceCollection->addLayout(HLayoutForCollection); this->m_SelectedCollectionData = new ItemColorComboboxData; QObject::connect( this->m_CollectionColorComboBox, SIGNAL( ItemSelected(ItemColorComboboxData) ), this, SLOT( UpdateValueSelectedCollection(ItemColorComboboxData) ) ); QObject::connect( this->m_CollectionColorComboBox, SIGNAL( NewCollectionToCreate() ), this, SIGNAL( NewCollectionToBeCreated() ) ); QObject::connect( this->m_SelectedTrace, SIGNAL( currentIndexChanged ( int ) ), this, SLOT ( CurrentTraceToUpdate( int ) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetCellTypeComboBox( QHBoxLayout* iCellLayout) { /* this->m_ChoseCellType = new QGoComboBox("Add a new celltype...", this, "Delete a celltype...");*/ QString Tooltip(tr("Celltype that will be applied to your new meshes") ); this->m_ChoseCellType = new QGoComboBox("Add a new celltype...", this); this->m_ChoseCellType->setToolTip(Tooltip); QHBoxLayout *HLayoutForCellType = new QHBoxLayout; this->m_LabelCellType = new QLabel(tr("CellType:"), this); this->m_LabelCellType->setToolTip(Tooltip); HLayoutForCellType->addWidget(this->m_LabelCellType); HLayoutForCellType->addWidget(m_ChoseCellType); iCellLayout->addLayout(HLayoutForCellType); this->m_SelectedCellType = new std::string; QObject::connect( this->m_ChoseCellType, SIGNAL( ItemSelected(std::string) ), this, SLOT( UpdateValueSelectedCellType(std::string) ) ); QObject::connect( this->m_ChoseCellType, SIGNAL( AddANewOneActivated() ), this, SIGNAL( AddANewCellType() ) ); QObject::connect( this->m_ChoseCellType, SIGNAL( DeleteActivated() ), this, SIGNAL( DeleteCellType() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetSubCellTypeComboBox( QHBoxLayout* iSubCellLayout) { QString Tooltip(tr("SubCellulartype that will be applied to your new meshes") ); this->m_ChoseSubCellType = new QGoComboBox("Add a new subcelltype...", this); this->m_ChoseSubCellType->setToolTip(Tooltip); this->m_LabelSubCellType = new QLabel(tr("SubCellType:"), this); this->m_LabelSubCellType->setToolTip(Tooltip); iSubCellLayout->addWidget(this->m_LabelSubCellType); iSubCellLayout->addWidget(m_ChoseSubCellType); this->m_SelectedSubCellType = new std::string; QObject::connect( this->m_ChoseSubCellType, SIGNAL( ItemSelected(std::string) ), this, SLOT( UpdateValueSelectedSubCellType(std::string) ) ); QObject::connect( this->m_ChoseSubCellType, SIGNAL( AddANewOneActivated() ), this, SIGNAL( AddANewSubCellType() ) ); QObject::connect( this->m_ChoseSubCellType, SIGNAL( DeleteActivated() ), this, SIGNAL( DeleteSubCellType() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetCurrentCellType( std::string iCellTypeText) { this->m_ChoseCellType->SetCurrentItem(iCellTypeText); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetCurrentCellTypeToSelectedOne() { this->SetCurrentCellType(*this->m_SelectedCellType); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetCurrentSubCellType( std::string iSubCellTypeText) { this->m_ChoseSubCellType->SetCurrentItem(iSubCellTypeText); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetCurrentSubCellTypeToSelectedOne() { this->SetCurrentSubCellType(*this->m_SelectedSubCellType); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetCurrentColor(std::string iColorText) { this->m_SelectedColorComboBox->SetCurrentItem(iColorText); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetCurrentColorToSelectedOne() { this->SetCurrentColor(this->m_SelectedColorData->first); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetCurrentCollectionID(std::string iID) { this->m_CollectionColorComboBox->SetCurrentItem(iID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*void QGoTraceSettingsWidget::UpdateTraceAndCollection(std::string iTrace, std::string iCollection) { this->m_SelectedTrace->setCurrentIndex( this->m_SelectedTrace->findText(iTrace.c_str() ) ); this->UpdateCollection(iCollection); }*/ //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::UpdateCollection( std::string iCollection) { this->m_CollectionName->setText( iCollection.c_str() ); this->m_CollectionName->show(); if (this->m_SelectedTrace->currentText() == "contour" || this->m_SelectedTrace->currentText() == "mesh") { this->m_ChoseCellType->show(); this->m_LabelCellType->show(); this->m_ChoseSubCellType->show(); this->m_LabelSubCellType->show(); this->m_CollectionName->show(); this->m_CollectionColorComboBox->show(); } else { this->m_ChoseCellType->hide(); this->m_LabelCellType->hide(); this->m_ChoseSubCellType->hide(); this->m_LabelSubCellType->hide(); this->m_CollectionColorComboBox->hide(); } if (this->m_SelectedTrace->currentText() == "lineage") { this->m_CollectionName->hide(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetWidgetFont() { //all widget: QFont Font; Font.setCapitalization(QFont::Capitalize); this->setFont(Font); //trace and collection name: Font.setCapitalization(QFont::AllUppercase); Font.setBold(true); this->m_SelectedTrace->setFont(Font); this->m_CollectionName->setFont(Font); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoTraceSettingsWidget::GetTraceName() { return this->m_SelectedTrace->currentText().toStdString(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::AddANewCollectionID( std::pair iNewCollectionID) { this->m_CollectionColorComboBox->AddItemWithColor(iNewCollectionID, true); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string * QGoTraceSettingsWidget::GetPointerSelectedCellType() { return this->m_SelectedCellType; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string * QGoTraceSettingsWidget::GetPointerSelectedSubCellType() { return this->m_SelectedSubCellType; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoTraceSettingsWidget::ItemColorComboboxData * QGoTraceSettingsWidget::GetPointerCollectionData() { return this->m_SelectedCollectionData; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoTraceSettingsWidget::ItemColorComboboxData * QGoTraceSettingsWidget::GetPointerColorData() { return this->m_SelectedColorData; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::UpdateValueSelectedCollection( ItemColorComboboxData iCollectionData) { std::string CollectionID = iCollectionData.first; if ( CollectionID.size() > 9 ) { if ( CollectionID.substr(0, 9) == "Add a new" ) { this->m_SelectedCollectionData->first = "0"; } } else { *this->m_SelectedCollectionData = iCollectionData; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /** \todo Lydie: except when adding a new value, these methods are called twice when something changes in the comboboxes*/ void QGoTraceSettingsWidget::UpdateValueSelectedCellType(std::string iCellType) { *this->m_SelectedCellType = iCellType; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::UpdateValueSelectedSubCellType(std::string iSubCellType) { *this->m_SelectedSubCellType = iSubCellType; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::UpdateValueSelectedColor( ItemColorComboboxData iColorData) { *this->m_SelectedColorData = iColorData; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoTraceSettingsWidget::GetCurrentSelectedCollectionID() { return atoi( this->m_SelectedCollectionData->first.c_str() ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::CurrentTraceToUpdate( int iIndexTrace ) { if (this->m_SelectedTrace->currentText() == "contour") { this->UpdateCollection("mesh"); } if (this->m_SelectedTrace->currentText() == "mesh") { this->UpdateCollection("track"); } if (this->m_SelectedTrace->currentText() == "track") { this->UpdateCollection("lineage"); } if (this->m_SelectedTrace->currentText() == "lineage") { this->UpdateCollection(""); } emit TraceChanged( iIndexTrace ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetPointerSelectedCellType(std::string* iCellType) { if(this->m_SelectedCellType) { delete this->m_SelectedCellType; this->m_SelectedCellType = NULL; } this->m_SelectedCellType = iCellType; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetPointerSelectedSubCellType(std::string* iSubCellType) { if(this->m_SelectedSubCellType) { delete this->m_SelectedSubCellType; this->m_SelectedSubCellType = NULL; } this->m_SelectedSubCellType = iSubCellType; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetPointerCollectionData(ItemColorComboboxData* iCollectionData) { if(this->m_SelectedCollectionData) { delete this->m_SelectedCollectionData; this->m_SelectedCollectionData = NULL; } this->m_SelectedCollectionData = iCollectionData; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetPointerColorData(ItemColorComboboxData* iColorData) { if(this->m_SelectedColorData) { delete this->m_SelectedColorData; this->m_SelectedColorData = NULL; } this->m_SelectedColorData = iColorData; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetSelectedPointersToNull() { this->m_SelectedCollectionData = NULL; this->m_SelectedColorData = NULL; this->m_SelectedCellType = NULL; this->m_SelectedSubCellType = NULL; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetCurrentTraceName(std::string iTraceName) { this->m_SelectedTrace->setCurrentIndex( this->m_SelectedTrace->findText(iTraceName.c_str() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/QGoNetworkUtilities.h0000644000175000017500000000531411667757442021550 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoNetworkUtilities_h #define __QGoNetworkUtilities_h #include #include "QGoGUILibConfigure.h" class QNetworkAccessManager; class QNetworkReply; /**\class QGoNetworkUtilities * \brief As of now, the main purpose of this class is to check for updates * on the official download site of gofigure */ class QGOGUILIB_EXPORT QGoNetworkUtilities:public QObject { Q_OBJECT public: /** \brief Constructor */ explicit QGoNetworkUtilities(QObject *parent = 0); /** \brief Destructor */ ~QGoNetworkUtilities(); /** \brief Check for updates */ void CheckForUpdates(); signals: /** \brief checking for udpate task is complete */ void CheckForUpdatesDone(QString msg, bool error); public slots: /** \brief display the result of query (Is it up-to-date?) */ virtual void DisplayResults(QNetworkReply *reply); protected: QNetworkAccessManager *m_Manager; QNetworkReply * m_Reply; }; #endif // NETWORKUTILS_H GoFigure2-v0.9.0/Code/GUI/lib/Watershed.cxx0000644000175000017500000001537011667757442020120 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "Watershed.h" #include "QGoGUILibConfigure.h" // for apply method #include "vtkImageExport.h" #include "vtkImageData.h" //Connection VTK/ITK #include "vtkImageExport.h" #include "itkVTKImageImport.h" #include "itkVTKImageToImageFilter.h" #include "vtkitkAdaptor.h" // ITK filter #include "itkWatershedBasedCellSegmentation.h" #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkImageToVTKImageFilter.h" //-------------------------------------------------------------------------- Watershed::Watershed() { /*m_Radius = 3.0; m_Iterations = 15; m_Curvature = 5; m_Center[0] = 0; m_Center[1] = 0; m_Dimension = 3;*/ } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- Watershed:: ~Watershed() { //m_Input->Delete(); } //-------------------------------------------------------------------------- /* //-------------------------------------------------------------------------- void ChanAndVesLevelSet:: setCenter(double* iCenter) { m_Center[0] = iCenter[0]; m_Center[1] = iCenter[1]; m_Center[2] = iCenter[2]; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void ChanAndVesLevelSet:: setRadius(double iRadius) { m_Radius = iRadius; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void ChanAndVesLevelSet:: setIterations(int iIterations) { m_Iterations = iIterations; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void ChanAndVesLevelSet:: setCurvature(int iCurvature) { m_Curvature = iCurvature; } //-------------------------------------------------------------------------- */ /* //-------------------------------------------------------------------------- void ChanAndVesLevelSet:: setDimension(int iDimension) { m_Dimension = iDimension; } //-------------------------------------------------------------------------- */ //-------------------------------------------------------------------------- vtkImageData * Watershed::Apply() { //itkWatershedBasedCellSegmentation /* std::cout<<"PARAMETERS:" <SetInput( getInput() ); vtk2itkImage->Update(); // Define the dimension of the images const unsigned int Dimension = 3; typedef itk::Image< unsigned char, Dimension > FeatureImageType; typedef FeatureImageType::Pointer FeatureImagePointer; typedef itk::Image< double, Dimension > InputImageType; typedef InputImageType::IndexType InputImageIndexType; typedef InputImageType::Pointer InputImagePointer; typedef itk::Image< int, Dimension > SegmentImageType; typedef SegmentImageType::Pointer SegmentImagePointer; typedef itk::ImageFileReader< FeatureImageType > FeatureReaderType; typedef itk::ImageFileWriter< SegmentImageType > SegmentWriterType; typedef itk::WatershedBasedCellSegmentation< FeatureImageType, InputImageType, SegmentImageType > SegmentationFilterType; // ImageType typedef itk::Image< unsigned char, Dimension > ImageType; // Import VTK Image to ITK typedef itk::VTKImageImport< ImageType > ImageImportType; typedef ImageImportType::Pointer ImageImportPointer; ImageImportPointer movingImporter = ImageImportType::New(); ConnectPipelines< vtkImageExport, ImageImportPointer >( vtk2itkImage, movingImporter); std::cout << "===================IMAGE==========================" << std::endl; std::cout << "==================================================" << std::endl; //movingImporter->Update(); movingImporter->GetOutput()->Print(cout); SegmentationFilterType::Pointer filter = SegmentationFilterType::New(); filter->SetInput( movingImporter->GetOutput() ); //filter->Set filter->Update(); // segmentation parameters std::cout << "segmentation finished" << std::endl; typedef itk::ImageToVTKImageFilter< SegmentImageType > ConverterType; ConverterType::Pointer converter = ConverterType::New(); converter->SetInput( filter->GetOutput() ); converter->Update(); std::cout << "conversion finished" << std::endl; vtkImageData *output = vtkImageData::New(); output->DeepCopy( converter->GetOutput() ); std::cout << "copy finished" << std::endl; return output; } //--------------------------------------------------------------------------GoFigure2-v0.9.0/Code/GUI/lib/QGoTabImageViewNDBase.h0000644000175000017500000000552411667757442021547 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTabImageViewNDBase_h #define __QGoTabImageViewNDBase_h #include "QGoTabImageViewElementBase.h" #include "QGoGUILibConfigure.h" class vtkImageData; /** \class QGoTabImageViewNDBase * \brief Abstract class for representing one tab element which * contains 2D or 3D image (without any temporal component). */ class QGOGUILIB_EXPORT QGoTabImageViewNDBase:public QGoTabImageViewElementBase { Q_OBJECT public: /** \brief Constructor */ explicit QGoTabImageViewNDBase(QWidget *parent = 0); /** \brief Destructor */ virtual ~QGoTabImageViewNDBase(); typedef QGoTabImageViewElementBase::QGoDockWidgetStatusPair QGoDockWidgetStatusPair; /** \brief */ virtual void SetImage(vtkImageData *iImage); /** \brief */ vtkImageData * GetImage(); public slots: /** \brief */ void ShowAllChannels(bool iChecked); /** \brief */ void ShowOneChannel(int iChannel); protected: vtkSmartPointer< vtkImageData > m_Image; /** \brief */ virtual void SetImageToImageViewer(vtkImageData *image) = 0; private: Q_DISABLE_COPY(QGoTabImageViewNDBase); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoTraceSettingsWidget.h0000644000175000017500000003016711667757442022152 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTraceSettingsWidget_h #define __QGoTraceSettingsWidget_h #include #include #include #include #include #include "QGoSelectedColorComboBox.h" #include "QGoCollectionColorComboBox.h" #include "QGoComboBox.h" #include #include "QGoGUILibConfigure.h" /** \class QGoTraceSettingsWidget \brief this class contains all the comboboxes for collectionID,color, celltypes and subcelltypes, and displays the trace and collection name. \ingroup GUI */ class QGOGUILIB_EXPORT QGoTraceSettingsWidget: public QWidget { Q_OBJECT public: explicit QGoTraceSettingsWidget(QWidget *parent = 0); ~QGoTraceSettingsWidget(); typedef QGoColorComboBox::ItemColorComboboxData ItemColorComboboxData; typedef std::vector< std::pair< std::string, std::string > > NamesDescrContainerType; QComboBox * m_SelectedTrace; QGoSelectedColorComboBox* m_SelectedColorComboBox; QGoCollectionColorComboBox* m_CollectionColorComboBox; QGoComboBox * m_ChoseCellType; QGoComboBox * m_ChoseSubCellType; /** \brief get the name of the trace currently displayed in the QLabel \return std::string contains the name of the trace */ std::string GetTraceName(); /** \brief set the selected celltype in the combobox corresponding to iCellTypeText \param[in] iCellTypeText name of the CellType to be selected */ void SetCurrentCellType(std::string iCellTypeText); /** \brief set the selected subcelltype in the combobox corresponding to the previous selected one, stored in m_SelectedSubCellType */ void SetCurrentCellTypeToSelectedOne(); /** \brief set the selected subcelltype in the combobox corresponding to iSubCellTypeText \param[in] iSubCellTypeText name of the SubCellType to be selected */ void SetCurrentSubCellType(std::string iSubCellTypeText); /** \brief set the selected subcelltype in the combobox corresponding to the previous selected one, stored in m_SelectedSubCellType */ void SetCurrentSubCellTypeToSelectedOne(); /** \brief set the selected color in the combobox corresponding to iColorText \param[in] iColorText name of the Color to be selected */ void SetCurrentColor(std::string iColorText); /** \brief set the selected color in the combobox corresponding to the previous selected one, stored in m_SelectedColorData */ void SetCurrentColorToSelectedOne(); /** \brief set the selected collectionID in the combobox to iID \param[in] iID ID of the collection to be selected */ void SetCurrentCollectionID(std::string iID); void SetCurrentTraceName(std::string iTraceName); /** \brief update the QLabel with iTrace and iCollection, the "add a new.." in the CollectionColorComboBox and hide/show the celltype and subcelltype comboboxes according to the iTrace \param[in] iTrace name of the trace to update \param[in] iCollection name of the collection to update */ //void UpdateTraceAndCollection( // std::string iTrace, std::string iCollection); /** \brief replace the list of collectionID with the ID and corresponding color in the iListExistingID and select the ID corresponding to iCollectionIDtoSelect if not empty, if empty, select the 1rst one \param[in] iListExistingID list of IDs with QColor to be displayed \param[in] iCollectionIDtoSelect ID to be selected in the combobox */ void SetListCollectionID( std::list< ItemColorComboboxData > iListExistingID, std::string iCollectionIDtoSelect = ""); /** \brief replace the list of colors with the name and corresponding color in the iListColors and select the color corresponding to iColortoSelect if not empty, if empty, select the 1rst one \param[in] iListColors list of colors with their names and QColor to be displayed \param[in] iColorToSelect name of the color to be selected in the combobox */ void SetListColors(std::list< ItemColorComboboxData > iListColors, std::string iColorToSelect = ""); /** \brief replace the list of colors with the name and corresponding color in the iListColors and select the color corresponding to m_SelectedColorData \param[in] iListColors list of colors with their names and QColor to be displayed */ void SetListColorsWithSelectedOne(std::list< ItemColorComboboxData > iListColors); /** \brief replace the list of celltype with the names in the iCellTypesData and select the celltype corresponding to iCellTypetoSelect if not empty, if empty, select the 1rst one. \param[in] iCellTypesData list of celltypes with their names and description to be displayed \param[in] iCellTypeToSelect name of the celltype to be selected in the combobox */ void SetListCellTypes(NamesDescrContainerType iCellTypesData, std::string iCellTypeToSelect = ""); /** \brief replace the list of celltype with the name in the iCellTypesData and select the celltype corresponding to m_SelectedCelltype \param[in] iCellTypesData list of celltypes with their names and description to be displayed */ void SetListCellTypeWithSelectedOne(NamesDescrContainerType iCellTypesData); /** \brief replace the list of subcelltype with the names in the iSubCellTypesData and select the subcelltype corresponding to iSubCellTypetoSelect if not empty, if empty, select the 1rst one. \param[in] iSubCellData list of subcelltypes with their names and description to be displayed \param[in] iSubCellTypeToSelect name of the subcelltype to be selected in the combobox */ void SetListSubCellTypes(NamesDescrContainerType iSubCellData, std::string iSubCellTypeToSelect = ""); /** \brief replace the list of subcelltype with the name in the iSubCellTypesData and select the subcelltype corresponding to m_SelectedSubCelltype \param[in] iSubCellTypesData list of subcelltypes with their names and description to be displayed */ void SetListSubCellTypeWithSelectedOne(NamesDescrContainerType iSubCellTypesData); std::string* GetPointerSelectedCellType(); std::string* GetPointerSelectedSubCellType(); ItemColorComboboxData* GetPointerCollectionData(); ItemColorComboboxData* GetPointerColorData(); void SetPointerSelectedCellType(std::string* iCellType); void SetPointerSelectedSubCellType(std::string* iSubCellType); void SetPointerCollectionData(ItemColorComboboxData* iCollectionData); void SetPointerColorData(ItemColorComboboxData* iColorData); unsigned int GetCurrentSelectedCollectionID(); //bool GetIsToolBarVisible(); public slots: /** \brief add a new collection in the collectionColorCombobox and select it \param[in] iNewCollectionID ID and QColor of the new item */ void AddANewCollectionID(std::pair iNewCollectionID); /** \brief in order the pointers already deleted are not deleted again */ void SetSelectedPointersToNull(); //void SetVisibilityStatus(bool IsVisible); signals: void AddANewCellType(); void DeleteCellType(); void AddANewSubCellType(); void DeleteSubCellType(); void AddNewColor(); void DeleteColor(); void NewCollectionToBeCreated(); void TraceChanged( int ); protected: QLabel * m_CollectionName; QLabel* m_LabelCellType; QLabel* m_LabelSubCellType; std::string * m_SelectedCellType; std::string * m_SelectedSubCellType; ItemColorComboboxData * m_SelectedCollectionData; ItemColorComboboxData * m_SelectedColorData; //bool m_IsToolBarVisible; void SetUpUi(); /** \brief add the SelectedColorCombobox to the layout and make the signal/slot connections for it */ void SetSelectedColorComboBox(QHBoxLayout* iColorLayout); /** \brief add the CollectionColorCombobox to the layout,set the trace and collection name labels, and make the signal/slot connections for it */ void SetTraceCollectionColorComboBox( QHBoxLayout* iLayoutTraceCollection, QLabel* iLabel); /** \brief add the Celltype QGoCombobox to the layout and make the signal/slot connections for it */ void SetCellTypeComboBox( QHBoxLayout* iCellLayout); /** \brief add the SubCellType QGoCombobox to the layout and make the signal/slot connections for it */ void SetSubCellTypeComboBox( QHBoxLayout* iSubCellLayout); void SetWidgetFont(); void UpdateCollection(std::string iCollection); /** \brief call the right methods to initialize the list if there is no iTextItemToSelect or select the iTextItemToSelect if not empty. \param[in] iComboBox the combobox with the list to be set up \param[in] iItemsData the list of items with their names and descriptions to be displayed \param[in] iTextItemToSelect the item to be selected \tparam T could be a QGoComboBox */ template< typename T > void SetListItemAndSelect(T *iComboBox, NamesDescrContainerType iItemsData, std::string iTextItemToSelect = "") { if ( !iTextItemToSelect.empty() ) { iComboBox->SetItemsFromList(iItemsData); if ( iComboBox->findText( iTextItemToSelect.c_str() ) != -1 ) { iComboBox->SetCurrentItem(iTextItemToSelect); } else { iComboBox->SetCurrentItemAndActivate(0); } } else { iComboBox->InitializeTheList(iItemsData); } } /** \overload */ template< typename T > void SetListItemAndSelect(T *iComboBox, std::list< ItemColorComboboxData > iItemsData, std::string iTextItemToSelect = "") { if ( !iTextItemToSelect.empty() ) { iComboBox->SetItemsFromListWithColor(iItemsData); if ( iComboBox->findText( iTextItemToSelect.c_str() ) != -1 ) { iComboBox->SetCurrentItem(iTextItemToSelect); } else { iComboBox->SetCurrentItemAndActivate(0); } } else { iComboBox->InitializeTheListWithColor(iItemsData); } } protected slots: void UpdateValueSelectedCollection(ItemColorComboboxData iCollectionData); void UpdateValueSelectedCellType(std::string iCellType); void UpdateValueSelectedSubCellType(std::string iSubCellType); void UpdateValueSelectedColor(ItemColorComboboxData iColorData); /** brief update the correspodning collection when the current trace has been changed and emit a signal that the trace has been changed */ void CurrentTraceToUpdate(int iIndex); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoNavigationDockWidget.cxx0000644000175000017500000003617611667757442022654 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoNavigationDockWidget.h" #include #include #include #include #include #include #include QGoNavigationDockWidget:: QGoNavigationDockWidget( QWidget *iParent, const GoFigure::TabDimensionType & iDim ) : QGoDockWidget(iParent), m_Dimension(iDim) { this->setupUi(this); QIcon Navigation; Navigation.addPixmap(QPixmap( QString::fromUtf8(":/fig/navigation.png") ), QIcon::Normal, QIcon::Off); this->m_ToggleAction->setIcon(Navigation); switch ( m_Dimension ) { case GoFigure::TWO_D: { this->XSliceLbl->setVisible(false); this->XSliceSpinBox->setVisible(false); this->YSliceLbl->setVisible(false); this->YSliceSpinBox->setVisible(false); this->ZSliceLbl->setVisible(false); this->ZSliceSpinBox->setVisible(false); this->TSliceLbl->setVisible(false); this->TSliceSpinBox->setVisible(false); break; } case GoFigure::TWO_D_WITH_T: { this->XSliceLbl->setVisible(false); this->XSliceSpinBox->setVisible(false); this->YSliceLbl->setVisible(false); this->YSliceSpinBox->setVisible(false); this->ZSliceLbl->setVisible(false); this->ZSliceSpinBox->setVisible(false); break; } case GoFigure::THREE_D: { this->TSliceLbl->setVisible(false); this->TSliceSpinBox->setVisible(false); break; } default: case GoFigure::THREE_D_WITH_T: { break; } } QObject::connect( this->XSliceSpinBox, SIGNAL( valueChanged(int) ), this, SIGNAL( XSliceChanged(int) ) ); QObject::connect( this->YSliceSpinBox, SIGNAL( valueChanged(int) ), this, SIGNAL( YSliceChanged(int) ) ); QObject::connect( this->ZSliceSpinBox, SIGNAL( valueChanged(int) ), this, SIGNAL( ZSliceChanged(int) ) ); QObject::connect( this->TSliceSpinBox, SIGNAL( valueChanged(int) ), this, SIGNAL( TSliceChanged(int) ) ); // doppler view specific widgets this->channelLabel->hide(); this->channelName->hide(); this->stepLabel->hide(); this->step->hide(); this->tLabel->hide(); this->t->hide(); m_Classic = true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoNavigationDockWidget:: ~QGoNavigationDockWidget() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget::SetXSlice(int iSlice) { this->XSliceSpinBox->setValue(iSlice); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget::SetYSlice(int iSlice) { this->YSliceSpinBox->setValue(iSlice); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget::SetZSlice(int iSlice) { this->ZSliceSpinBox->setValue(iSlice); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget::SetTSlice(int iSlice) { this->TSliceSpinBox->setValue(iSlice); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget::SetXMinimumAndMaximum(const int & iMin, const int & iMax) { if( iMin != iMax ) { this->XSliceSpinBox->setMinimum(iMin); this->XSliceSpinBox->setMaximum(iMax); this->XSliceSlider->setMinimum(iMin); this->XSliceSlider->setMaximum(iMax); this->MinXSlicelbl->setText( tr("%1").arg(iMin) ); this->MaxXSlicelbl->setText( tr("%1").arg(iMax) ); } else { this->YSliceLbl->hide(); this->YSliceSpinBox->hide(); this->YSliceSlider->hide(); this->MinYSlicelbl->hide(); this->MaxYSlicelbl->hide(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget::SetYMinimumAndMaximum(const int & iMin, const int & iMax) { if( iMin != iMax ) { this->YSliceSpinBox->setMinimum(iMin); this->YSliceSpinBox->setMaximum(iMax); this->YSliceSlider->setMinimum (iMin); this->YSliceSlider->setMaximum(iMax); this->MinYSlicelbl->setText( tr("%1").arg(iMin) ); this->MaxYSlicelbl->setText( tr("%1").arg(iMax) ); } else { this->YSliceLbl->hide(); this->YSliceSpinBox->hide(); this->YSliceSlider->hide(); this->MinYSlicelbl->hide(); this->MaxYSlicelbl->hide(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget::SetZMinimumAndMaximum(const int & iMin, const int & iMax) { if( iMin != iMax ) { this->ZSliceSpinBox->setMinimum(iMin); this->ZSliceSpinBox->setMaximum(iMax); this->ZSliceSlider->setMinimum (iMin); this->ZSliceSlider->setMaximum(iMax); this->MinZSlicelbl->setText( tr("%1").arg(iMin) ); this->MaxZSlicelbl->setText( tr("%1").arg(iMax) ); } else { this->ZSliceLbl->hide(); this->ZSliceSpinBox->hide(); this->ZSliceSlider->hide(); this->MinZSlicelbl->hide(); this->MaxZSlicelbl->hide(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget::SetTMinimumAndMaximum(const int & iMin, const int & iMax) { if( iMin != iMax ) { this->TSliceSpinBox->setMinimum(iMin); this->TSliceSpinBox->setMaximum(iMax); this->TSliceSlider->setMinimum (iMin); this->TSliceSlider->setMaximum(iMax); this->MinTSlicelbl->setText( tr("%1").arg(iMin) ); this->MaxTSlicelbl->setText( tr("%1").arg(iMax) ); QObject::connect( this->ModeComboBox, SIGNAL( activated(int) ), this, SIGNAL( ModeChanged(int) ) ); QObject::connect( this->ModeComboBox, SIGNAL( activated(int) ), this, SLOT( UpdateWidget(int) ) ); QObject::connect( this->step, SIGNAL( valueChanged(int) ), this, SIGNAL( StepChanged(int) ) ); QObject::connect( this->t, SIGNAL( valueChanged(int) ), this, SIGNAL( DopplerSizeChanged(int) ) ); } else { this->TSliceLbl->hide(); this->TSliceSpinBox->hide(); this->TSliceSlider->hide(); this->MinTSlicelbl->hide(); this->MaxTSlicelbl->hide(); this->ModeComboBox->hide(); this->channelLabel->hide(); this->channelName->hide(); this->stepLabel->hide(); this->step->hide(); this->tLabel->hide(); this->t->hide(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget::MoveToPreviousTimePoint() { if ( TSliceSpinBox->value() > TSliceSpinBox->minimum() ) { emit TSliceChanged(TSliceSpinBox->value() - 1); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget::MoveToNextTimePoint() { if ( TSliceSpinBox->value() < TSliceSpinBox->maximum() ) { emit TSliceChanged(TSliceSpinBox->value() + 1); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget::UpdateWidget(int iStep) { if ( iStep == 0 ) { this->channelLabel->hide(); this->channelName->hide(); this->stepLabel->hide(); this->step->hide(); this->tLabel->hide(); this->t->hide(); } else { this->channelLabel->show(); this->channelName->show(); this->stepLabel->show(); this->step->show(); this->tLabel->show(); this->t->show(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget:: AddChannel(const QString& iName, const QColor& iColor, const unsigned int& iNumber, const bool& iChecked) { // create check box + colored push button QCheckBox *checkBox1 = new QCheckBox(iName, this); checkBox1->setObjectName(iName); checkBox1->setChecked(iChecked); QString style = "border: 1px solid black; background-color: rgba(%1, %2, %3, 150); border-radius: 4px;"; checkBox1->setStyleSheet( style.arg(iColor.red()).arg(iColor .green()).arg(iColor.blue())); QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(checkBox1); // to be modified - 7 this->gridLayout_2->addLayout(layout, 7+iNumber, 0, 0); //create signals connections QObject::connect( checkBox1, SIGNAL( clicked(bool) ), this, SLOT( visibilityChanged(bool) ) ); // vector of widget so we can remove it from layout efficiently m_ListCheckBoxes.push_back(checkBox1); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget:: ModifyChannel(QString iName, QColor iColor) { //modify color of bg of checkbox! QList::iterator it2; // doppler view or not? if(m_Classic) { it2 = m_ListCheckBoxes.begin(); } else { it2 = m_ListDoppler.begin(); } while(iName.compare((*it2)->objectName()) != 0) { ++it2; } QString style = "border: 1px solid black; background-color: rgba(%1, %2, %3, 150); border-radius: 4px;"; (*it2)->setStyleSheet( style.arg(iColor.red()).arg(iColor .green()).arg(iColor.blue())); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget:: visibilityChanged(bool iVisibility) { emit visibilityChanged(QObject::sender()->objectName(), iVisibility); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget:: VisibilityListChannels(const bool& iVisibility) { QList::iterator it = m_ListCheckBoxes.begin(); while(it != m_ListCheckBoxes.end()) { (*it)->setVisible(iVisibility); (*it)->setChecked(iVisibility); ++it; } QList::iterator it2 = m_ListPushButtons.begin(); while(it2 != m_ListPushButtons.end()) { (*it2)->setVisible(iVisibility); ++it2; } m_Classic = iVisibility; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget:: AddDoppler(const QString& iName, const QColor& iColor, const unsigned int& iNumber, const bool& iChecked) { // create check box + colored push button QCheckBox *checkBox1 = new QCheckBox(iName, this); checkBox1->setObjectName(iName); checkBox1->setChecked(iChecked); QString style = "border: 1px solid black; background-color: rgba(%1, %2, %3, 100); border-radius: 4px;"; checkBox1->setStyleSheet( style.arg(iColor.red()).arg(iColor .green()).arg(iColor.blue())); QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(checkBox1); // to be modified - 7 this->gridLayout_2->addLayout(layout, 7+iNumber, 0, 0); //create signals connections QObject::connect( checkBox1, SIGNAL( clicked(bool) ), this, SLOT( visibilityChanged(bool) ) ); // more signals for modify LUT // vector of widget so we can remove it from layout efficiently m_ListDoppler.push_back(checkBox1); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget:: VisibilityListDoppler(const bool& iVisibility) { QList::iterator it = m_ListDoppler.begin(); while(it != m_ListDoppler.end()) { (*it)->setVisible(iVisibility); ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget:: setChannelName(QString iChannelName) { this->channelName->setText(iChannelName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNavigationDockWidget:: DeleteDopplerWidgets() { qDeleteAll(m_ListDoppler.begin(), m_ListDoppler.end()); m_ListDoppler.clear(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoNavigationDockWidget:: GetFirstVisibleChannel() { int index = 0; QList::iterator it2 = m_ListCheckBoxes.begin(); while( it2 != m_ListCheckBoxes.end() ) { if((*it2)->isChecked()) { return index; } ++index; ++it2; } return -1; } GoFigure2-v0.9.0/Code/GUI/lib/DBManager/0000755000175000017500000000000011667757442017220 5ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBContourManager.h0000755000175000017500000002035311667757442023140 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBContourManager_h #define __QGoDBContourManager_h #include "QGoTableWidget.h" #include "GoDBCollectionOfTraces.h" #include "GoDBTWContainerForContourMesh.h" #include "QGoDBTraceManager.h" #include "ContourContainer.h" #include "QGoGUILibConfigure.h" /** \class QGoDBContourManager \brief This class manages the database queries, the table widget and the data from the database in the Container for visu for the contours \ingroup DB, GUI */ class QGOGUILIB_EXPORT QGoDBContourManager:public QGoDBTraceManager { Q_OBJECT public: QGoDBContourManager(int iImgSessionID, QWidget *iparent); ~QGoDBContourManager(); typedef std::pair< std::string, QColor > NameWithColorData; /** \brief set the m_ContourContainerInfoForVisu to the iContainerForVisu \param[in] iContainerForVisu common container for the visu and database */ void SetContoursInfoContainerForVisu(ContourContainer *iContainerForVisu); unsigned int SaveNewContourFromVisu(int iTCoord, unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, unsigned int iMeshID); /** \brief update the bounding box and the points for the checked contour and return the contourid */ unsigned int SaveReeditedContourFromVisu(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iTCoord, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iContourNodes, vtkMySQLDatabase *iDatabaseConnector); /** \brief get all the data from the database to load all the contours for the imagingsession into the table widget and the container for the visu \param[in] iDatabaseConnector connection to the database */ void DisplayInfoAndLoadVisuContainerForAllContours(vtkMySQLDatabase *iDatabaseConnector); void DisplayInfoAndLoadVisuContainerForAllContoursForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); void AddInfoInTWAndVisuContainerForContoursForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); void RemoveTracesFromTWAndContainerForVisuForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); /** \brief is called when the user choses the change color action in the context menu,emit signals to get the databaseconnection and the selectedColor and updates directly the checked traces with the new color in the database, the TW and the visu container as contour has no collectionof */ void ChangeTraceColor(); /** \brief virtual pure method in QGoDBTraceManager */ virtual std::list< unsigned int > UpdateTheTracesColor(vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual void UpdateTWAndContainerForImportedTraces(const std::vector< int > & iVectorImportedTraces, vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual void DeleteCheckedTraces(vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual std::list< unsigned int > GetListHighlightedIDs(); void CleanTWAndContainerForGivenTimePoint(vtkMySQLDatabase *iDatabaseConnector, const std::list& iTimePoints); signals: /** \brief signal emitted when the user clicks on "Reedit contour" in the context menu */ void TraceToReEdit(unsigned int); protected: GoDBTWContainerForContourMesh *m_TWContainer; ContourContainer *m_ContourContainerInfoForVisu; //virtual pure method in QGoDBTraceManager virtual void SetCollectionsTraceNames(); virtual void AddActionsContextMenu(QMenu *iMenu); /** \brief add the action "generate a mesh from contours" in the context menu */ void AddActionForCreateNewCollectionFromCheckedTraces(); virtual void DisplayInfoForLastCreatedTrace(vtkMySQLDatabase *iDatabaseConnector); virtual void DisplayInfoForExistingTrace(vtkMySQLDatabase *iDatabaseConnector, int iTraceID); //virtual pure method in QGoDBTraceManager virtual void DisplayInfoForAllTraces(vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual void DisplayInfoForTracesForSpecificTPs(vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); void AddInfoForContoursInTWForSpecificTPs(vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); //virtual pure method in QGoDBTraceManager virtual void GetTracesInfoFromDBAndModifyContainerForVisu( vtkMySQLDatabase* iDatabaseConnector, std::list iListTraceIDs = std::list< unsigned int >()); //QGoDBTraceManager method virtual void AddToSelectedCollection(); //QGoDBTraceManager method virtual void CreateCorrespondingCollection(); /** \brief check that all the highlighted contours belong to the current timepoint, if not display a message to the user and return false \return true if all the highlighted contours are from the current timepoint */ bool AreCheckedContoursFromCurrentTimepoint(); protected slots: /** \brief emit TraceToReEdit if one and only one contour is checked in the TW */ void ReEditTrace(); //virtual pure method in QGoDBTraceManager virtual void UpdateHighlightedElementsInVisuContainer(int iTraceID); //virtual pure method in QGoDBTraceManager virtual void UpdateVisibleElementsInVisuContainer(int iTraceID); //virtual pure method in QGoDBTraceManager virtual void SetColorCoding(bool IsChecked); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBTraceManager.h0000755000175000017500000011334211667757442022546 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBTraceManager_h #define __QGoDBTraceManager_h #include #include #include #include "QGoTableWidget.h" #include "GoDBCollectionOfTraces.h" #include "GoDBTableWidgetContainer.h" #include "QGoGUILibConfigure.h" #include "ContourMeshContainer.h" #include "QGoColorCodingDialog.h" #include "vtkLookupTable.h" #include "vtkLookupTableManager.h" /** \class QGoDBTraceManager \brief Abstract class inherited by QGoDBContourManager,Mesh,Track,Lineage \ingroup DB GUI */ class QGOGUILIB_EXPORT QGoDBTraceManager:public QObject { Q_OBJECT public: explicit QGoDBTraceManager( QObject* iParent = NULL ); virtual ~QGoDBTraceManager(); typedef GoDBTableWidgetContainer::TWContainerType TWContainerType; typedef std::pair< std::string, QColor > NameWithColorData; typedef std::pair< unsigned int, QColor > IDWithColorData; /** \brief get the m_Table \return a QGoTableWidget */ QGoTableWidget * GetTableWidget(); /** \brief set the m_DatabaseConnection to iDatabaseConnector */ void SetDatabaseConnection(vtkMySQLDatabase *iDatabaseConnector); /** \brief return the distinct traces with their color for the imagingsession, for all timepoints if the timepoint is set to the default one or for the corresponding timepoint if not \param[in] iDatabaseConnector connection to the database \param[in] ioIDToSelect ID to be selected in the combobox \return a list of the tracesIDs with their corresponding QColor */ virtual std::list< NameWithColorData > GetAllTraceIDsWithColor( vtkMySQLDatabase *iDatabaseConnector, std::string & ioIDToSelect); /** \brief delete the corresponding traces in the table widget and in the container for visu \param[in] iTraceIDs list of the IDs for the traces to be deleted */ void UpdateTWAndContainerForDeletedTraces( const std::list< unsigned int > & iTraceIDs); /** \brief get the data needed from the database for the imported traces,display them in new inserted rows of the m_Table and update the container for the visu. \param[in] iVectorImportedTraces IDs of the imported traces \param[in] iDatabaseConnector connection to the database */ virtual void UpdateTWAndContainerForImportedTraces( const std::vector< int > & iVectorImportedTraces, vtkMySQLDatabase *iDatabaseConnector) = 0; /** \brief \return the list of traceIDs that have highlighted set to true in the ContainerForVisu. */ virtual std::list< unsigned int > GetListHighlightedIDs()= 0; /** \brief virtual pure. update the color of the checked traces in the database, the visu container and the TW and return the collectionOf IDs. (i.e traces that belongs to these traces as collection: contourIDs belonging to these meshes if the trace is a mesh) \param[in] iDatabaseConnector connection to the database \return a list of the tracesIDs, part of the collection represented by the checked traces */ virtual std::list< unsigned int > UpdateTheTracesColor( vtkMySQLDatabase *iDatabaseConnector) = 0; /** \brief delete the checked traces from the database, the TW and the container for visu \param[in] iDatabaseConnector connection to the database */ virtual void DeleteCheckedTraces(vtkMySQLDatabase *iDatabaseConnector) = 0; /** \brief update the collectionID of the tracesIDs in the list with the iCollectionID in the database and the TW \param[in] iDatabaseConnector connection to the database \param[in] iListTracesIDs list of the tracesIDs that the collectionID need to be changed \param[in] iCollectionID collectionID that needs to be changed for the traces */ void UpdateCollectionID(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs, int iCollectionID); /** \brief update in the database the bounding boxes corresponding to the TracesIDs and update the corresponding rows in the TW if the bool is set to true. \param[in] iDatabaseConnector connection to the database \param[in] iListTracesIDs list of the tracesIDs with a bounding box to update \param[in] UpdateTW display the updates in the TW */ virtual void UpdateBoundingBoxes(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs, bool UpdateTW = true); /** \brief return the list of collection IDs distinct and different from zero corresponding to the tracesIDs \param[in] iDatabaseConnector connection to the database \param[in] iListTracesIDs list of the tracesIDs from which the collectionID is needed \return a list of the collectionIDs distinct and different from zero found in the database for these tracesIDs */ std::list< unsigned int > GetListCollectionIDs( vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs); /** \brief get the collectionOf IDs for the TracesIDs found in iListTraces \param[in] iDatabaseConnector connection to the database \param[in] iListTraces list of the tracesIDs from which the collectionOf IDs are needed \return a list of the corresponding CollectionOf IDs (exp: return a list of ContourIDs belonging to the meshesIDs listed in iListTraces) */ std::list< unsigned int > GetListTracesIDsFromThisCollectionOf( vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTraces); /** \brief get the list of tracesIDs belonging to the collection listed in iListCollectionIDs \param[in] iDatabaseConnector connection to the database \param[in] iListCollectionIDs list of the collection for which the traces are needed \return list of the traces belonging to these collections */ std::list< unsigned int > GetListTracesIDsBelongingToCollectionIDs( vtkMySQLDatabase *iDatabaseConnector, const std::list& iListCollectionIDs); /** \brief get the data from the database corresponding to the iListTraces and display them in the Table Widget \param[in] iDatabaseConnector connection to the database \param[in] iListTraces list of the TraceIDs the rows in the TW need to be updated */ void DisplayInfoForExistingTraces(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int >& iListTraces); /** \brief get the last saved traces in the database \param[in] iDatabaseConnector connection to the database \param[in] iNumberOfTracesIDs number of the last tracesIDs required \return a list of the IDs */ std::list< unsigned int > GetLastCreatedTracesIDs( vtkMySQLDatabase *iDatabaseConnector, int iNumberOfTracesIDs); /** \brief set the pointer to the selected collection data \param[in] iCollectionData pointer to the selected collection data */ void SetSelectedCollection (NameWithColorData* iCollectionData); /** \brief set the pointer to the current timepoint \param[in] iTimePoint pointer to the current timepoint */ void SetCurrentTimePoint(int* iTimePoint); /** \brief set the pointer to the current selected color \param[in] iColorData pointer to the current selected color */ void SetSelectedColor(NameWithColorData* iColorData); /** \todo Lydie: create a class for ContourMesh*/ /** \brief if m_IsShowOnlyCurrentTimePointOn is true, call the method to show only the rows for the current timepoint, useful when the timepoint changes */ void CheckShowRows(); void UpdateLastSelectedOneAsCollection(); signals: /** \brief signal emitted when the user click on the action "change color" from the context menu as it can impact different TraceManagers */ void TraceColorToChange(); /** \brief signal emitted when the user click on the action "DeleteTraces" from the context menu as it can impact different TraceManagers */ void CheckedTracesToDelete(); /** \brief signal emitted when the user clicks on "go to the trace" in the context menu and return the coordinates for the center of the bounding box of the trace */ void NeedToGoToTheLocation(int XCoord, int YCoord, int ZCoord, int TCoord); /** \brief signal emitted when the user clicks on "create a new collection from checked traces" in the context menu and return the list of checked tracesIDs */ void NewCollectionFromCheckedTraces(std::list< unsigned int > ); void CheckedTracesToAddToSelectedCollection(std::list< unsigned int > ); void NeedToGetDatabaseConnection(); void DBConnectionNotNeededAnymore(); /** \brief signal emitted when a new trace is created that need to be added in the trace settings widget. (when a new mesh is created while contour table is displayed for example) */ void AddNewTraceIDInTS(std::pair iTraceToAddData); void PrintMessage(QString iMessage, int iTimeOut = 0); protected: std::string m_TraceName; std::string m_TraceNameID; std::string m_CollectionName; std::string m_CollectionNameID; std::string m_CollectionOf; std::string m_CollectionOfID; NameWithColorData* m_SelectedCollectionData; NameWithColorData* m_SelectedColorData; int* m_CurrentTimePoint; std::string m_LastSelectedTraceAsCollection; int m_ImgSessionID; QGoTableWidget * m_Table; GoDBCollectionOfTraces *m_CollectionOfTraces; vtkMySQLDatabase * m_DatabaseConnector; bool m_IsColorCodingOn; bool m_IsShowOnlyCurrentTimePointOn; QMenu* m_CheckedTracesMenu; /** \brief Virtual pure method: get the data needed from the database and display them in the m_Table for all traces corresponding to the imagingsession \param[in] iDatabaseConnector connection to the database */ virtual void DisplayInfoForAllTraces(vtkMySQLDatabase *iDatabaseConnector) = 0; virtual void DisplayInfoForTracesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list& iListTPs) = 0; /** \brief Virtual pure method: get the data needed from the database for the last created trace and display them in a new inserted row of the m_Table. \param[in] iDatabaseConnector connection to the database */ virtual void DisplayInfoForLastCreatedTrace(vtkMySQLDatabase *iDatabaseConnector) = 0; /** \brief Virtual pure method: get the data needed from the database for the existing trace with iTraceID and update the corresponding row in the m_Table. \param[in] iDatabaseConnector connection to the database \param[in] iTraceID ID of the trace */ virtual void DisplayInfoForExistingTrace(vtkMySQLDatabase *iDatabaseConnector, int iTraceID) = 0; /** \brief transform the iName into iNameID \param[in] iName \return iNameID */ std::string GetTheNameIDFromName(std::string iName); /** \brief set the variables class members \param[in] iImgSessionID to set the m_ImgSessionID \param[in] iParent parent for the m_Table */ void SetInfo(unsigned int iImgSessionID, QWidget *iParent); /** \brief virtual pure method: set the std::string class members */ virtual void SetCollectionsTraceNames() = 0; /** \brief get the ID for the last created trace in the database \param[in] iDatabaseConnector connection to the database \return the ID corresponding to the trace */ int GetLastCreatedTraceID(vtkMySQLDatabase *iDatabaseConnector); /** \brief return a double rgba[4] from a QColor \param[in] iColor QColor \return a double* rgba[4] */ double * GetVectorFromQColor(QColor iColor); /** \brief create a GoDBCoordinateRow and set its fields X,Y,Z,Tcoord \param[in] iXCoord \param[in] iYCoord \param[in] iZCoord \param[in] iTCoord \return a new created GoDBCooordinateRow with coordinates */ GoDBCoordinateRow GetCoordinateFromInt(int iXCoord, int iYCoord, int iZCoord, int iTCoord); template< typename C, typename S > void GetTracesInfoFromDBAndModifyContainerForVisu( vtkMySQLDatabase* iDatabaseConnector, std::vector iVectIDs, C *iContainerForVisu) { std::list list_of_traces = GetTracesInfoFromDBForVisuContainer( list_of_traces, iDatabaseConnector, this->m_TraceName, this->m_CollectionName, this->m_ImgSessionID, -1, iVectIDs); typename std::list::iterator it = list_of_traces.begin(); while ( it != list_of_traces.end() ) { iContainerForVisu->Insert(*it); ++it; } } /** \brief fill the TWContainer with all the data needed from the database and display them into the m_Table \param[in] iTWContainer contains all the description of its columns to get the data from the database and to display them in the m_Table but has no value yet \param[in] iDatabaseConnector connection to the database \param[in] iState if false the visible column will be unchecked in the TW \param[in] iIndexShowColumn index of the show column in the TW Container(to be set up for mesh and contour) \tparam T this method takes only children of GoDBTableWidgetContainer as type */ template< typename T > void DisplayInfoForAllTracesTemplate(T *iTWContainer, vtkMySQLDatabase *iDatabaseConnector, Qt::CheckState iState, int iIndexShowColumn = 0) { TWContainerType RowContainer = iTWContainer->GetContainerLoadedWithAllFromDB(iDatabaseConnector); std::list< std::pair< std::string, std::string > > ColumnNamesAndToolTips = iTWContainer->GetListColumnsNamesAndToolTipsForTableWidget(); this->m_Table->DisplayInitialContent( RowContainer, iTWContainer->GetIndexForGroupColor(this->m_TraceName), iTWContainer->GetIndexForGroupColor(this->m_CollectionName), this->m_TraceName, this->m_CollectionName, ColumnNamesAndToolTips, iState, iIndexShowColumn); } template< typename T > void DisplayInfoForTracesForSpecificTPsTemplate(T *iTWContainer, vtkMySQLDatabase *iDatabaseConnector, Qt::CheckState iState, const std::list & iListTPs, int iIndexShowColumn = 0) { //load the container with the traces infos for the TW for the TimePoints contained //in iListTPs: TWContainerType RowContainer = iTWContainer->GetContainerLoadedWithAllFromDB(iDatabaseConnector, iListTPs); std::list< std::pair< std::string, std::string > > ColumnNamesAndToolTips = iTWContainer->GetListColumnsNamesAndToolTipsForTableWidget(); //to load the column names and display the content of the TWContainer: this->m_Table->DisplayInitialContent( RowContainer, iTWContainer->GetIndexForGroupColor(this->m_TraceName), iTWContainer->GetIndexForGroupColor(this->m_CollectionName), this->m_TraceName, this->m_CollectionName, ColumnNamesAndToolTips, iState, iIndexShowColumn); } /** \brief fill the TWContainer with the data needed from the database for the last created trace and insert a new row into the m_Table to display them \param[in] iTWContainer contains all the description of its columns to get the data from the database and to display them in the m_Table but has no value yet \param[in] iDatabaseConnector connection to the database \tparam T this method takes only children of GoDBTableWidgetContainer as type */ template< typename T > void DisplayInfoForLastCreatedTraceTemplate(T *iTWContainer, vtkMySQLDatabase *iDatabaseConnector) { int TraceID = this->GetLastCreatedTraceID(iDatabaseConnector); TWContainerType RowContainer = iTWContainer->GetContainerForOneSpecificTrace(iDatabaseConnector, TraceID); // insert is buggy on sorted table // 1- unsort (if sorted) // 2- insert // 3- sort (if sorted) bool sorting = this->m_Table->isSortingEnabled(); if(sorting) { this->m_Table->setSortingEnabled(false); } this->m_Table->InsertOnlyOneNewRow(RowContainer, iTWContainer->GetIndexForGroupColor(this->m_TraceName), iTWContainer->GetIndexForGroupColor(this->m_CollectionName), this->m_TraceName, this->m_CollectionName); if(sorting) { this->m_Table->setSortingEnabled(true); } } /** \brief fill the TWContainer with the data needed from the database for the trace with the iTraceID and update the corresponding row into the m_Table \param[in] iTWContainer contains all the description of its columns to get the data from the database and to display them in the m_Table but has no value yet \param[in] iDatabaseConnector connection to the database \param[in] iTraceID ID for the trace the info will be displayed \tparam T this method takes only children of GoDBTableWidgetContainer as type */ template< typename T > void DisplayInfoForExistingTraceTemplate(T *iTWContainer, vtkMySQLDatabase *iDatabaseConnector, int iTraceID) { if (iTraceID != 0) { TWContainerType RowContainer = iTWContainer->GetContainerForOneSpecificTrace(iDatabaseConnector, iTraceID); this->m_Table->UpdateRow(RowContainer, iTWContainer->GetIndexForGroupColor(this->m_TraceName), iTWContainer->GetIndexForGroupColor(this->m_CollectionName), this->m_TraceName, this->m_CollectionName, iTraceID); } } /** \brief create the trace row with the related data provided by the visu, iTCoordMax is equal to 0 as for contour and mesh, it is the same as TCoord \param[in] iXCoordMin X coord min of the bounding box \param[in] iYCoordMin Y coord min of the bounding box \param[in] iZCoordMin Z coord min of the bounding box \param[in] iTCoord T coord min of the bounding box and max if iTCoordMax = 0 \param[in] iXCoordMax X coord max of the bounding box \param[in] iYCoordMax Y coord max of the bounding box \param[in] iZCoordMax Z coord max of the bounding box \param[in] iTraceNodes polydata from which the points will be extracted \param[in] iColor color of the trace \param[in] iDatabaseConnector connection to the database \param[in,out] iTrace GoDBTraceRow with the fields to be set \param[in] iCollectionID collection ID of the trace \param[in] iTCoordMax T coord max of the bounding box \tparam T */ template< typename T > unsigned int CreateNewTraceInDBFromVisu( unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iTCoord, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iTraceNodes, NameWithColorData iColor, vtkMySQLDatabase *iDatabaseConnector, T & iTrace, unsigned int iCollectionID, unsigned int iTCoordMax = 0) { this->SetTraceBoundingBoxAndPoints< T >(iXCoordMin, iYCoordMin, iZCoordMin, iTCoord, iXCoordMax, iYCoordMax, iZCoordMax, iTraceNodes, iDatabaseConnector, iTrace, iTCoordMax); return this->m_CollectionOfTraces->CreateNewTraceInDB< T >(iTrace, iDatabaseConnector, iColor, iCollectionID); } template< typename T > void SetTraceBoundingBoxAndPoints(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iTCoord, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, T & iTrace, unsigned int iTCoordMax = 0) { GoDBCoordinateRow coord_min = this->GetCoordinateFromInt(iXCoordMin, iYCoordMin, iZCoordMin, iTCoord); unsigned int TCoord; if ( iTCoordMax == 0 ) { TCoord = iTCoord; } else { TCoord = iTCoordMax; } GoDBCoordinateRow coord_max = this->GetCoordinateFromInt(iXCoordMax, iYCoordMax, iZCoordMax, TCoord); iTrace.SetTheDataFromTheVisu(iDatabaseConnector, iTraceNodes, coord_min, coord_max); } /** \brief get all the data from the database to load all the traces for the imagingsession into the table widget and the container for the visu \param[in] iTWContainer contains all the description of its columns to get the data from the database and to display them in the m_Table but has no value yet \param[in] iDatabaseConnector connection to the database \tparam T only children of GoDBTableWidgetContainer as type T */ template< typename T > void DisplayInfoAndLoadVisuContainerWithAllTraces(T *iTWContainer, vtkMySQLDatabase *iDatabaseConnector) { this->DisplayInfoForAllTraces(iDatabaseConnector); /** \todo Lydie: modify the TWContainer to return a list of unsigned int*/ std::vector< int > VectorIDs = iTWContainer->GetAllTraceIDsInContainer(); std::list ListIDs(VectorIDs.begin(), VectorIDs.end()); this->GetTracesInfoFromDBAndModifyContainerForVisu(iDatabaseConnector,ListIDs); } template< typename C> void DisplayInfoAndLoadVisuContainerWithAllTracesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, C* iContainerForVisu, const std::list & iListTPs) { this->DisplayInfoForTracesForSpecificTPs( iDatabaseConnector, iListTPs); std::list ListIDs = this->m_CollectionOfTraces->GetTraceIDsBelongingToListTimePoints( iDatabaseConnector, iListTPs); if(ListIDs.size() > 0) { this->GetTracesInfoFromDBAndModifyContainerForVisu(iDatabaseConnector,ListIDs); } } template< typename C> void RemoveTracesFromTWAndContainerForVisuForSpecificTPsTemplate( vtkMySQLDatabase *iDatabaseConnector, C* iContainerForVisu, const std::list & iListTPs) { std::list ListIDs = this->m_CollectionOfTraces->GetTraceIDsBelongingToListTimePoints( iDatabaseConnector, iListTPs); iContainerForVisu->Clear(ListIDs); QStringList StrgListTPs; std::list::const_iterator iter = iListTPs.begin(); while (iter != iListTPs.end() ) { QString temp; temp.setNum(static_cast(*iter)); StrgListTPs << temp; ++iter; } //erase in the table widget: this->m_Table->DeleteRowsWithSpecificTimePoints(StrgListTPs); } /** \brief update for the imported traces the table widget and the database info of the container for visu. \param[in] iTWContainer contains all the description of its columns to get the data from the database and to display them in the m_Table but has no value yet \param[in] iVectorTraceIDs vector of the imported TracesIDs \param[in] iDatabaseConnector connection to the database \tparam T this method takes only children of GoDBTableWidgetContainer */ template< typename T > void UpdateTWAndContainerWithImportedTracesTemplate(T *iTWContainer, const std::vector< int > & iVectorTraceIDs, vtkMySQLDatabase *iDatabaseConnector) { this->m_Table->setSortingEnabled(false); //insert the info from the database for the traces into the container //for visu: /** \todo Lydie modify to have as argument a list of unsigned int*/ std::list< unsigned int > ListTraceIDs(iVectorTraceIDs.begin(), iVectorTraceIDs.end() ); this->GetTracesInfoFromDBAndModifyContainerForVisu( iDatabaseConnector, ListTraceIDs); //insert the new rows into the TW: std::list< unsigned int >::iterator iter = ListTraceIDs.begin(); while ( iter != ListTraceIDs.end() ) { TWContainerType RowContainer = iTWContainer->GetContainerForOneSpecificTrace(iDatabaseConnector, *iter); this->m_Table->InsertOnlyOneNewRow(RowContainer, iTWContainer->GetIndexForGroupColor(this->m_TraceName), iTWContainer->GetIndexForGroupColor(this->m_CollectionName), this->m_TraceName, this->m_CollectionName); ++iter; } this->m_Table->setSortingEnabled(true); this->m_Table->resizeColumnsToContents(); } /** \brief update the visu container, the database and the TW with the user selected color for the highlighted traces \param[in] iDatabaseConnector connection to the database \param[in] iContainerInfoForVisu info needed for the visu \return a list of the tracesIDs, part of the collection represented by the checked traces \tparam T children of GoDBTraceRow \tparam C ContourMeshContainer or TrackContainer */ template< typename T,typename C > std::list< unsigned int > UpdateTheTracesColorTemplate( vtkMySQLDatabase *iDatabaseConnector, C *iContainerInfoForVisu) { std::list< unsigned int > oListOfCollectionOfIDs = std::list< unsigned int >(); std::list< unsigned int > ListTracesIDs; ListTracesIDs = iContainerInfoForVisu-> UpdateAllHighlightedElementsWithGivenColor(this->m_SelectedColorData->second); if ( ListTracesIDs.empty() ) { QMessageBox msgBox; msgBox.setText( tr("Please select at least one %1 for the color to be changed") .arg( this->m_TraceName.c_str() ) ); msgBox.exec(); } else { std::list< unsigned int >::iterator iter = ListTracesIDs.begin(); while ( iter != ListTracesIDs.end() ) { this->m_CollectionOfTraces->ChangeColorForTrace< T >(*iter, *this->m_SelectedColorData, iDatabaseConnector); this->DisplayInfoForExistingTrace(iDatabaseConnector, *iter); ++iter; } oListOfCollectionOfIDs = this->m_CollectionOfTraces-> GetListTracesIDsFromThisCollectionOf(iDatabaseConnector, ListTracesIDs); } return oListOfCollectionOfIDs; } /** \brief set the iMemberContainerInfoForVisu to the iContainerForVisu and create the connections SLOT/SIGNAL \param[in] iContainerForVisu common container for the visu and database \param[in] iMemberContainerForVisu m_TraceContainerInfoForVisu \tparam T ContourMeshContainer or TrackContainer */ template< typename T > void SetTracesInfoContainerForVisuTemplate(T *iContainerForVisu, T **iMemberContainerForVisu) { *iMemberContainerForVisu = iContainerForVisu; QObject::connect( *iMemberContainerForVisu, SIGNAL( TracePicked(uint, Qt::CheckState) ), this, SLOT( CheckTheTraceInTW(uint, Qt::CheckState) ) ); QObject::connect( *iMemberContainerForVisu, SIGNAL( TraceVisibilityChanged(uint, Qt::CheckState) ), this, SLOT ( ShowTheTraceInTW(uint, Qt::CheckState) ) ); QObject::connect( this->m_Table, SIGNAL( ModifyHighlightListTraces(QStringList,Qt::CheckState) ), *iMemberContainerForVisu, SLOT ( UpdateElementHighlightingWithGivenTraceIDs(QStringList, Qt::CheckState) ) ); QObject::connect( this->m_Table, SIGNAL( ModifyVisibilityListTraces(QStringList,Qt::CheckState) ), *iMemberContainerForVisu, SLOT ( UpdateElementVisibilityWithGivenTraceIDs(QStringList, Qt::CheckState) ) ); } /** \brief delete the traces from the database, the TW and the container for visu \param[in] iDatabaseConnector connection to the database \param[in] iContainerForVisu common container for the visu and database \param[in] iListTracesToDelete list of the tracesIDs to be deleted \param[in] DeleteHighlightedTraces if true, the traces to be deleted are the ones highlighted in the visu \tparam T ContourMeshContainer or TrackContainer */ // TODO Nico- useless bool, should test lenght of list instead...! template void DeleteTracesTemplate(vtkMySQLDatabase *iDatabaseConnector, T *iContainerForVisu, std::list iListTracesToDelete = std::list(), bool DeleteHighlightedTraces = true) { std::list< unsigned int > ListTracesIDsToDelete; if (DeleteHighlightedTraces) //case where the traces to be deleted are the ones highlighted in the visu { ListTracesIDsToDelete = iContainerForVisu->GetHighlightedElementsTraceID(); iContainerForVisu->DeleteAllHighlightedElements(); } else //case where specific traces need to be deleted, not the highlighted ones { ListTracesIDsToDelete = iListTracesToDelete; std::list::iterator iter = iListTracesToDelete.begin(); while( iter != iListTracesToDelete.end() ) { iContainerForVisu->DeleteElement(*iter); ++iter; } } this->m_CollectionOfTraces->DeleteTracesInDB( ListTracesIDsToDelete, iDatabaseConnector); this->m_Table->DeleteCheckedRows(this->m_TraceNameID, ListTracesIDsToDelete); } /** \brief get a map with the tracesIDs as keys and the values of the selected columns as values for all traces in the table widget and update the color of the traces in the visu \param[in] iContainerForVisu common container for the visu and database \param[in] IsChecked corresponds to the state of the checkable action \tparam ContourMeshContainer or TrackContainer */ template void SetColorCodingTemplate( T* iContainerForVisu, bool IsChecked) { std::string ColumnName = ""; std::map Values; m_IsColorCodingOn = IsChecked; if (IsChecked) { Values = this->m_Table->GetTraceIDAndColumnsValues( this->m_TraceNameID, ColumnName); vtkLookupTable* LUT = NULL; bool IsRandomIncluded = (ColumnName == this->m_TraceNameID) || (ColumnName == this->m_CollectionNameID); QGoColorCodingDialog::ColorWay UserColorway = QGoColorCodingDialog::GetColorWay( this->m_TraceName, &LUT, IsRandomIncluded, this->m_Table ); switch ( UserColorway ) { case QGoColorCodingDialog::Default: iContainerForVisu->SetColorCode( ColumnName,Values ); break; case QGoColorCodingDialog::Random: iContainerForVisu->SetRandomColor(ColumnName,Values ); break; case QGoColorCodingDialog::LUT: iContainerForVisu->SetColorCode( ColumnName,Values ); iContainerForVisu->SetLookupTableForColorCoding(LUT); break; default: case QGoColorCodingDialog::Nothing: m_IsColorCodingOn = !IsChecked; break; } } else { m_IsColorCodingOn = IsChecked; iContainerForVisu->SetColorCode( ColumnName, Values ); } } /** \brief get the info needed from the database to fill the container for visu \param[in] iDatabaseConnector connection to the database \param[in] iContainerForVisu common container for the visu and database \param[in] iListTraceIDs list of the IDs the info are needed */ template void GetTracesInfoFromDBAndModifyContainerForVisuTemplate( T* iContainerForVisu, vtkMySQLDatabase* iDatabaseConnector, const std::list & iListTraceIDs) { typedef typename T::MultiIndexContainerElementType Structure; std::list list_of_traces = this->m_CollectionOfTraces->GetListStructureFromDB( iDatabaseConnector, this->m_ImgSessionID, iListTraceIDs); typename std::list< Structure >::iterator it = list_of_traces.begin(); while ( it != list_of_traces.end() ) { iContainerForVisu->Insert(*it); ++it; } } virtual void AddActionsContextMenu(QMenu *iMenu); void AddGeneralActionsContextMenu(QMenu *iMenu); void AddSpecificActionsForContourMesh(QMenu *iMenu); virtual void AddActionForAddingCheckedTracesToCollection(); /** \brief get the info needed from the database to update the container for visu */ virtual void GetTracesInfoFromDBAndModifyContainerForVisu( vtkMySQLDatabase* iDatabaseConnector, std::list iListTraceIDs = std::list< unsigned int >())= 0; bool CheckThatThereAreTracesToDelete(const std::list & iListTracesIDToDelete); protected slots: //context menu: /** \brief create the context menu when the user clicks on the table widget \param[in] iPos position of the context menu event */ void CreateContextMenu(const QPoint & iPos); void CheckSelectedRows(); void UncheckSelectedRows(); void ShowSelectedRows(); void HideSelectedRows(); /** \brief is called when the user choses the change color action in the context menu, emit the signal TraceColorToChange as it impacts the collectionOf also */ virtual void ChangeTraceColor(); void DeleteTracesFromContextMenu(); /** \brief slot called when a trace has been picked from the visu, to update the TW "checked/unchecked" column correspondingly \param[in] iTraceID TraceID that has been picked \param[in] iState state to which the TW needs to be updated */ void CheckTheTraceInTW(unsigned int iTraceID, Qt::CheckState iState); /** \brief slot called when a trace has been shown/hidden from the visu, to update the TW "show/hide" column correspondingly \param[in] iTraceID TraceID that has been shown/hidden \param[in] iState state to which the TW needs to be updated */ void ShowTheTraceInTW(unsigned int iTraceID, Qt::CheckState iState); void GoToTheTrace(); /** \brief slot called when the user click on "create a collection from checked traces" in the context menu, emit the signal NewCollectionFromCheckedTraces as it impact the collection also */ virtual void CreateCorrespondingCollection(); virtual void AddToSelectedCollection(); /** \brief modify to the opposite one the highlighted property of the corresponding trace base on traceID in the container for visu \param[in] iTraceID ID of the trace for the property to be modified */ virtual void UpdateHighlightedElementsInVisuContainer(int iTraceID) = 0; /** \brief modify to the opposite one the Visible property of the corresponding trace base on traceID in the container for visu \param[in] iTraceID ID of the trace for the property to be modified */ virtual void UpdateVisibleElementsInVisuContainer(int iTraceID) = 0; /** \brief ColorCode the traces in the visualization base on a selected column in the table widget \param[in] IsChecked set to true if the action is checked, to false if not */ virtual void SetColorCoding(bool IsChecked)= 0; /** \brief Show only the rows in the table widget that have a timepoint equal to the current timepoint if IsChecked is true, show all the rows if false \param[in] IsChecked set to true if the action is checked, to false if not */ void ShowOnlyRowsForCurrentTimePoint(bool IsChecked); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBLineageManager.h0000644000175000017500000001643111667757442023052 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBLineageManager_h #define __QGoDBLineageManager_h #include "QGoTableWidget.h" #include "GoDBCollectionOfTraces.h" #include "GoDBTWContainerForLineage.h" #include "QGoDBTraceManager.h" #include "QGoGUILibConfigure.h" #include "LineageContainer.h" #include "TrackContainer.h" /** \class QGoDBLineageManager \brief This class manages the database queries, the table widget and the data from the database in the Container for visu for the lineages \ingroup DB, GUI */ class QGOGUILIB_EXPORT QGoDBLineageManager:public QGoDBTraceManager { Q_OBJECT public: QGoDBLineageManager(int iImgSessionID, QWidget *iparent); ~QGoDBLineageManager(); virtual void DisplayInfoForLastCreatedTrace(vtkMySQLDatabase *iDatabaseConnector); virtual void DisplayInfoForExistingTrace(vtkMySQLDatabase *iDatabaseConnector, int iTraceID); /** \brief set the m_LineageContainerInfoForVisu and the m_TrackContainerInfoForVisu to the iContainerForVisu and iTrackContainerInfoForvisu \param[in] iContainerForVisu common container for the visu and database \param[in] iTrackContainerInfoForvisu common container for tracks for the visu and database */ void SetLineagesInfoContainersForVisu( LineageContainer *iContainerForVisu, TrackContainer *iTrackContainerInfoForvisu); /** \brief get all the data from the database to load all the lineages for the imagingsession into the table widget and the container for the visu \param[in] iDatabaseConnector connection to the database */ void DisplayInfoAndLoadVisuContainerForAllLineages( vtkMySQLDatabase *iDatabaseConnector); /** \brief create a new lineage with IDRoot in the database, add it in the TW and in the visu container \param[in] iDatabaseConnector connection to the database \param[in] iTrackRoot ID of the track that is the root of the new lineage to create \return the ID of the new lineage just created */ unsigned int CreateNewLineageWithTrackRoot( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackRoot); //virtual pure method in QGoDBTraceManager std::list< unsigned int > UpdateTheTracesColor(vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual void UpdateTWAndContainerForImportedTraces( const std::vector< int > & iVectorImportedTraces, vtkMySQLDatabase *iDatabaseConnector); /** \brief delete the traces of the list from the database, the TW and the container for visu \param[in] iDatabaseConnector connection to the database \param[in] iListTraces list of the tracesIDs to be deleted */ void DeleteListTraces(vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTraces); //virtual pure method in QGoDBTraceManager virtual void DeleteCheckedTraces( vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual std::list< unsigned int > GetListHighlightedIDs(); virtual void UpdateBoundingBoxes(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs, bool UpdateTW = true); public slots: void UpdateElementHighlighting(unsigned int); /* * \brief Export all the lineages to vtkTree into the folder chosen by the user. * Those trees can be read with the lineageViewer. */ void ExportLineages(); protected: GoDBTWContainerForLineage *m_TWContainer; LineageContainer *m_LineageContainerInfoForVisu; TrackContainer *m_TrackContainerInfoForVisu; //virtual pure method in QGoDBTraceManager virtual void SetCollectionsTraceNames(); //virtual pure method in QGoDBTraceManager virtual void DisplayInfoForAllTraces(vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual void DisplayInfoForTracesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); //virtual pure method in QGoDBTraceManager virtual void GetTracesInfoFromDBAndModifyContainerForVisu( vtkMySQLDatabase* iDatabaseConnector, std::list iListTraceIDs = std::list< unsigned int >()); void InsertLineageInTW(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTraceID); /** \brief update the trackID root for the lineage with iTrackIDRoot \param[in] iDatabaseConnector connection to the database \param[in] iLineageID ID of the lineage the TrackIDRoot needs to be updated \param[in] iTrackIDRoot ID of the track to be the root of the lineage */ void UpdateTrackRootSelectedLineage(vtkMySQLDatabase* iDatabaseConnector, unsigned int iLineageID, unsigned int iTrackIDRoot); /* * \brief Update the scalars and colors for all the divisions of a lineage in the trackContainer for the visu */ void UpdateDivisionsInTrackContainer(unsigned int iLineageID); /** \brief delete the divisions of a lineage in the database and in the visu */ void DeleteDivisionsForLineages( vtkMySQLDatabase *iDatabaseConnector, const std::list & iLineageID); void DeleteADivision( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackFamilyID); protected slots: //virtual pure method in QGoDBTraceManager virtual void UpdateHighlightedElementsInVisuContainer(int iTraceID); //virtual pure method in QGoDBTraceManager virtual void UpdateVisibleElementsInVisuContainer(int iTraceID); //virtual pure method in QGoDBTraceManager virtual void SetColorCoding(bool IsChecked); virtual void DeleteTracesFromContextMenu(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBTrackManager.h0000755000175000017500000004215311667757442022555 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBTrackManager_h #define __QGoDBTrackManager_h #include "QGoTableWidget.h" #include "GoDBCollectionOfTraces.h" #include "GoDBTWContainerForTrack.h" #include "QGoDBTraceManager.h" #include "QGoGUILibConfigure.h" #include "TrackContainer.h" #include "GoDBTrackFamilyRow.h" class TrackStructure; /** \class QGoDBTrackManager \brief This class manages the database queries, the table widget and the data from the database in the Container for visu for the tracks \ingroup DB, GUI */ class QGOGUILIB_EXPORT QGoDBTrackManager:public QGoDBTraceManager { Q_OBJECT public: QGoDBTrackManager(int iImgSessionID, QWidget *iparent); ~QGoDBTrackManager(); virtual void DisplayInfoForLastCreatedTrace(vtkMySQLDatabase *iDatabaseConnector); virtual void DisplayInfoForExistingTrace(vtkMySQLDatabase *iDatabaseConnector, int iTraceID); /** \brief set the m_TrackContainerInfoForVisu to the iContainerForVisu \param[in] iContainerForVisu common container for the visu and database */ void SetTracksInfoContainerForVisu(TrackContainer *iContainerForVisu); /** \brief get all the data from the database to load all the tracks for the imagingsession into the table widget and the container for the visu \param[in] iDatabaseConnector connection to the database */ void DisplayInfoAndLoadVisuContainerForAllTracks( vtkMySQLDatabase *iDatabaseConnector); /** \brief get all the data from the database of the track family table and give the corresponding info to the track container for visu \param[in] iDatabaseConnector connection to the database */ void LoadInfoVisuContainerForTrackFamilies(vtkMySQLDatabase *iDatabaseConnector); /** \brief display in the TW the values extracted from iTrackAttributes * called when loading all tracks from database when opening an imagingsession \param[in] iTrackAttributes computed values for a track \param[in] iTrackID trackID of the track we want to display the values */ void DisplayOnlyCalculatedValuesForExistingTrack( GoFigureTrackAttributes *iTrackAttributes, unsigned int iTrackID); /** \brief create a new track with no mesh and no points in the database, add it in the TW and in the visu container \param[in] iDatabaseConnector connection to the database \return the ID of the new track just created */ unsigned int CreateNewTrackWithNoMesh( vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager std::list< unsigned int > UpdateTheTracesColor(vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual void UpdateTWAndContainerForImportedTraces( const std::vector< int > & iVectorImportedTraces, vtkMySQLDatabase *iDatabaseConnector); /** \brief delete the traces of the list from the database, the TW and the container for visu \param[in] iDatabaseConnector connection to the database \param[in] iListTraces list of the tracesIDs to be deleted */ void DeleteListTraces(vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTraces); //virtual pure method in QGoDBTraceManager virtual void DeleteCheckedTraces( vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual std::list< unsigned int > GetListHighlightedIDs(); /** \brief get the data from the TrackContainer corresponding to the user selected TrackID and put them in the current element of the track container */ void UpdateCurrentElementTrackContainer(); /** \brief update the points of the imported track in current_element with the info from the meshes and save them in the database */ void UpdatePointsOfCurrentElementForImportedTrack( std::map iMeshesInfo, vtkMySQLDatabase* iDatabaseConnector); //method in QGoDBTraceManager void UpdateBoundingBoxes( vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs); /** \brief check if the track belongs to a division and if it is possible to add the mesh without making the track overlapping the other tracks of the divisions, if so return a message to the user, if not, return the trackID of the divisions to be updated in the visu, if return empty message and empty list, the track doesn't belong to any division */ std::string CheckMeshCanBeAddedToTrack( vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID, unsigned int iMeshTimePoint, std::list &ioMotherTrackDivisionToUpdate); /** \brief update the track container for visu and consequently the divisions in the visu */ void UpdateDivisions(const std::list & iListMotherTrackIDs); /** \brief Modify volume of the given track ID */ void AddVolume(const unsigned int& iTrackID, const double& iVolume); /** \brief Modify volume of the given track ID */ void AddVolumes(const std::list< std::pair > & iVolumes); /** \brief Modify volume of the given track ID */ void RemoveVolumes(const std::list< std::pair > & iVolumes); /** \brief Modify volume of the given track ID */ void AddVolumes(const std::list< std::pair > & iVolumes, unsigned int iTrackID); /** \brief Modify volume of the given track ID */ void RemoveVolumes(const std::list< std::pair > & iVolumes, unsigned int iTrackID); std::vector GetTrackFamily(vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID); bool isMother(vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID); /** \brief check that the mothertrackID is not already a mother in another trackfamily, create the trackfamily if not and return the trackfamilyID \param[in] iDatabaseConnector connection to the database \param[in] iMotherTrackID \param[in] iDaughtersID \return ID of the new created trackfamily */ int CreateTrackFamily(vtkMySQLDatabase* iDatabaseConnector, unsigned int iMotherTrackID, const std::list & iDaughtersID); signals: void NeedMeshesInfoForImportedTrack(unsigned int iTrackID); void TrackToSplit(unsigned int iTrackID, std::list iListMeshIDs); void TrackIDToBeModifiedWithWidget(std::list iListTracksID); void MeshesToAddToTrack(std::list iListMeshes, unsigned int iTrackID); void CheckedTracksToAddToSelectedLineage(std::list iDaughtersID, unsigned int iLineageID, std::list iLineagesToDelete); void NewLineageToCreateFromTracks( std::list iCheckedTracksIDs, unsigned int iTrackIDRoot, std::list iLineagesToDelete); void NeedToGoToTheRealLocation(double, double, double, int); public slots: /** \brief slot called when the user chose "Delete the division for this tracks" */ void DeleteTheDivisions(std::list iDivisions = std::list()); /** \brief slot called when the user chose "Create a new division from checked tracks" */ void CreateCorrespondingTrackFamily(std::list iDivisions = std::list()); protected: GoDBTWContainerForTrack *m_TWContainer; TrackContainer *m_TrackContainerInfoForVisu; //virtual pure method in QGoDBTraceManager virtual void SetCollectionsTraceNames(); //virtual pure method in QGoDBTraceManager virtual void DisplayInfoForAllTraces(vtkMySQLDatabase *iDatabaseConnector); virtual void DisplayInfoForTracesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); //virtual pure method in QGoDBTraceManager virtual void GetTracesInfoFromDBAndModifyContainerForVisu( vtkMySQLDatabase* iDatabaseConnector, std::list iListTraceIDs = std::list< unsigned int >()); /** \brief get the center of bounding boxes from the database for the meshes belonging to the iTrackID, update the polydata in the container for visu and save it in the database \param[in] iDatabaseConnector connection to the database \param[in] iTrackID ID for the track the polydata needs to be recalculated */ void UpdateTrackPolydataForVisu(vtkMySQLDatabase *iDatabaseConnector,unsigned int iTrackID); //virtual in QGoDBTraceManager void AddActionsContextMenu(QMenu *iMenu); /** \brief create or update the track contained in the current element of the track container into the database, the table widget and insert the current element into the track container \param[in] iDatabaseConnector connection to the database */ void SaveTrackCurrentElement(vtkMySQLDatabase* iDatabaseConnector); void SaveTrackStructure(vtkMySQLDatabase* iDatabaseConnector, TrackStructure* iStructure); /** \brief check that the 2 tracks are not overloaping, if not, return the trackID to keep for the merge and the one to delete \param[in] iTrackIDs IDs of both tracks to check \param[in,out] ioTraceIDToKeep ID of the trace to keep after the merge \param[in,out] ioTraceIDToDelete ID of the trace to delete after the merge \param[in] iDatabaseConnector connection to the database \return false of the tracks are not overlapping, true if they are */ bool CheckOverlappingTracks(std::list iTrackIDs, unsigned int &ioTraceIDToKeep, unsigned int &ioTraceIDToDelete, vtkMySQLDatabase* iDatabaseConnector); /** \brief update the trackFamilyID in the database for the track corresponding to iDaughterID, if the trackfamilyID is 0, then the lineageID will be set to 0 also for this track \param[in] iDatabaseconnector connection to the database \param[in] iDaughterID ID of the track to be updated \param[in] iTrackFamilyID */ void UpdateTrackFamilyIDForDaughter(vtkMySQLDatabase* iDatabaseConnector, unsigned int iDaughterID,unsigned int iTrackFamilyID); /** \brief get the trackID with the lowest timepoint as the mother trackID, if several tracks have the lowest timepoint, return false. if other tracks from the list are overlapping the mother trackID, return false. \param[in] iListTracksID tracks ID to be identified \param[in,out] ioMotherID to be modified with the identified mother TrackID \param[in,out] ioDaughtersID to be modified with the identified daughters TrackID \return false if it was not possible to identify them based on the timepoints */ bool IdentifyMotherDaughtersToCreateTrackFamily( vtkMySQLDatabase* iDatabaseConnector, const std::list & iListTracksID, int &ioMotherID, std::list &ioDaughtersID); /** \brief get the lineage ids of the 2 daughters, then get all the tracks belonging to these 2 lineages and push them into the ioTrackIDsOfTheFamilies. \param[in] iDatabaseConnector connection to the database \param[in,out] ioTrackIDsOfTheFamilies IDs of all the tracks that will belong to the same lineage as the mother of the new created division \return the lineage ids of the 2 daughters */ std::list GetTrackIDFromDaughtersFamilies( vtkMySQLDatabase* iDatabaseConnector, std::list &ioTrackIDsOfTheFamilies); /** \brief set the trackfamilyid of the daughters to 0, delete the trackfamily from the database and from the visu and check if the daughters are mothers, if not fill the ioTrackIDsNoLineage, if yes, update the all family \ */ void DeleteOneDivision(GoDBTrackFamilyRow iDivision, vtkMySQLDatabase* iDatabaseConnector, std::list &ioTrackIDsNoLineage, std::list &ioMotherLineageToDelete); /** \brief build a message for the user to know which ones of the selected tracks have no division and emit a signal for it to be printed into the status bar \param[in] iTracksNoDivision IDs of the selected tracks that are not mothers */ void PrintAMessageForTracksWithNoDivision(std::list iTracksNoDivision); /** \brief set the trackfamilyID of the daughter to 0, get all the tracks with the same lineage and emit a signal to create a lineage from these tracks with the daughter as trackIDRoot if ioPartOfHigherLineage, the lineage of the division will not be deleted as higher tracks belong to it */ void CreateALineageWithFormerDaughterOfADeletedDivision( unsigned int iDaughterID, vtkMySQLDatabase* iDatabaseConnector, bool &ioPartOfHigherLineage); /** \brief return the trackfamilyID of the division the track is a mother of or 0 if the track is not a mother */ unsigned int IsTheTrackAMother(unsigned int iDaughterID, vtkMySQLDatabase* iDatabaseConnector); /** \brief return the trackfamilyID of the division the track is a daughter of or 0 if the track is not a daughter */ unsigned int IsTheTrackADaughter(unsigned int iTrackID, vtkMySQLDatabase* iDatabaseConnector); /** \brief check if the daughters are mothers, if yes, create a new lineage for them, if not, update the track familyID to 0 and fill the ioTrackIDsNoLineage with them, if ioPartOfHigherLineage is false, delete the lineage after creating a new one for the daughter family if the daughter is a mother and set the ioPartOfHigherLineage to true */ void UpdateFormerDaughtersOfADeletedDivision( std::list iDaughtersID, std::list &ioTrackIDsNoLineage, bool &ioPartOfHigherLineage); /** \brief get the division IDs the track belongs to as a mother or as a daughter */ std::list GetDivisionIDsTheTrackBelongsTo( vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID ); /** \brief check that the iTimePoint is < to the mintimepoint of the daughter from the division where trackID is a mother */ unsigned int CheckBoundingBoxDivisionAsAMother(vtkMySQLDatabase* iDatabaseConnector, unsigned int iTimePoint, unsigned int iTrackFamilyID ); /** \brief check that the iTimePoint is > to the maxtimepoint of the mother from the division where trackID is a daughter */ unsigned int CheckBoundingBoxDivisionAsADaughter(vtkMySQLDatabase* iDatabaseConnector, unsigned int iTimePoint, unsigned int iTrackFamilyID ); protected slots: //virtual pure method in QGoDBTraceManager virtual void UpdateHighlightedElementsInVisuContainer(int iTraceID); //virtual pure method in QGoDBTraceManager virtual void UpdateVisibleElementsInVisuContainer(int iTraceID); //virtual pure method in QGoDBTraceManager virtual void SetColorCoding(bool IsChecked); /** \brief get the trackIDs checked in the TW that will be modified with the widget and emit a signal with them as info on meshes are needed. */ void SplitMergeTrackWithWidget(); /** \brief check that there is only one checked track in the TW and emit a signal with it as the checked mesh is needed also to split the track */ void TrackIDToEmit(); /** \brief check that only 2 tracks are checked in the TW, if not display a message to the user, check that the 2 tracks are not overlapping, if yes, display a message to the user, get the meshes of the track with the lowest timepoints, delete this track and send a signal for the list of meshes of the previous track to be reassigned to the track with the highest timepoints */ void MergeTracks(); void GoToTrackEnd(); void GoToTrackBegin(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBSubCellTypeManager.h0000644000175000017500000000507211667757442023700 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBSubCellTypeManager_h #define __QGoDBSubCellTypeManager_h #include "QGoDBNameDescEntityManager.h" #include "GoDBSubCellTypeRow.h" /** \class QGoDBSubCellTypeManager \brief the QGoDBSubCellTypeManager manages the interactions between the user and the database for the SubCellularType DBTable. \ingroup DB GUI */ class QGoDBSubCellTypeManager:public QGoDBNameDescEntityManager { Q_OBJECT public: /** \todo Lydie: make a class template for celltype/subcelltype */ explicit QGoDBSubCellTypeManager (QWidget *iParent = 0); ~QGoDBSubCellTypeManager() {} protected: GoDBSubCellTypeRow m_NewSubCellType; //mother class method virtual void SaveNewEntityInDB(); protected slots: //mother class method virtual void ValidateName(std::string iName, std::string iDescription); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBContourManager.cxx0000644000175000017500000004630511667757442023515 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBContourManager.h" #include "GoDBContourRow.h" #include #include #include #include #include "GoDBContourRow.h" QGoDBContourManager::QGoDBContourManager(int iImgSessionID, QWidget *iparent) : QGoDBTraceManager(), m_ContourContainerInfoForVisu(NULL) { this->SetInfo(iImgSessionID, iparent); this->m_TWContainer = new GoDBTWContainerForContourMesh(this->m_TraceName, this->m_CollectionName, iImgSessionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoDBContourManager::~QGoDBContourManager() { if ( this->m_TWContainer ) { delete this->m_TWContainer; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::SetContoursInfoContainerForVisu( ContourContainer *iContainerForVisu) { this->SetTracesInfoContainerForVisuTemplate< ContourContainer >( iContainerForVisu, &this->m_ContourContainerInfoForVisu); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::SetCollectionsTraceNames() { this->m_TraceName = "contour"; this->m_CollectionName = "mesh"; this->m_CollectionOf = "None"; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::DisplayInfoAndLoadVisuContainerForAllContours( vtkMySQLDatabase *iDatabaseConnector) { this->DisplayInfoAndLoadVisuContainerWithAllTraces< GoDBTWContainerForContourMesh > (this->m_TWContainer, iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::DisplayInfoAndLoadVisuContainerForAllContoursForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { this->DisplayInfoAndLoadVisuContainerWithAllTracesForSpecificTPs< ContourMeshContainer > (iDatabaseConnector, this->m_ContourContainerInfoForVisu, iListTPs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::AddInfoInTWAndVisuContainerForContoursForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { //this->AddInfoInTWAndContainerForVisuForSpecificTPs< ContourMeshContainer > // (iDatabaseConnector, this->m_ContourContainerInfoForVisu, iListTPs); this->AddInfoForContoursInTWForSpecificTPs(iDatabaseConnector, iListTPs); std::list ListIDs = this->m_CollectionOfTraces->GetTraceIDsBelongingToListTimePoints( iDatabaseConnector, iListTPs); std::list list_of_traces = this->m_CollectionOfTraces-> GetListStructureFromDB( iDatabaseConnector, this->m_ImgSessionID, ListIDs); /** \todo Nico: implement a method that get list_of_traces as argument and as this list of structure in the container for visu */ } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager:: AddInfoForContoursInTWForSpecificTPs(vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { //int IndexShowColumn = this->m_TWContainer->GetIndexShowColumn(); /*this->AddInfoForTracesInTWForSpecificTPsTemplate( this->m_TWContainer, iDatabaseConnector, Qt::Unchecked, IndexShowColumn );*/ //load the container with the traces infos for the TW for the TimePoints contained //in iListTPs: TWContainerType RowContainer = this->m_TWContainer->GetContainerLoadedWithAllFromDB(iDatabaseConnector, iListTPs); this->m_Table->InsertNewRows(RowContainer, this->m_TWContainer->GetIndexForGroupColor(this->m_TraceName), this->m_TWContainer->GetIndexForGroupColor(this->m_CollectionName), this->m_TraceName, this->m_CollectionName, Qt::Unchecked); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::DisplayInfoForAllTraces( vtkMySQLDatabase *iDatabaseConnector) { int IndexShowColumn = this->m_TWContainer->GetIndexShowColumn(); this->DisplayInfoForAllTracesTemplate< GoDBTWContainerForContourMesh >( this->m_TWContainer, iDatabaseConnector, Qt::Unchecked, IndexShowColumn); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::DisplayInfoForTracesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { int IndexShowColumn = this->m_TWContainer->GetIndexShowColumn(); this->DisplayInfoForTracesForSpecificTPsTemplate< GoDBTWContainerForContourMesh >( this->m_TWContainer, iDatabaseConnector, Qt::Unchecked, iListTPs, IndexShowColumn); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::DisplayInfoForLastCreatedTrace( vtkMySQLDatabase *iDatabaseConnector) { this->DisplayInfoForLastCreatedTraceTemplate< GoDBTWContainerForContourMesh >( this->m_TWContainer, iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::DisplayInfoForExistingTrace( vtkMySQLDatabase *iDatabaseConnector, int iTraceID) { this->DisplayInfoForExistingTraceTemplate< GoDBTWContainerForContourMesh >( this->m_TWContainer, iDatabaseConnector, iTraceID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager:: RemoveTracesFromTWAndContainerForVisuForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { this->RemoveTracesFromTWAndContainerForVisuForSpecificTPsTemplate< ContourMeshContainer > (iDatabaseConnector, this->m_ContourContainerInfoForVisu, iListTPs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::AddActionsContextMenu(QMenu *iMenu) { QGoDBTraceManager::AddActionsContextMenu(iMenu); this->AddSpecificActionsForContourMesh(iMenu); this->m_CheckedTracesMenu->addAction( tr("ReEdit the checked %1") .arg( this->m_TraceName.c_str() ), this, SLOT( ReEditTrace() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::AddActionForCreateNewCollectionFromCheckedTraces() { this->m_CheckedTracesMenu->addAction( tr("Generate a new mesh from checked contours"), this, SLOT( CreateCorrespondingCollection() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::ChangeTraceColor() { emit NeedToGetDatabaseConnection(); this->UpdateTheTracesColor(this->m_DatabaseConnector); emit DBConnectionNotNeededAnymore(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoDBContourManager::UpdateTheTracesColor( vtkMySQLDatabase *iDatabaseConnector) { return this->UpdateTheTracesColorTemplate< GoDBContourRow, ContourMeshContainer >( iDatabaseConnector, this->m_ContourContainerInfoForVisu); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBContourManager::SaveNewContourFromVisu( int iTCoord, unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, unsigned int iMeshID) { //if ( this->m_SelectedCollectionData->first != "Add a new mesh ..." //&& iMeshID != 0) if ( iMeshID != 0 ) { iMeshID = ss_atoi< unsigned int >(this->m_SelectedCollectionData->first); } GoDBContourRow NewContour(this->m_ImgSessionID); int NewContourID = this->CreateNewTraceInDBFromVisu< GoDBContourRow >( iXCoordMin, iYCoordMin, iZCoordMin, iTCoord,//*this->m_CurrentTimePoint, iXCoordMax, iYCoordMax, iZCoordMax, iTraceNodes, *this->m_SelectedColorData, iDatabaseConnector, NewContour, iMeshID); // pointer to double has to be deleted after usage... double *rgba = this->GetVectorFromQColor(this->m_SelectedColorData->second); this->m_ContourContainerInfoForVisu->UpdateCurrentElementFromDB( NewContourID, rgba); delete[] rgba; this->DisplayInfoForLastCreatedTrace(iDatabaseConnector); return NewContourID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBContourManager::SaveReeditedContourFromVisu(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iTCoord, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iContourNodes, vtkMySQLDatabase *iDatabaseConnector) { unsigned int TraceID = this->m_ContourContainerInfoForVisu->m_CurrentElement.TraceID; GoDBContourRow ReeditedContour; ReeditedContour.SetValuesForSpecificID(TraceID, iDatabaseConnector); this->SetTraceBoundingBoxAndPoints(iXCoordMin, iYCoordMin, iZCoordMin, iTCoord, iXCoordMax, iYCoordMax, iZCoordMax, iContourNodes, iDatabaseConnector, ReeditedContour); ReeditedContour.SaveInDB(iDatabaseConnector); this->DisplayInfoForExistingTrace(iDatabaseConnector, TraceID); return TraceID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::ReEditTrace() { std::list< unsigned int > ListCheckedTraces = this->m_ContourContainerInfoForVisu->GetHighlightedElementsTraceID(); if ( ListCheckedTraces.empty() ) { QMessageBox msgBox; msgBox.setText( tr("Please select the %1 you want to reedit") .arg( this->m_TraceName.c_str() ) ); msgBox.exec(); } else { if ( ListCheckedTraces.size() != 1 ) { QMessageBox msgBox; msgBox.setText( tr("Please select only one %1 to reedit") .arg( this->m_TraceName.c_str() ) ); msgBox.exec(); } else { emit TraceToReEdit( ListCheckedTraces.front() ); } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::UpdateTWAndContainerForImportedTraces( const std::vector< int > & iVectorImportedTraces, vtkMySQLDatabase *iDatabaseConnector) { this->UpdateTWAndContainerWithImportedTracesTemplate< GoDBTWContainerForContourMesh >( this->m_TWContainer, iVectorImportedTraces, iDatabaseConnector); //update the visualization and the data from visu in the container for visu: this->m_ContourContainerInfoForVisu-> UpdateVisualizationForGivenIDs< std::vector< int > >( iVectorImportedTraces); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::DeleteCheckedTraces(vtkMySQLDatabase *iDatabaseConnector) { this->DeleteTracesTemplate< ContourMeshContainer >(iDatabaseConnector, this->m_ContourContainerInfoForVisu); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoDBContourManager::GetListHighlightedIDs() { return this->m_ContourContainerInfoForVisu->GetHighlightedElementsTraceID(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::UpdateHighlightedElementsInVisuContainer( int iTraceID) { this->m_ContourContainerInfoForVisu-> UpdateElementHighlightingWithGivenTraceID(iTraceID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::UpdateVisibleElementsInVisuContainer(int iTraceID) { this->m_ContourContainerInfoForVisu-> UpdateElementVisibilityWithGivenTraceID(iTraceID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::GetTracesInfoFromDBAndModifyContainerForVisu( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs) { this->GetTracesInfoFromDBAndModifyContainerForVisuTemplate< ContourContainer >( this->m_ContourContainerInfoForVisu, iDatabaseConnector, iListTraceIDs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::SetColorCoding(bool IsChecked) { this->SetColorCodingTemplate< ContourMeshContainer >( this->m_ContourContainerInfoForVisu, IsChecked); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::AddToSelectedCollection() { if ( this->AreCheckedContoursFromCurrentTimepoint() ) { QGoDBTraceManager::AddToSelectedCollection(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager::CreateCorrespondingCollection() { if ( this->AreCheckedContoursFromCurrentTimepoint() ) { QGoDBTraceManager::CreateCorrespondingCollection(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoDBContourManager::AreCheckedContoursFromCurrentTimepoint() { std::list< unsigned int > ListCheckedContours = this->m_ContourContainerInfoForVisu->GetHighlightedElementsTraceID(); if ( !ListCheckedContours.empty() ) { emit NeedToGetDatabaseConnection(); std::list< unsigned int >::iterator iter = ListCheckedContours.begin(); while ( iter != ListCheckedContours.end() ) { unsigned int TimepointContour = this->m_CollectionOfTraces->GetBoundedBoxTimePoint(this->m_DatabaseConnector, *iter); if ( TimepointContour != static_cast< unsigned int >( *this->m_CurrentTimePoint ) ) { emit PrintMessage( tr( "To see only the contours from the current timepoint in the table, right click on the table and select 'Show only in the table the contours for the current timepoint' ") ); QMessageBox msgBox; msgBox.setText( tr("Please select only contours from the current timepoint: %1 !!") .arg(*this->m_CurrentTimePoint) ); msgBox.exec(); return false; } ++iter; } emit DBConnectionNotNeededAnymore(); } return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBContourManager:: CleanTWAndContainerForGivenTimePoint(vtkMySQLDatabase *iDatabaseConnector, const std::list& iTimePoints) { this->RemoveTracesFromTWAndContainerForVisuForSpecificTPsTemplate( iDatabaseConnector, this->m_ContourContainerInfoForVisu, iTimePoints); } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBSubCellTypeManager.cxx0000644000175000017500000000531211667757442024250 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBSubCellTypeManager.h" QGoDBSubCellTypeManager::QGoDBSubCellTypeManager (QWidget *iParent) : QGoDBNameDescEntityManager(iParent, "subcellulartype", 0) { } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void QGoDBSubCellTypeManager::SaveNewEntityInDB() { if ( !this->CheckEntityAlreadyExists< GoDBSubCellTypeRow >(this->m_NewSubCellType) ) { this->m_NewSubCellType.SaveInDB(this->m_DatabaseConnector); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void QGoDBSubCellTypeManager::ValidateName(std::string iName, std::string iDescription) { this->ValidateNameTemplate< GoDBSubCellTypeRow >(this->m_NewSubCellType, iName, iDescription); }GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBNameDescEntityManager.h0000755000175000017500000001721211667757442024363 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBNameDescEntityManager_h #define __QGoDBNameDescEntityManager_h #include #include #include "vtkMySQLDatabase.h" #include "QGoNameDescriptionInputDialog.h" /** \class QGoDBNameDescEntityManager \brief Abstract class : the QGoDBNameDescEntityManager manages the interactions between the user and the database (add a new one, delete)for a DBTable containing a name and a description.Has some Qt widgets and manages queries for this particular DBTable (i.e get list of existing ones). \ingroup DB GUI */ class QGoDBNameDescEntityManager: public QWidget { Q_OBJECT public: /** \param[in] iParent QWidget parent \param[in] iEntityName Name of the DBTable \param[in] iImgSessionID ID of the current imagingsession */ explicit QGoDBNameDescEntityManager (QWidget *iParent = 0, std::string iEntityName = "", int iImgSessionID = 0); ~QGoDBNameDescEntityManager(); typedef std::vector< std::pair< std::string, std::string > > NamesDescrContainerType; /** \brief execute the dialog asking the user to enter a name and a description, validates the name, set the m_DatabaseConnector, save the entity in the DB and return the name of the new entity \param[in] iDatabaseConnector connection to the database \return Name of the new entity, empty if the user canceled the adding */ std::string AddAnEntity(vtkMySQLDatabase *iDatabaseConnector); /** \brief return the list of all the existing entities stored in the database \param[in] iDatabaseConnector connection to the database \return a vector of all the names associated with their description */ NamesDescrContainerType GetListExistingEntities( vtkMySQLDatabase *iDatabaseConnector); /** \brief show the list of the existing entities so the user can choose the ones he wants to delete, then delete them from the database \param[in] iDatabaseConnector connection to the database \return true if the user chooses to delete an entity, false if he canceled the deleting */ virtual bool DeleteEntity(vtkMySQLDatabase *iDatabaseConnector); /** \brief return the name of the new entity added \return name of the new entity */ std::string GetNameNewEntity(); /** \brief get the ID of the entity based on the name \param[in] iDatabaseConnector connection to the database \param[in] iName name of the entity \return ID of the entity */ int GetTheEntityID(std::string iName, vtkMySQLDatabase *iDatabaseConnector); protected slots: /** \brief Pure Virtual method : check that the name doesn't already exists in the database, if so, make the m_NameDescDialog asks the user to choose another one, if no, close the m_NameDescDialog and call SaveNewEntityInDB() \param[in] iName name entered by the user \param[in] iDescription description entered by the user */ virtual void ValidateName( std::string iName, std::string iDescription) = 0; /** \brief Delete in the database the entities with the names contained in the vector \param[in] iVectorNamesEntitiesToDelete vector of the names for the entities to be deleted in the database */ void DeleteEntitiesFromList( std::vector< std::string > iVectorNamesEntitiesToDelete); protected: int m_ImgSessionID; std::string m_EntityName; QGoNameDescriptionInputDialog *m_NameDescDialog; vtkMySQLDatabase * m_DatabaseConnector; std::string m_NameNewEntity; /** \brief Pure Virtual method : save the new entity in the database, the m_DatabaseConnectorForNewEntity needs to be set before calling this method. Check that the entity doesn't already exists in the database, if so, give the user the name of the existing entity */ virtual void SaveNewEntityInDB() = 0; /** \brief return the names of all the entities stored in the database \param[in] iDatabaseConnector connection to the database \return a vector of the names */ std::vector< std::string > GetNameExistingEntities(vtkMySQLDatabase *iDatabaseConnector); /** \brief check if the entity already exists in the database, if yes, give the name of the existing entity to the user, if no, record the name iName as the name of the new entity \param[in] iNewEntity contains data to check if it already exists \return bool return true if it already exists, false if not \tparam T this method takes only children of GoDBNameDescRow as type */ template< typename T > bool CheckEntityAlreadyExists(T iNewEntity) { std::string Name = iNewEntity.GetMapValue("Name"); if ( iNewEntity.DoesThisEntityAlreadyExistsAndReturnName( this->m_DatabaseConnector, Name) != -1 ) { QMessageBox msgBox; msgBox.setText( tr("This %1 already exists, its name is: ' %2 ' ") .arg( this->m_EntityName.c_str() ) .arg( Name.c_str() ) ); msgBox.exec(); return true; } else { this->m_NameNewEntity = Name; return false; } } /** \brief check if the name already exists for this entity in the database, if yes, let the user know, if not, call SaveNewEntityInDB \tparam T this method takes only children of GoDBNameDescRow as type \param[in] iName name for the new entity entered by the user \param[in] iDescription description for the new entity entered by the user \param[in,out] ioNewEntity fields name and description modified by the method */ template< typename T > void ValidateNameTemplate(T & ioNewEntity, std::string iName, std::string iDescription) { ioNewEntity.SetField("Name", iName); ioNewEntity.SetField("Description", iDescription); if ( ioNewEntity.DoesThisNameAlreadyExists( this->m_DatabaseConnector) != -1 ) { this->m_NameDescDialog->NameAlreadyExists(); } else { this->m_NameDescDialog->accept(); this->SaveNewEntityInDB(); } } }; #endif GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBTraceManager.cxx0000644000175000017500000005677011667757442023131 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBTraceManager.h" #include #include #include #include QGoDBTraceManager::QGoDBTraceManager(QObject *iParent) : QObject(iParent), m_SelectedCollectionData(NULL), m_SelectedColorData(NULL), m_CurrentTimePoint(NULL), m_Table(NULL), m_CollectionOfTraces(NULL), m_DatabaseConnector(NULL), m_IsColorCodingOn(false), m_IsShowOnlyCurrentTimePointOn(false) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoDBTraceManager::~QGoDBTraceManager() { if ( this->m_CollectionOfTraces ) { delete this->m_CollectionOfTraces; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::SetInfo(unsigned int iImgSessionID, QWidget *iParent) { SetCollectionsTraceNames(); this->m_TraceNameID = this->GetTheNameIDFromName(this->m_TraceName); this->m_CollectionNameID = this->GetTheNameIDFromName(this->m_CollectionName); this->m_CollectionOfID = this->GetTheNameIDFromName(this->m_CollectionOf); this->m_CollectionOfTraces = new GoDBCollectionOfTraces(this->m_CollectionName, this->m_TraceName, this->m_CollectionOf, iImgSessionID); this->m_Table = new QGoTableWidget(iParent); QObject::connect( this->m_Table, SIGNAL( CheckedRowsChanged(int) ), this, SLOT( UpdateHighlightedElementsInVisuContainer(int) ) ); QObject::connect( this->m_Table, SIGNAL( VisibleRowsChanged(int) ), this, SLOT( UpdateVisibleElementsInVisuContainer(int) ) ); QObject::connect( this->m_Table, SIGNAL(customContextMenuRequested (const QPoint &) ), this, SLOT( CreateContextMenu ( const QPoint &) ) ); this->m_ImgSessionID = iImgSessionID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoDBTraceManager::GetTheNameIDFromName(std::string iName) { std::string oNameID = iName; oNameID += "ID"; return oNameID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoTableWidget * QGoDBTraceManager::GetTableWidget() { return this->m_Table; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoDBTraceManager::GetLastCreatedTraceID( vtkMySQLDatabase *iDatabaseConnector) { return MaxValueForOneColumnInTable( iDatabaseConnector, this->m_TraceNameID, this->m_TraceName, "ImagingSessionID", ConvertToString< unsigned int >(this->m_ImgSessionID) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::CreateContextMenu(const QPoint & iPos) { QMenu *ContextMenu = new QMenu; this->AddActionsContextMenu(ContextMenu); ContextMenu->exec( this->m_Table->mapToGlobal(iPos) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::AddActionsContextMenu(QMenu *iMenu) { this->AddGeneralActionsContextMenu(iMenu); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::AddGeneralActionsContextMenu(QMenu *iMenu) { m_CheckedTracesMenu = new QMenu( tr("With the checked %1s").arg( this->m_TraceName.c_str() ) ); m_CheckedTracesMenu->addAction( tr("Delete them"), this, SLOT( DeleteTracesFromContextMenu() ) ); //m_CheckedTracesMenu->addAction( tr("Add to selected %1 %2").arg( // this->m_CollectionName.c_str() ) // .arg(this->m_SelectedCollectionData->first.c_str()), // this, SLOT( AddToSelectedCollection() ) ); m_CheckedTracesMenu->addAction( tr("Change their color to the selected one : %1") .arg( this->m_SelectedColorData->first.c_str() ), this, SLOT( ChangeTraceColor() ) ); iMenu->addAction( this->m_CheckedTracesMenu->menuAction() ); QMenu *SelectedTracesMenu = new QMenu( tr("With the selected %1s").arg( this->m_TraceName.c_str() ) ); SelectedTracesMenu->addAction( tr("Check the selected %1s") .arg( this->m_TraceName.c_str() ), this, SLOT( CheckSelectedRows() ) ); SelectedTracesMenu->addAction( tr("Uncheck the selected %1s") .arg( this->m_TraceName.c_str() ), this, SLOT( UncheckSelectedRows() ) ); SelectedTracesMenu->addAction( tr("Show the selected %1s") .arg( this->m_TraceName.c_str() ), this, SLOT( ShowSelectedRows() ) ); SelectedTracesMenu->addAction( tr("Hide the selected %1s") .arg( this->m_TraceName.c_str() ), this, SLOT( HideSelectedRows() ) ); iMenu->addAction( SelectedTracesMenu->menuAction() ); QMenu *ColorMenu = new QMenu( tr("Change color of your %1s").arg( this->m_TraceName.c_str() ) ); ColorMenu->addAction( tr("To the selected color for the checked %1s") .arg( this->m_TraceName.c_str() ), this, SLOT( ChangeTraceColor() ) ); QAction *ColorCoding = new QAction(tr("Based on the selected column"), ColorMenu); ColorCoding->setCheckable(true); ColorCoding->setChecked(m_IsColorCodingOn); QObject::connect( ColorCoding, SIGNAL( triggered (bool) ), this, SLOT( SetColorCoding(bool) ) ); ColorMenu->addAction(ColorCoding); iMenu->addAction( ColorMenu->menuAction() ); iMenu->addAction( tr("Copy Selection"), this->m_Table, SLOT( CopySelection() ) ); iMenu->addAction( tr("Copy table"), this->m_Table, SLOT( CopyTable() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::AddSpecificActionsForContourMesh(QMenu *iMenu) { /** \todo Lydie: when using lineages, remove the following*/ //for the time being, as we don't use lineages iMenu->addAction( tr("Go to this %1") .arg( this->m_TraceName.c_str() ), this, SLOT( GoToTheTrace() ) ); QAction *ShowCurrentTimePoint = new QAction(tr("Show only in the table the %1 for the current timepoint") .arg( this->m_TraceName.c_str() ), iMenu); ShowCurrentTimePoint->setCheckable(true); ShowCurrentTimePoint->setChecked(this->m_IsShowOnlyCurrentTimePointOn); QObject::connect( ShowCurrentTimePoint, SIGNAL( triggered (bool) ), this, SLOT( ShowOnlyRowsForCurrentTimePoint(bool) ) ); iMenu->addAction(ShowCurrentTimePoint); /** \todo Lydie: when using lineage, put it in the generalActionsContextMenu*/ this->AddActionForAddingCheckedTracesToCollection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager::AddActionForAddingCheckedTracesToCollection() { this->m_CheckedTracesMenu->addAction( tr("Add to selected %1 %2") .arg( this->m_CollectionName.c_str() ) .arg( this->m_SelectedCollectionData->first.c_str() ), this, SLOT( AddToSelectedCollection() ) ); this->m_CheckedTracesMenu->addAction( tr("Create a new %1 from checked %2s") .arg( this->m_CollectionName.c_str() ) .arg( this->m_TraceName.c_str() ), this, SLOT( CreateCorrespondingCollection() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::CheckSelectedRows() { this->m_Table->ChangeCheckStateSelectedRows(this->m_TraceName, this->m_TraceNameID, Qt::Checked); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager::UncheckSelectedRows() { this->m_Table->ChangeCheckStateSelectedRows(this->m_TraceName, this->m_TraceNameID, Qt::Unchecked); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager::ShowSelectedRows() { this->m_Table->ChangeVisibilityStateSelectedRows(this->m_TraceName, this->m_TraceNameID, Qt::Checked); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager::HideSelectedRows() { this->m_Table->ChangeVisibilityStateSelectedRows(this->m_TraceName, this->m_TraceNameID, Qt::Unchecked); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager::ChangeTraceColor() { //as it impacts also the collectionof, a signal has to be emitted: //but not for contourManager (no collectionof) where ChangeTraceColor() //is then reimplemented emit TraceColorToChange(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ std::list< unsigned int > QGoDBTraceManager::GetListTracesIDsFromThisCollectionOf( vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTraces) { return this->m_CollectionOfTraces->GetListTracesIDsFromThisCollectionOf( iDatabaseConnector, iListTraces); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ std::list< unsigned int > QGoDBTraceManager::GetListTracesIDsBelongingToCollectionIDs( vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListCollectionIDs) { return this->m_CollectionOfTraces->GetTraceIDsBelongingToCollectionID(iDatabaseConnector, iListCollectionIDs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager:: DisplayInfoForExistingTraces(vtkMySQLDatabase * iDatabaseConnector, const std::list< unsigned int > & iListTraces) { this->m_Table->setSortingEnabled(false); std::list< unsigned int >::const_iterator iter = iListTraces.begin(); while ( iter != iListTraces.end() ) { this->DisplayInfoForExistingTrace(iDatabaseConnector, *iter); ++iter; } this->m_Table->setSortingEnabled(true); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ bool QGoDBTraceManager::CheckThatThereAreTracesToDelete( const std::list & iListTracesIDToDelete) { if ( iListTracesIDToDelete.empty() ) { QMessageBox msgBox; msgBox.setText( tr("Please check at least one %1 to be deleted") .arg( this->m_TraceName.c_str() ) ); msgBox.exec(); return false; } else { switch( QMessageBox::warning(this->m_Table, tr(""), tr("Are you sure you want to delete\n" "permanently the selected %1s?").arg( this->m_TraceName.c_str() ), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) { case QMessageBox::Yes: return true; case QMessageBox::No: return false; default: return false; } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager::DeleteTracesFromContextMenu() { std::list< unsigned int > ListTracesIDToDelete = this->GetListHighlightedIDs(); if (this->CheckThatThereAreTracesToDelete(ListTracesIDToDelete) ) { //as it impacts also on the collection and the collectionOf, //a signal has to be emitted for another traceManager: emit CheckedTracesToDelete(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager::UpdateCollectionID(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs, int iCollectionID) { this->m_CollectionOfTraces->UpdateCollectionIDOfSelectedTraces(iListTracesIDs, iCollectionID, iDatabaseConnector); this->DisplayInfoForExistingTraces(iDatabaseConnector, iListTracesIDs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ std::list< unsigned int > QGoDBTraceManager::GetListCollectionIDs( vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs) { return this->m_CollectionOfTraces->GetListCollectionIDs( iDatabaseConnector, iListTracesIDs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager::UpdateBoundingBoxes(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs, bool UpdateTW) { this->m_CollectionOfTraces->RecalculateDBBoundingBox(iDatabaseConnector, iListTracesIDs); if ( UpdateTW ) { this->DisplayInfoForExistingTraces(iDatabaseConnector, iListTracesIDs); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------ double * QGoDBTraceManager::GetVectorFromQColor(QColor iColor) { qreal r, g, b, a; iColor.getRgbF(&r, &g, &b, &a); double *rgba = new double[4]; rgba[0] = static_cast< double >( r ); rgba[1] = static_cast< double >( g ); rgba[2] = static_cast< double >( b ); rgba[3] = static_cast< double >( a ); return rgba; } //------------------------------------------------------------------------- //------------------------------------------------------------------------ std::list< QGoDBTraceManager::NameWithColorData > QGoDBTraceManager::GetAllTraceIDsWithColor( vtkMySQLDatabase *iDatabaseConnector, std::string & ioIDToSelect) { ioIDToSelect = this->m_LastSelectedTraceAsCollection; return this->m_CollectionOfTraces->GetAllTracesIDsWithColor( iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager::CheckTheTraceInTW(unsigned int iTraceID, Qt::CheckState iState) { this->m_Table->SetCheckStateForTraceID(iTraceID, this->m_TraceName, iState, false); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager::ShowTheTraceInTW(unsigned int iTraceID, Qt::CheckState iState) { this->m_Table->SetVisibleStateForTraceID(iTraceID, this->m_TraceName, iState, false); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTraceManager::GoToTheTrace() { std::list< unsigned int > ListCheckedTraces = this->GetListHighlightedIDs(); if ( ListCheckedTraces.size() != 1 ) { QMessageBox msgBox; msgBox.setText( tr("Please select one and only one %1 to go to") .arg( this->m_TraceName.c_str() ) ); msgBox.exec(); return; } GoDBCoordinateRow CoordCenter = this->m_Table->GetCoordinateCenterBoundingBox(ListCheckedTraces.front(), this->m_TraceName); emit NeedToGoToTheLocation( CoordCenter.GetMapValue("XCoord"), CoordCenter.GetMapValue("YCoord"), CoordCenter.GetMapValue("ZCoord"), CoordCenter.GetMapValue("TCoord") ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::CreateCorrespondingCollection() { std::list< unsigned int > ListCheckedTraces = this->GetListHighlightedIDs(); if ( ListCheckedTraces.empty() ) { QMessageBox msgBox; msgBox.setText( tr("Please select at least one %1 to create the %2") .arg( this->m_TraceName.c_str() ) .arg( this->m_CollectionName.c_str() ) ); msgBox.exec(); return; } emit NewCollectionFromCheckedTraces(ListCheckedTraces); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBCoordinateRow QGoDBTraceManager::GetCoordinateFromInt(int iXCoord, int iYCoord, int iZCoord, int iTCoord) { GoDBCoordinateRow coord; coord.SetField< unsigned int >("XCoord", iXCoord); coord.SetField< unsigned int >("YCoord", iYCoord); coord.SetField< unsigned int >("ZCoord", iZCoord); coord.SetField< unsigned int >("TCoord", iTCoord); return coord; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::AddToSelectedCollection() { std::list< unsigned int > ListCheckedTraces = this->GetListHighlightedIDs(); if ( ListCheckedTraces.empty() ) { QMessageBox msgBox; msgBox.setText( tr("Please check at least one %1 to be part of the %2") .arg( this->m_TraceName.c_str() ) .arg( this->m_CollectionName.c_str() ) ); msgBox.exec(); return; } emit CheckedTracesToAddToSelectedCollection( this->GetListHighlightedIDs() ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoDBTraceManager::GetLastCreatedTracesIDs( vtkMySQLDatabase *iDatabaseConnector, int iNumberOfTraceIDs) { return this->m_CollectionOfTraces->GetLastCreatedTracesIDs( iDatabaseConnector, iNumberOfTraceIDs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::SetDatabaseConnection( vtkMySQLDatabase *iDatabaseConnector) { this->m_DatabaseConnector = iDatabaseConnector; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::SetSelectedCollection(NameWithColorData *iCollectionData) { this->m_SelectedCollectionData = iCollectionData; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::SetCurrentTimePoint(int *iTimePoint) { this->m_CurrentTimePoint = iTimePoint; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::SetSelectedColor(NameWithColorData *iColorData) { this->m_SelectedColorData = iColorData; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::ShowOnlyRowsForCurrentTimePoint(bool IsChecked) { this->m_IsShowOnlyCurrentTimePointOn = IsChecked; if ( IsChecked ) { this->m_Table->ShowOnlyRowsForTimePoint(*this->m_CurrentTimePoint); } else { this->m_Table->ShowAllRows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::CheckShowRows() { if ( this->m_IsShowOnlyCurrentTimePointOn ) { this->ShowOnlyRowsForCurrentTimePoint(true); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTraceManager::UpdateLastSelectedOneAsCollection() { this->m_LastSelectedTraceAsCollection = this->m_SelectedCollectionData->first; } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBNameDescEntityManager.cxx0000644000175000017500000001542011667757442024732 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBNameDescEntityManager.h" #include "ConvertToStringHelper.h" #include "SelectQueryDatabaseHelper.h" #include "QueryDataBaseHelper.h" #include "QGoDeleteFromListDialog.h" QGoDBNameDescEntityManager:: QGoDBNameDescEntityManager( QWidget *iParent, std::string iEntityName, int iImgSessionID) : QWidget(iParent), m_NameDescDialog(NULL), m_DatabaseConnector(NULL) { this->m_EntityName = iEntityName; this->m_ImgSessionID = iImgSessionID; this->m_NameNewEntity = ""; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoDBNameDescEntityManager::~QGoDBNameDescEntityManager() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoDBNameDescEntityManager::AddAnEntity( vtkMySQLDatabase *iDatabaseConnector) { this->m_NameDescDialog = new QGoNameDescriptionInputDialog( this, this->m_EntityName.c_str() ); this->m_DatabaseConnector = iDatabaseConnector; QObject::connect ( this->m_NameDescDialog, SIGNAL( NewNameDescription(std::string, std::string) ), this, SLOT( ValidateName(std::string, std::string) ) ); bool ok = this->m_NameDescDialog->exec(); if ( !ok ) { this->m_NameNewEntity.clear(); } return this->m_NameNewEntity; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoDBNameDescEntityManager::NamesDescrContainerType QGoDBNameDescEntityManager::GetListExistingEntities(vtkMySQLDatabase *iDatabaseConnector) { if ( this->m_ImgSessionID != 0 ) { return ListSpecificValuesForTwoColumns(iDatabaseConnector, this->m_EntityName, "Name", "Description", "ImagingSessionID", ConvertToString< int >(this->m_ImgSessionID), "Name"); } else { return VectorTwoColumnsFromTable(iDatabaseConnector, "Name", "Description", this->m_EntityName, "Name"); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoDBNameDescEntityManager::DeleteEntity( vtkMySQLDatabase *iDatabaseConnector) { QGoDeleteFromListDialog *Dialog = new QGoDeleteFromListDialog( this->GetNameExistingEntities(iDatabaseConnector), this, this->m_EntityName); this->m_DatabaseConnector = iDatabaseConnector; QObject::connect(Dialog, SIGNAL( ListEntitiesToDelete(std::vector< std::string > ) ), this, SLOT( DeleteEntitiesFromList(std::vector< std::string > ) ) ); Dialog->show(); return Dialog->exec(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBNameDescEntityManager::DeleteEntitiesFromList( std::vector< std::string > iVectorNamesEntitiesToDelete) { if ( this->m_DatabaseConnector != 0 ) { DeleteRows(this->m_DatabaseConnector, this->m_EntityName, "Name", iVectorNamesEntitiesToDelete); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoDBNameDescEntityManager::GetNameNewEntity() { return this->m_NameNewEntity; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector< std::string > QGoDBNameDescEntityManager::GetNameExistingEntities(vtkMySQLDatabase *iDatabaseConnector) { std::vector< std::string > ResultsQuery; if ( iDatabaseConnector ) { // if m_ImgSessionID = 0, the entity name is not related to an // imagingsession if ( this->m_ImgSessionID != 0 ) { ResultsQuery = ListSpecificValuesForOneColumn( iDatabaseConnector, this->m_EntityName, "Name", "ImagingSessionID", ConvertToString< int >(this->m_ImgSessionID), "Name"); } else { ResultsQuery = ListAllValuesForOneColumn(iDatabaseConnector, "Name", this->m_EntityName); } } return ResultsQuery; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoDBNameDescEntityManager::GetTheEntityID(std::string iName, vtkMySQLDatabase *iDatabaseConnector) { std::string EntityNameID = this->m_EntityName; EntityNameID += "ID"; return FindOneID(iDatabaseConnector, this->m_EntityName, EntityNameID, "Name", iName); } GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBColorManager.cxx0000644000175000017500000001301211667757442023127 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBColorManager.h" #include #include #include "SelectQueryDatabaseHelper.h" QGoDBColorManager::QGoDBColorManager (QWidget *iParent) : QGoDBNameDescEntityManager(iParent, "color", 0) { } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ QGoDBColorManager::~QGoDBColorManager() { //this->m_DatabaseConnector->Close(); //this->m_DatabaseConnector->Delete(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ QGoDBColorManager::ItemColorComboboxData QGoDBColorManager::AddANewColor( vtkMySQLDatabase *iDatabaseConnector) { this->m_NewColorData.first.clear(); QColor col = QColorDialog::getColor(Qt::white, NULL, "Pick a new color", QColorDialog::ShowAlphaChannel); if ( col.isValid() ) { this->m_NewColorData.second = col; this->m_NewColorData.first = QGoDBNameDescEntityManager::AddAnEntity(iDatabaseConnector); } return this->m_NewColorData; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBColorManager::SaveNewEntityInDB() { if ( !this->CheckEntityAlreadyExists< GoDBColorRow >(this->m_NewColor) ) { QColor col = this->m_NewColorData.second; this->m_NewColor.SetField< int >( "Red", col.red() ); this->m_NewColor.SetField< int >( "Green", col.green() ); this->m_NewColor.SetField< int >( "Blue", col.blue() ); this->m_NewColor.SetField< int >( "Alpha", col.alpha() ); this->m_NewColor.SaveInDB(this->m_DatabaseConnector); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void QGoDBColorManager::ValidateName(std::string iName, std::string iDescription) { this->ValidateNameTemplate< GoDBColorRow >(this->m_NewColor, iName, iDescription); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool QGoDBColorManager::DeleteEntity(vtkMySQLDatabase *iDatabaseConnector) { QGoDeleteFromListDialog *Dialog = new QGoDeleteFromListDialog( this->GetListExistingColors(iDatabaseConnector), this, this->m_EntityName); this->m_DatabaseConnector = iDatabaseConnector; QObject::connect(Dialog, SIGNAL( ListEntitiesToDelete(std::vector< std::string > ) ), this, SLOT( DeleteEntitiesFromList(std::vector< std::string > ) ) ); Dialog->show(); return Dialog->exec(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ std::list< QGoDBColorManager::ItemColorComboboxData > QGoDBColorManager::GetListExistingColors(vtkMySQLDatabase *iDatabaseConnector) { std::list< ItemColorComboboxData > oInfoColors; std::vector< std::string > ResultsQuery = ListAllValuesForOneColumn( iDatabaseConnector, "*", "color", "name"); unsigned int i = 0; while ( i < ResultsQuery.size() ) { ItemColorComboboxData temp; temp.first = ResultsQuery[i + 1]; QColor tempColor( atoi( ResultsQuery[i + 2].c_str() ), atoi( ResultsQuery[i + 3].c_str() ), atoi( ResultsQuery[i + 4].c_str() ), atoi( ResultsQuery[i + 5].c_str() ) ); temp.second = tempColor; oInfoColors.push_back(temp); i = i + 7; } return oInfoColors; }GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBBookmarkManager.cxx0000644000175000017500000001172511667757442023627 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBBookmarkManager.h" #include #include "SelectQueryDatabaseHelper.h" QGoDBBookmarkManager::QGoDBBookmarkManager(QWidget *iParent, int iImgSessionID) : QGoDBNameDescEntityManager(iParent, "bookmark", iImgSessionID) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoDBBookmarkManager::~QGoDBBookmarkManager() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBBookmarkManager::AddABookmark(int iCoordID, vtkMySQLDatabase *iDatabaseConnector) { this->m_CoordIDForNewBookmark = iCoordID; this->AddAnEntity(iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBBookmarkManager::SaveNewEntityInDB() { QDateTime CreationDate = QDateTime::currentDateTime(); std::string CreationDateStr = CreationDate.toString(Qt::ISODate).toStdString(); this->m_NewBookmark.SetField("CreationDate", CreationDateStr); this->m_NewBookmark.SetField< int >("CoordID", this->m_CoordIDForNewBookmark); this->m_NewBookmark.SetField< int >("ImagingSessionID", this->m_ImgSessionID); if ( !this->CheckEntityAlreadyExists< GoDBBookmarkRow >(this->m_NewBookmark) ) { this->m_NewBookmark.SaveInDB(this->m_DatabaseConnector); emit ListBookmarksChanged(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBCoordinateRow QGoDBBookmarkManager::GetCoordinatesForBookmark( vtkMySQLDatabase *iDatabaseConnector, std::string iName) { GoDBCoordinateRow BookmarkCoord; BookmarkCoord.SetValuesForSpecificID( this->GetCoordIDForBookmark(iDatabaseConnector, iName), iDatabaseConnector); return BookmarkCoord; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoDBBookmarkManager::GetCoordIDForBookmark( vtkMySQLDatabase *iDatabaseConnector, std::string iName) { return FindOneID(iDatabaseConnector, "bookmark", "CoordID", "Name", iName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBBookmarkManager::ValidateName(std::string iName, std::string iDescription) { this->ValidateNameTemplate< GoDBBookmarkRow >(this->m_NewBookmark, iName, iDescription); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBBookmarkManager::DeleteBookmark( vtkMySQLDatabase *iDatabaseConnector) { bool ok = this->DeleteEntity(iDatabaseConnector); if ( ok ) { emit ListBookmarksChanged(); //to update the menu for bookmarks; } }GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBBookmarkManager.h0000644000175000017500000001004711667757442023250 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBBookmarkManager_h #define __QGoDBBookmarkManager_h #include "GoDBCoordinateRow.h" #include "GoDBBookmarkRow.h" #include "QGoGUILibConfigure.h" #include "QGoDBNameDescEntityManager.h" /** \class QGoDBBookmarkManager \brief the QGoDBBookmarkManager manages the interactions between the user and the database for the Bookmark DBTable. \ingroup DB GUI */ class QGOGUILIB_EXPORT QGoDBBookmarkManager: public QGoDBNameDescEntityManager { Q_OBJECT public: explicit QGoDBBookmarkManager(QWidget *iParent = 0, int iImgSessionID = 0); ~QGoDBBookmarkManager(); /** \brief execute the dialog asking the user to enter a name and a description, validates the name, set the m_DatabaseConnectorForNewBkmrk and save the bookmark in the DB \param[in] iCoordID ID for the coordinate to be saved in the bookmark table \param[in] iDatabaseConnector connection to the database */ void AddABookmark(int iCoordID, vtkMySQLDatabase *iDatabaseConnector); /** \brief return the coordinate for the bookmark with the name iName \param[in] iDatabaseConnector connection to the database \param[in] iName name of the bookmark for which we want to get the coordinate \return GoDBCoordinateRow containing the data for the coordinate which name is iName */ GoDBCoordinateRow GetCoordinatesForBookmark( vtkMySQLDatabase *iDatabaseConnector, std::string iName); /** \brief delete the bookmarks from the database from a list the user selects and send a signal to tell that the list has changed \param[in] iDatabaseConnector connection to the database */ void DeleteBookmark(vtkMySQLDatabase *iDatabaseConnector); protected: GoDBBookmarkRow m_NewBookmark; int m_CoordIDForNewBookmark; protected slots: //mother class method void SaveNewEntityInDB(); /** \brief get the coordid for the bookmark with the name iName \param[in] iDatabaseConnector connection to the database \param[in] iName Name of the bookmark \return ID for the coordinate in the bookmark DBTable */ int GetCoordIDForBookmark(vtkMySQLDatabase *iDatabaseConnector, std::string iName); //mother class method void ValidateName(std::string iName, std::string iDescription); signals: void ListBookmarksChanged(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBCellTypeManager.h0000644000175000017500000000472011667757442023225 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBCellTypeManager_h #define __QGoDBCellTypeManager_h #include "QGoDBNameDescEntityManager.h" #include "GoDBCellTypeRow.h" /** \class QGoDBCellTypeManager \brief the QGoDBCellTypeManager manages the interactions between the user and the database for the celltype DBTable. \ingroup DB GUI */ class QGoDBCellTypeManager:public QGoDBNameDescEntityManager { Q_OBJECT public: explicit QGoDBCellTypeManager (QWidget *iParent = 0); ~QGoDBCellTypeManager() {} protected: GoDBCellTypeRow m_NewCellType; //mother class method virtual void SaveNewEntityInDB(); protected slots: //mother class method virtual void ValidateName(std::string iName, std::string iDescription); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBTrackManager.cxx0000644000175000017500000014602111667757442023124 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBTrackManager.h" #include "GoDBTrackRow.h" #include "GoDBTrackFamilyRow.h" #include #include #include "TrackStructure.h" #include "ConvertToStringHelper.h" QGoDBTrackManager::QGoDBTrackManager(int iImgSessionID, QWidget *iparent) : QGoDBTraceManager(), m_TrackContainerInfoForVisu(NULL) { this->SetInfo(iImgSessionID, iparent); this->m_TWContainer = new GoDBTWContainerForTrack(iImgSessionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoDBTrackManager::~QGoDBTrackManager() { if ( this->m_TWContainer ) { delete this->m_TWContainer; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::SetTracksInfoContainerForVisu( TrackContainer *iContainerForVisu) { this->SetTracesInfoContainerForVisuTemplate< TrackContainer >( iContainerForVisu, &this->m_TrackContainerInfoForVisu); QObject::connect( this->m_TrackContainerInfoForVisu, SIGNAL( NeedMeshesInfoForImportedTrack(unsigned int) ), this, SIGNAL( NeedMeshesInfoForImportedTrack(unsigned int) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::SetCollectionsTraceNames() { this->m_TraceName = "track"; this->m_CollectionName = "lineage"; this->m_CollectionOf = "mesh"; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::DisplayInfoForAllTraces( vtkMySQLDatabase *iDatabaseConnector) { this->DisplayInfoForAllTracesTemplate< GoDBTWContainerForTrack >( this->m_TWContainer, iDatabaseConnector, Qt::Unchecked); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::DisplayInfoForTracesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { (void) iListTPs; this->DisplayInfoForAllTraces(iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::DisplayInfoAndLoadVisuContainerForAllTracks( vtkMySQLDatabase *iDatabaseConnector) { this->DisplayInfoAndLoadVisuContainerWithAllTraces< GoDBTWContainerForTrack > (this->m_TWContainer, iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::DisplayInfoForLastCreatedTrace( vtkMySQLDatabase *iDatabaseConnector) { this->DisplayInfoForLastCreatedTraceTemplate< GoDBTWContainerForTrack >( this->m_TWContainer, iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::DisplayInfoForExistingTrace( vtkMySQLDatabase *iDatabaseConnector, int iTraceID) { this->DisplayInfoForExistingTraceTemplate< GoDBTWContainerForTrack >( this->m_TWContainer, iDatabaseConnector, iTraceID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBTrackManager::CreateNewTrackWithNoMesh( vtkMySQLDatabase *iDatabaseConnector) { GoDBTrackRow NewTrack; unsigned int NewTrackID = this->m_CollectionOfTraces->CreateCollectionWithNoTracesNoPoints< GoDBTrackRow >( iDatabaseConnector, *this->m_SelectedColorData, NewTrack); this->m_TrackContainerInfoForVisu->ResetCurrentElement(); // pointer to double has to be deleted after usage... double* color = this->GetVectorFromQColor(this->m_SelectedColorData->second); this->m_TrackContainerInfoForVisu->UpdateCurrentElementFromDB( NewTrackID, color, true); delete[] color; this->m_TrackContainerInfoForVisu->InsertCurrentElement(); this->DisplayInfoForLastCreatedTrace(iDatabaseConnector); NameWithColorData NewTrackData(ConvertToString< unsigned int >(NewTrackID), this->m_SelectedColorData->second); emit AddNewTraceIDInTS(NewTrackData); return NewTrackID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoDBTrackManager::UpdateTheTracesColor( vtkMySQLDatabase *iDatabaseConnector) { return this->UpdateTheTracesColorTemplate< GoDBTrackRow, TrackContainer >(iDatabaseConnector, this->m_TrackContainerInfoForVisu); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::UpdateTWAndContainerForImportedTraces( const std::vector< int > & iVectorImportedTraces, vtkMySQLDatabase *iDatabaseConnector) { this->UpdateTWAndContainerWithImportedTracesTemplate< GoDBTWContainerForTrack >(this->m_TWContainer, iVectorImportedTraces, iDatabaseConnector); //call the TrackContainer to give him iVectorImportedTraces } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::DeleteCheckedTraces(vtkMySQLDatabase *iDatabaseConnector) { //if the tracks to be deleted belongs to some divisions, the divisions need to //be deleted first: std::list ListDivisionsToDelete = this->m_CollectionOfTraces->GetTrackFamilyID(iDatabaseConnector, this->GetListHighlightedIDs() ); std::list::iterator iter = ListDivisionsToDelete.begin(); std::list TrackIDsWithNoLineage = std::list(); std::list LineagesToDelete = std::list(); while( iter != ListDivisionsToDelete.end() ) { if (*iter != 0) { emit NeedToGetDatabaseConnection(); GoDBTrackFamilyRow Division(*iter, this->m_DatabaseConnector); this->DeleteOneDivision(Division, this->m_DatabaseConnector, TrackIDsWithNoLineage, LineagesToDelete); } ++iter; } if (!TrackIDsWithNoLineage.empty() ) //set the lineageID to 0 and update the bounding boxes of the previous lineages { emit CheckedTracksToAddToSelectedLineage(TrackIDsWithNoLineage, 0, LineagesToDelete); } emit NeedToGetDatabaseConnection(); this->DeleteTracesTemplate< TrackContainer >(this->m_DatabaseConnector, this->m_TrackContainerInfoForVisu); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::DeleteListTraces(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTraces) { this->DeleteTracesTemplate< TrackContainer >(iDatabaseConnector, this->m_TrackContainerInfoForVisu, iListTraces, false); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoDBTrackManager::GetListHighlightedIDs() { return this->m_TrackContainerInfoForVisu->GetHighlightedElementsTraceID(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::UpdateHighlightedElementsInVisuContainer( int iTraceID) { this->m_TrackContainerInfoForVisu->UpdateElementHighlightingWithGivenTraceID(iTraceID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::UpdateVisibleElementsInVisuContainer(int iTraceID) { this->m_TrackContainerInfoForVisu-> UpdateElementVisibilityWithGivenTraceID(iTraceID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::GetTracesInfoFromDBAndModifyContainerForVisu( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs) { this->GetTracesInfoFromDBAndModifyContainerForVisuTemplate< TrackContainer >( this->m_TrackContainerInfoForVisu, iDatabaseConnector, iListTraceIDs); } //------------------------------------------------------------------------- // add pointer to structure instead //------------------------------------------------------------------------- void QGoDBTrackManager::SaveTrackCurrentElement( vtkMySQLDatabase *iDatabaseConnector) { GoDBTrackRow TrackToSave(this->m_ImgSessionID); unsigned int TrackID = this->m_TrackContainerInfoForVisu->m_CurrentElement.TraceID; if ( TrackID != 0 ) { TrackToSave.SetValuesForSpecificID(TrackID, iDatabaseConnector); } //save the track into the database TrackToSave.SetThePointsFromPolydata( this->m_TrackContainerInfoForVisu->m_CurrentElement.Nodes); TrackID = TrackToSave.SaveInDB(iDatabaseConnector); //save the track into the container: this->m_TrackContainerInfoForVisu->InsertCurrentElement(); //calculate the values to be put in the table widget: GoFigureTrackAttributes trackAttributes( this->m_TrackContainerInfoForVisu->m_CurrentElement.ComputeAttributes() ); this->m_TWContainer->SetTrackAttributes(&trackAttributes); this->m_TrackContainerInfoForVisu->ResetCurrentElement(); //update the table widget: if ( TrackID == 0 ) { this->DisplayInfoForLastCreatedTrace(iDatabaseConnector); } else { this->DisplayInfoForExistingTrace(iDatabaseConnector, TrackID); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::SaveTrackStructure( vtkMySQLDatabase *iDatabaseConnector, TrackStructure* iStructure) { GoDBTrackRow TrackToSave(this->m_ImgSessionID); unsigned int TrackID = iStructure->TraceID; if ( TrackID != 0 ) { TrackToSave.SetValuesForSpecificID(TrackID, iDatabaseConnector); } //save the track into the database TrackToSave.SetThePointsFromPolydata(iStructure->Nodes); TrackID = TrackToSave.SaveInDB(iDatabaseConnector); //calculate the values to be put in the table widget: GoFigureTrackAttributes trackAttributes( iStructure->ComputeAttributes() ); this->m_TWContainer->SetTrackAttributes(&trackAttributes); //update the table widget: if ( TrackID == 0 ) { this->DisplayInfoForLastCreatedTrace(iDatabaseConnector); } else { this->DisplayInfoForExistingTrace(iDatabaseConnector, TrackID); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::UpdatePointsOfCurrentElementForImportedTrack( std::map< unsigned int, double * > iMeshesInfo, vtkMySQLDatabase *iDatabaseConnector) { this->m_TrackContainerInfoForVisu->ImportTrackInCurrentElement(iMeshesInfo); this->SaveTrackCurrentElement(iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::UpdateTrackPolydataForVisu(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID) { std::list< double * > ListCenters = this->m_CollectionOfTraces->GetCoordinateCenterBoundingBox( iDatabaseConnector, iTrackID); TrackStructure* structure = this->m_TrackContainerInfoForVisu->UpdatePointsForATrack(iTrackID, ListCenters); SaveTrackStructure(iDatabaseConnector, structure); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::UpdateBoundingBoxes( vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs) { QGoDBTraceManager::UpdateBoundingBoxes(iDatabaseConnector, iListTracesIDs, false); std::list< unsigned int >::const_iterator iter = iListTracesIDs.begin(); while ( iter != iListTracesIDs.end() ) { this->UpdateTrackPolydataForVisu(iDatabaseConnector, *iter); ++iter; } } //------------------------------------------------------------------------- void QGoDBTrackManager::SetColorCoding(bool IsChecked) { this->SetColorCodingTemplate< TrackContainer >( this->m_TrackContainerInfoForVisu, IsChecked); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::AddActionsContextMenu(QMenu *iMenu) { QGoDBTraceManager::AddActionsContextMenu(iMenu); QMenu *SplitMergeMenu = new QMenu(tr("Split/Merge them"), iMenu); SplitMergeMenu->addAction( tr("Using the Widget"), this, SLOT( SplitMergeTrackWithWidget() ) ); SplitMergeMenu->addAction( tr("Split your track"), this, SLOT( TrackIDToEmit() ) ); SplitMergeMenu->addAction( tr("Merge your 2 tracks"), this, SLOT( MergeTracks() ) ); iMenu->addAction( SplitMergeMenu->menuAction() ); this->m_CheckedTracesMenu->addAction( tr("Go to the end") .arg( this->m_TraceName.c_str() ), this, SLOT( GoToTrackEnd() ) ); this->m_CheckedTracesMenu->addAction( tr("Go to the beginning") .arg( this->m_TraceName.c_str() ), this, SLOT( GoToTrackBegin() ) ); this->m_CheckedTracesMenu->addAction( tr("Create a new division from checked %1s") .arg( this->m_TraceName.c_str() ), this, SLOT( CreateCorrespondingTrackFamily() ) ); this->m_CheckedTracesMenu->addAction( tr("Delete the division for this tracks") , this, SLOT( DeleteTheDivisions() ) ); } //------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoDBTrackManager::TrackIDToEmit() { std::list< unsigned int > HighlightedTrackIDs = this->m_TrackContainerInfoForVisu->GetHighlightedElementsTraceID(); if ( HighlightedTrackIDs.size() != 1 ) { QMessageBox msgBox; msgBox.setText( tr("Please check one and only one Track to split") ); msgBox.exec(); } else { emit NeedToGetDatabaseConnection(); std::list list_meshes = this->GetListTracesIDsFromThisCollectionOf(this->m_DatabaseConnector, HighlightedTrackIDs); emit TrackToSplit( HighlightedTrackIDs.front(), list_meshes ); emit DBConnectionNotNeededAnymore(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::SplitMergeTrackWithWidget() { std::list< unsigned int > HighlightedTrackIDs = this->m_TrackContainerInfoForVisu->GetHighlightedElementsTraceID(); if ( HighlightedTrackIDs.size() == 0 ) { QMessageBox msgBox; msgBox.setText( tr("Please check at least one Track to be visualized in the widget") ); msgBox.exec(); } else { emit TrackIDToBeModifiedWithWidget(HighlightedTrackIDs); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::DisplayOnlyCalculatedValuesForExistingTrack( GoFigureTrackAttributes *iTrackAttributes, unsigned int iTrackID) { if ( iTrackAttributes != 0 ) { int timeInterval = m_TrackContainerInfoForVisu->getTimeInterval(); assert( timeInterval != 0 ); std::vector< std::string > ColumnNames (9); std::vector< std::string > Values (9); ColumnNames.at(0) = "Deplacement"; Values.at(0) = ConvertToString< double >(iTrackAttributes->total_length); ColumnNames.at(1) = "Distance"; Values.at(1) = ConvertToString< double >(iTrackAttributes->distance); ColumnNames.at(2) = "Theta"; Values.at(2) = ConvertToString< double >(iTrackAttributes->theta); ColumnNames.at(3) = "Phi"; Values.at(3) = ConvertToString< double >(iTrackAttributes->phi); ColumnNames.at(4) = "AvgSpeed"; Values.at(4) = ConvertToString< double > (iTrackAttributes->avg_speed / static_cast< double >( timeInterval )); ColumnNames.at(5) = "MaxSpeed"; Values.at(5) = ConvertToString< double > (iTrackAttributes->max_speed / static_cast< double >( timeInterval )); ColumnNames.at(6) = "AvgVolume"; Values.at(6) = ConvertToString< double >(iTrackAttributes->avg_volume); ColumnNames.at(7) = "NumberOfMeshes"; Values.at(7) = ConvertToString< unsigned int >(iTrackAttributes->number_meshes); ColumnNames.at(8) = "Tmax - Tmin"; Values.at(8) = ConvertToString< unsigned int >(iTrackAttributes->temporal_extent); this->m_Table->AddValuesForID(ColumnNames, Values, iTrackID, "trackID"); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::MergeTracks() { std::list< unsigned int > CheckedTrack = this->m_TrackContainerInfoForVisu->GetHighlightedElementsTraceID(); if ( CheckedTrack.size() != 2 ) { QMessageBox msgBox; msgBox.setText( tr("Please check two and only two tracks to be merged") ); msgBox.exec(); } else { emit NeedToGetDatabaseConnection(); unsigned int TrackIDToKeep = 0; unsigned int TrackIDToDelete = 0; if ( this->CheckOverlappingTracks(CheckedTrack, TrackIDToKeep, TrackIDToDelete, this->m_DatabaseConnector) ) { QMessageBox msgBox; msgBox.setText( tr("The two tracks are overlapping, it is not possible to merge them !!") ); msgBox.exec(); } else { //if first is mother of a lineage, doin't do anything bool isMother = this->isMother(this->m_DatabaseConnector, TrackIDToDelete); if(isMother) { emit DBConnectionNotNeededAnymore(); QMessageBox msgBox; msgBox.setText( tr("The first track is already a mother track !!") ); msgBox.exec(); return; } // if second is dauther of a lineage, don't do anything std::vector family1 = this->GetTrackFamily(this->m_DatabaseConnector, TrackIDToKeep); if(family1.size() > 0) { emit DBConnectionNotNeededAnymore(); QMessageBox msgBox; msgBox.setText( tr("The second track is already a daughter track !!") ); msgBox.exec(); return; } // delete smallest track (in time) // strategy: // 1-delete previous division // 2-create new track // 3-create new division // therefore we ensure to have a correct lineage tree unsigned int oldMotherID = 0; unsigned int oldDaughter = 0; // delete mother division std::vector family = this->GetTrackFamily(this->m_DatabaseConnector, TrackIDToDelete); // if track belongs to a lineage if(family.size() > 0) { oldMotherID = family[1]; if(family[2] == TrackIDToDelete) { oldDaughter = family[3]; } else { oldDaughter = family[2]; } // Delete old track mother division std::list oldList; oldList.push_back(oldMotherID); this->DeleteTheDivisions(oldList); } // connection is closed above... emit NeedToGetDatabaseConnection(); // merge std::list< unsigned int > TraceIDToDelete; TraceIDToDelete.push_back(TrackIDToDelete); std::list< unsigned int > MeshesBelongingToTrackToDelete = this->m_CollectionOfTraces->GetListTracesIDsFromThisCollectionOf( this->m_DatabaseConnector, TraceIDToDelete); this->DeleteListTraces(this->m_DatabaseConnector, TraceIDToDelete); emit MeshesToAddToTrack(MeshesBelongingToTrackToDelete, TrackIDToKeep); // if track belongs to a lineage if(family.size() > 0) { // Create division old mother and new daughter std::list newdaughter; newdaughter.push_back(oldMotherID); newdaughter.push_back(oldDaughter); newdaughter.push_back(TrackIDToKeep); this->CreateCorrespondingTrackFamily(newdaughter); } } emit DBConnectionNotNeededAnymore(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoDBTrackManager::CheckOverlappingTracks( std::list< unsigned int > iTrackIDs, unsigned int & ioTraceIDToKeep, unsigned int & ioTraceIDToDelete, vtkMySQLDatabase *iDatabaseConnector) { unsigned int TraceID1 = 0, TraceID2 = 0; unsigned int TimePointMin1 = 0, TimePointMin2 = 0, TimePointMax1 = 0, TimePointMax2 = 0; bool oTracksOverlapping = true; std::list< unsigned int >::iterator iter = iTrackIDs.begin(); if ( iter == iTrackIDs.end() ) { std::cout << "Pb, there should have been 2 tracks instead of 0 in this method" << std::endl; return oTracksOverlapping; } TraceID1 = *iter; TimePointMin1 = this->m_CollectionOfTraces->GetBoundedBoxTimePoint( iDatabaseConnector, TraceID1, true); TimePointMax1 = this->m_CollectionOfTraces->GetBoundedBoxTimePoint( iDatabaseConnector, TraceID1, false); ++iter; if ( iter == iTrackIDs.end() ) { std::cout << "Pb, there should have been 2 tracks instead of 1 in this method" << std::endl; return oTracksOverlapping; } TraceID2 = *iter; TimePointMin2 = this->m_CollectionOfTraces->GetBoundedBoxTimePoint( iDatabaseConnector, TraceID2, true); TimePointMax2 = this->m_CollectionOfTraces->GetBoundedBoxTimePoint( iDatabaseConnector, TraceID2, false); if ( TimePointMin2 > TimePointMax1 ) { oTracksOverlapping = false; ioTraceIDToKeep = TraceID2; ioTraceIDToDelete = TraceID1; } if ( TimePointMin1 > TimePointMax2 ) { oTracksOverlapping = false; ioTraceIDToKeep = TraceID1; ioTraceIDToDelete = TraceID2; } return oTracksOverlapping; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::CreateCorrespondingTrackFamily( std::list iDivisions ) { int MotherID = 0; std::list DaughtersIDs = std::list(); std::list CheckedTracks; if(iDivisions.size()) { CheckedTracks = iDivisions; } else { CheckedTracks = this->GetListHighlightedIDs(); } if (CheckedTracks.size() != 3) { QMessageBox msgBox; msgBox.setText( tr("Please select 3 tracks to add your division") ); msgBox.exec(); return; } emit NeedToGetDatabaseConnection(); if (this->IdentifyMotherDaughtersToCreateTrackFamily(this->m_DatabaseConnector, CheckedTracks, MotherID, DaughtersIDs) ) { int TrackFamilyID = this->CreateTrackFamily(this->m_DatabaseConnector, MotherID, DaughtersIDs); if (TrackFamilyID != -1) { //check the lineageID of the mother: std::list TrackID; TrackID.push_back(MotherID); std::list LineageIDToCheck = this->m_CollectionOfTraces->GetListCollectionIDs(this->m_DatabaseConnector,TrackID); //update the trackFamilyID for the daughters: std::list::iterator iter = DaughtersIDs.begin(); while(iter != DaughtersIDs.end() ) { this->UpdateTrackFamilyIDForDaughter(this->m_DatabaseConnector, *iter, TrackFamilyID); ++iter; } //if the daughters belongs to other lineages, they need to be deleted and all the tracks belonging //to these lineages have to be added to the DaughtersIDs list to be added to the mother lineage std::list PreviousLineagesToDelete = this->GetTrackIDFromDaughtersFamilies(this->m_DatabaseConnector, DaughtersIDs); if (!LineageIDToCheck.empty()) { //the mother track already belong to the lineage, need to add the daughters and her families: emit CheckedTracksToAddToSelectedLineage(DaughtersIDs, LineageIDToCheck.front(), PreviousLineagesToDelete); } else { //need to add to the new lineage the mother track, the daughters and her families: DaughtersIDs.push_back(MotherID); emit NewLineageToCreateFromTracks(DaughtersIDs, MotherID, PreviousLineagesToDelete); } } } emit DBConnectionNotNeededAnymore(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoDBTrackManager::IdentifyMotherDaughtersToCreateTrackFamily( vtkMySQLDatabase* iDatabaseConnector, const std::list & iListTracksID, int &ioMotherID, std::list & ioDaughtersID) { //get the trackid with the lowest timepoint and check that there is only one: ioMotherID = this->m_CollectionOfTraces->GetTraceIDWithLowestTimePoint( iDatabaseConnector,iListTracksID); if (ioMotherID == -1) { QMessageBox msgBox; msgBox.setText( tr("Can not create the division as two of your selected tracks can be the mother") ); msgBox.exec(); return false; } //check that none of the 2 others tracks overlap the mother: std::list::const_iterator iter = iListTracksID.begin(); //to change: modify the method CheckOverlappingTracks: unsigned int ioTraceIDToKeep = 0; unsigned int ioTraceIDToDelete = 0; while(iter != iListTracksID.end()) { if (*iter != static_cast(ioMotherID) ) { std::list TracksOverlappingToCheck; TracksOverlappingToCheck.push_back(ioMotherID); TracksOverlappingToCheck.push_back(*iter); if (this->CheckOverlappingTracks(TracksOverlappingToCheck, ioTraceIDToKeep, ioTraceIDToDelete, iDatabaseConnector) ) { QMessageBox msgBox; msgBox.setText( tr("Can not create the division as one daughter is overlapping the mother") ); msgBox.exec(); return false; } ioDaughtersID.push_back(*iter); } ++iter; } return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoDBTrackManager::CreateTrackFamily(vtkMySQLDatabase* iDatabaseConnector, unsigned int iMotherTrackID, const std::list & iDaughtersID) { int oTrackFamilyID = -1; //check that the mother is not already a mother in a trackfamily: GoDBTrackFamilyRow TrackFamily; TrackFamily.SetField("TrackIDMother", iMotherTrackID); if (TrackFamily.DoesThisTrackFamilyAlreadyExists(iDatabaseConnector) != -1) { QMessageBox msgBox; msgBox.setText( tr("Can not create the division as the Mother track is already mother of other daugthers") ); msgBox.exec(); return oTrackFamilyID; } if(iDaughtersID.size() != 2) { std::cout<<"Pb, there is more than 2 daughters to create the division !!"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return oTrackFamilyID; } std::list::const_iterator iter = iDaughtersID.begin(); unsigned int TrackIDDaughterOne = *iter; ++iter; unsigned int TrackIDDaughterTwo = *iter; TrackFamily.SetField("TrackIDDaughter1", TrackIDDaughterOne); TrackFamily.SetField("TrackIDDaughter2", TrackIDDaughterTwo); this->m_TrackContainerInfoForVisu->AddDivision(iMotherTrackID, TrackIDDaughterOne, TrackIDDaughterTwo); return TrackFamily.SaveInDB(iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::UpdateTrackFamilyIDForDaughter( vtkMySQLDatabase* iDatabaseConnector, unsigned int iDaughterID, unsigned int iTrackFamilyID) { GoDBTrackRow Daughter; Daughter.SetValuesForSpecificID(iDaughterID, iDatabaseConnector); Daughter.SetField("TrackFamilyID", iTrackFamilyID); Daughter.SaveInDB(iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list QGoDBTrackManager::GetTrackIDFromDaughtersFamilies( vtkMySQLDatabase* iDatabaseConnector, std::list &ioTrackIDsOfTheFamilies) { //delete the daughtersLineageID then as they are useless: std::list DaughtersLineageID = this->m_CollectionOfTraces->GetListCollectionIDs(iDatabaseConnector, ioTrackIDsOfTheFamilies); std::list FirstDaugthersIDs = ioTrackIDsOfTheFamilies; std::list::iterator iter = FirstDaugthersIDs.begin(); ioTrackIDsOfTheFamilies.clear(); //in order not to have twice the daughtersIDs while(iter != FirstDaugthersIDs.end() ) { std::list ListDaughterID; ListDaughterID.push_back(*iter); std::list LineageIDofDaughter = this->m_CollectionOfTraces->GetListCollectionIDs(iDatabaseConnector, ListDaughterID); if (LineageIDofDaughter.empty()) //need to put back the ID of the daughter as it won't be returned by the query { ioTrackIDsOfTheFamilies.push_back(*iter); } else { std::list CollectionID; CollectionID.push_back(LineageIDofDaughter.front()); std::list TrackIDsofTheFamily = this->m_CollectionOfTraces->GetTraceIDsBelongingToCollectionID( iDatabaseConnector, CollectionID); std::list::iterator iterTrackIDs = TrackIDsofTheFamily.begin(); while (iterTrackIDs != TrackIDsofTheFamily.end() ) { ioTrackIDsOfTheFamilies.push_back(*iterTrackIDs); ++iterTrackIDs; } } ++iter; } return DaughtersLineageID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::LoadInfoVisuContainerForTrackFamilies( vtkMySQLDatabase *iDatabaseConnector) { std::list ListTrackIDs = this->m_CollectionOfTraces->GetTrackFamilyDataFromDB(iDatabaseConnector); this->m_TrackContainerInfoForVisu->SetListOfDivisions(ListTrackIDs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::DeleteTheDivisions(std::list iDivisions) { //check that the selected traces are all mother, if not message in the status bar: std::list TrackIDNotMother = std::list(); std::list CheckedTracks; if(iDivisions.size()) { CheckedTracks = iDivisions; } else { CheckedTracks = this->m_TrackContainerInfoForVisu->GetHighlightedElementsTraceID(); } std::list TrackIDsWithNoLineage = std::list(); std::list LineagesToDelete = std::list(); if (CheckedTracks.empty() ) { QMessageBox msgBox; msgBox.setText( tr("Please select the MotherTracks you want the divisions to be deleted") ); msgBox.exec(); return; } std::list::iterator iter = CheckedTracks.begin(); while (iter != CheckedTracks.end()) { emit NeedToGetDatabaseConnection(); GoDBTrackFamilyRow Division; Division.SetField("TrackIDMother", *iter); int TrackFamilyToDelete = Division.DoesThisTrackFamilyAlreadyExists(this->m_DatabaseConnector); if (TrackFamilyToDelete == -1) //the selected track is not a mother { TrackIDNotMother.push_back(*iter); } else { Division.SetValuesForSpecificID(TrackFamilyToDelete, this->m_DatabaseConnector); //set the value of the existing TrackFamily this->DeleteOneDivision(Division, this->m_DatabaseConnector, TrackIDsWithNoLineage, LineagesToDelete ); } ++iter; } this->PrintAMessageForTracksWithNoDivision(TrackIDNotMother); if (!TrackIDsWithNoLineage.empty() ) //set the lineageID to 0 and update the bounding boxes of the previous lineages { emit CheckedTracksToAddToSelectedLineage(TrackIDsWithNoLineage, 0, LineagesToDelete); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::DeleteOneDivision(GoDBTrackFamilyRow iDivision, vtkMySQLDatabase* iDatabaseConnector, std::list &ioTrackIDsNoLineage, std::list &ioMotherLineageToDelete) { std::list DaughtersIDs; DaughtersIDs.push_back( iDivision.GetMapValue("TrackIDDaughter1") ); DaughtersIDs.push_back( iDivision.GetMapValue("TrackIDDaughter2") ); int MotherID = iDivision.GetMapValue("TrackIDMother"); bool IsPartOfBiggerLineage = true; if (!this->IsTheTrackADaughter(MotherID, this->m_DatabaseConnector) ) // set the lineageID to 0 { ioTrackIDsNoLineage.push_back(MotherID); IsPartOfBiggerLineage = false; } //delete the division from the database: iDivision.DeleteFromDB(this->m_DatabaseConnector); //update the different values for the daughters of the division: this->UpdateFormerDaughtersOfADeletedDivision(DaughtersIDs, ioTrackIDsNoLineage, IsPartOfBiggerLineage); //delete the division from the visu: this->m_TrackContainerInfoForVisu->DeleteADivision( MotherID ); if (!IsPartOfBiggerLineage) //the mother is not a daughter and the daughters are not mother, the lineage need to be deleted { emit NeedToGetDatabaseConnection(); GoDBTrackRow Mother(MotherID, this->m_DatabaseConnector); emit DBConnectionNotNeededAnymore(); ioMotherLineageToDelete.push_back(Mother.GetMapValue("lineageID") ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::UpdateFormerDaughtersOfADeletedDivision( std::list iDaughtersID, std::list &ioTrackIDsNoLineage, bool &ioPartOfHigherLineage) { std::list::iterator iter = iDaughtersID.begin(); while (iter != iDaughtersID.end() ) { if (*iter != 0) { emit NeedToGetDatabaseConnection(); this->UpdateTrackFamilyIDForDaughter(this->m_DatabaseConnector, *iter, 0); if (this->IsTheTrackAMother(*iter, this->m_DatabaseConnector) ) { this->CreateALineageWithFormerDaughterOfADeletedDivision(*iter, this->m_DatabaseConnector, ioPartOfHigherLineage); } else { ioTrackIDsNoLineage.push_back(*iter); } } ++iter; } emit DBConnectionNotNeededAnymore(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::PrintAMessageForTracksWithNoDivision( std::list iTracksNoDivision) { if (!iTracksNoDivision.empty() ) { std::string Message = "Nothing has been done for these tracks "; std::list::iterator iter = iTracksNoDivision.begin(); while (iter != iTracksNoDivision.end() ) { Message += ConvertToString(*iter); Message += ", "; ++iter; } Message += "because they are not mothers of any divisions"; emit PrintMessage(Message.c_str()); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBTrackManager::IsTheTrackAMother(unsigned int iDaughterID, vtkMySQLDatabase* iDatabaseConnector) { GoDBTrackFamilyRow Family; Family.SetField("TrackIDMother", iDaughterID); int TrackFamilyID = Family.DoesThisTrackFamilyAlreadyExists(iDatabaseConnector); if (TrackFamilyID != -1) { return static_cast< unsigned int >( TrackFamilyID ); } return 0; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBTrackManager::IsTheTrackADaughter(unsigned int iTrackID, vtkMySQLDatabase* iDatabaseConnector) { GoDBTrackRow Track(iTrackID, iDatabaseConnector); return ss_atoi (Track.GetMapValue("TrackFamilyID") ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::CreateALineageWithFormerDaughterOfADeletedDivision( unsigned int iDaughterID, vtkMySQLDatabase* iDatabaseConnector, bool &ioPartOfHigherLineage) { //GoDBTrackRow Daughter(iDaughterID, iDatabaseConnector); std::list PreviousLineageToDelete = std::list(); if (!ioPartOfHigherLineage) //the lineage should not be deleted if higher tracks belong to it { GoDBTrackRow Daughter(iDaughterID, iDatabaseConnector); PreviousLineageToDelete.push_back( Daughter.GetMapValue("lineageID") ); //get the previous lineage ID of the daughter ioPartOfHigherLineage = true; // the second daughter will have a lineage set to 0 anyway } //get all the tracks daugthers of the DaughterID: std::list TracksIDs = this->m_TrackContainerInfoForVisu->GetSubLineage(iDaughterID); if (TracksIDs.size() > 1) { emit NewLineageToCreateFromTracks(TracksIDs, iDaughterID, PreviousLineageToDelete); //need to create a new lineage with //the family of the daughter } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoDBTrackManager::CheckMeshCanBeAddedToTrack( vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID, unsigned int iMeshTimePoint, std::list &ioMotherTrackDivisionToUpdate) { std::string Message = ""; unsigned int TrackMinTimePoint = this->m_CollectionOfTraces->GetBoundedBoxTimePoint(iDatabaseConnector, iTrackID, true); unsigned int TrackMaxTimePoint = this->m_CollectionOfTraces->GetBoundedBoxTimePoint(iDatabaseConnector, iTrackID, false); //if the mesh inside the bounding box of the track, no pb: if (iMeshTimePoint > TrackMinTimePoint && iMeshTimePoint < TrackMaxTimePoint) { return Message; } unsigned int DivisionIDTrackIsAMother = this->IsTheTrackAMother(iTrackID, iDatabaseConnector); unsigned int DivisionIDTrackIsADaughter = this->IsTheTrackADaughter(iTrackID, iDatabaseConnector); //if the track doesn't belong to any division, no pb: if (!DivisionIDTrackIsAMother && !DivisionIDTrackIsADaughter) { return Message; } if (DivisionIDTrackIsAMother) { if (iMeshTimePoint >= TrackMinTimePoint) { //check that the meshtimepoint < timepoint min daughter if not, message unsigned int DivisionToUpdate = this->CheckBoundingBoxDivisionAsAMother( iDatabaseConnector, iMeshTimePoint, DivisionIDTrackIsAMother ); if (DivisionToUpdate != 0) { ioMotherTrackDivisionToUpdate.push_back(DivisionToUpdate); } else { Message = "The mesh will not belong to any track as there is a problem with the division"; return Message; } } } if (DivisionIDTrackIsADaughter) { if (iMeshTimePoint > TrackMaxTimePoint) { return Message; } //check that the meshtimepoint > timepoint max mother if not, message unsigned int DivisionToUpdate = this->CheckBoundingBoxDivisionAsADaughter(iDatabaseConnector, iMeshTimePoint, DivisionIDTrackIsADaughter); if (DivisionToUpdate != 0) { ioMotherTrackDivisionToUpdate.push_back(DivisionToUpdate); } else { Message = "The mesh will not belong to any track as there is a problem with the division"; return Message; } } return Message; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBTrackManager::CheckBoundingBoxDivisionAsAMother( vtkMySQLDatabase* iDatabaseConnector, unsigned int iTimePoint, unsigned int iTrackFamilyID ) { if(iTrackFamilyID != 0) { GoDBTrackFamilyRow Division(iTrackFamilyID, iDatabaseConnector); if ( (iTimePoint < this->m_CollectionOfTraces->GetBoundedBoxTimePoint( iDatabaseConnector, Division.GetMapValue("TrackIDDaughter1") ) && (iTimePoint < this->m_CollectionOfTraces->GetBoundedBoxTimePoint( iDatabaseConnector, Division.GetMapValue("TrackIDDaughter2") ) ) ) ) { return Division.GetMapValue("TrackIDMother"); } return 0; } return 0; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBTrackManager::CheckBoundingBoxDivisionAsADaughter( vtkMySQLDatabase* iDatabaseConnector, unsigned int iTimePoint, unsigned int iTrackFamilyID ) { if (iTrackFamilyID != 0) { GoDBTrackFamilyRow Division(iTrackFamilyID, iDatabaseConnector); if ( iTimePoint > this->m_CollectionOfTraces->GetBoundedBoxTimePoint( iDatabaseConnector, Division.GetMapValue("TrackIDMother") ) ) { return Division.GetMapValue("TrackIDMother"); } return 0; } return 0; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list QGoDBTrackManager::GetDivisionIDsTheTrackBelongsTo( vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID ) { std::list Tracks; Tracks.push_back(iTrackID); std::list oDivisionIDs = this->m_CollectionOfTraces->GetTrackFamilyID( iDatabaseConnector, Tracks ); return oDivisionIDs; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::UpdateDivisions(const std::list & iListMotherTrackIDs) { std::list::const_iterator iter = iListMotherTrackIDs.begin(); while (iter != iListMotherTrackIDs.end() ) { this->m_TrackContainerInfoForVisu->CreateDivisionPolydata(*iter); ++iter; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager:: AddVolume(const unsigned int& iTrackID, const double& iVolume) { this->m_TrackContainerInfoForVisu->AddVolume(iTrackID, iVolume); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager:: AddVolumes(const std::list< std::pair > & iVolumes) { std::list< std::pair >::const_iterator it = iVolumes.begin(); while(it != iVolumes.end()) { this->m_TrackContainerInfoForVisu->AddVolume((*it).first, (*it).second); ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager:: RemoveVolumes(const std::list< std::pair > & iVolumes) { std::list< std::pair >::const_iterator it = iVolumes.begin(); while(it != iVolumes.end()) { this->m_TrackContainerInfoForVisu->AddVolume((*it).first, (-1)*((*it).second)); ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager:: AddVolumes(const std::list< std::pair > & iVolumes, unsigned int iTrackID) { std::list< std::pair >::const_iterator it = iVolumes.begin(); while(it != iVolumes.end()) { this->m_TrackContainerInfoForVisu->AddVolume(iTrackID, (*it).second); ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager:: RemoveVolumes(const std::list< std::pair > & iVolumes, unsigned int iTrackID) { std::list< std::pair >::const_iterator it = iVolumes.begin(); while(it != iVolumes.end()) { this->m_TrackContainerInfoForVisu->AddVolume(iTrackID, (-1)*((*it).second)); ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTrackManager::GoToTrackEnd() { // open db connection emit NeedToGetDatabaseConnection(); // make sure only one trace is checked std::list< unsigned int > ListCheckedTraces = this->GetListHighlightedIDs(); if ( ListCheckedTraces.size() != 1 ) { QMessageBox msgBox; msgBox.setText( tr("Please select one and only one %1 to go to") .arg( this->m_TraceName.c_str() ) ); msgBox.exec(); return; } //get last point of the trace from db std::stringstream points( this->m_CollectionOfTraces->GetPoints( this->m_DatabaseConnector, this->m_TraceName, ListCheckedTraces.front()) ); int numberOfPoints = 0; int count = 1; points >> numberOfPoints; if( numberOfPoints > 0) { // go to the last point double point = 0.0; while( count < numberOfPoints ) { points >> point; points >> point; points >> point; points >> point; ++count; } double x = 0; points >> x; double y = 0; points >> y; double z = 0; points >> z; double t = 0; points >> t; emit NeedToGoToTheRealLocation( x,y,z, static_cast(t) ); } // close db connection emit DBConnectionNotNeededAnymore(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ void QGoDBTrackManager::GoToTrackBegin() { // open db connection emit NeedToGetDatabaseConnection(); // make sure only one trace is checked std::list< unsigned int > ListCheckedTraces = this->GetListHighlightedIDs(); if ( ListCheckedTraces.size() != 1 ) { QMessageBox msgBox; msgBox.setText( tr("Please select one and only one %1 to go to") .arg( this->m_TraceName.c_str() ) ); msgBox.exec(); return; } //get last point of the trace from db std::stringstream points( this->m_CollectionOfTraces->GetPoints( this->m_DatabaseConnector, this->m_TraceName, ListCheckedTraces.front()) ); int numberOfPoints = 0; points >> numberOfPoints; if( numberOfPoints > 0) { double x = 0; points >> x; double y = 0; points >> y; double z = 0; points >> z; double t = 0; points >> t; // go to the last point of the track emit NeedToGoToTheRealLocation( x,y,z, static_cast(t) ); } // close db connection emit DBConnectionNotNeededAnymore(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ std::vector QGoDBTrackManager::GetTrackFamily(vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID) { return this->m_CollectionOfTraces->GetTrackFamily(iDatabaseConnector, iTrackID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------ bool QGoDBTrackManager::isMother(vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID) { return this->m_CollectionOfTraces->isMother(iDatabaseConnector, iTrackID); } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBCellTypeManager.cxx0000644000175000017500000000524211667757442023600 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBCellTypeManager.h" QGoDBCellTypeManager::QGoDBCellTypeManager (QWidget *iParent) : QGoDBNameDescEntityManager(iParent, "celltype", 0) { } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void QGoDBCellTypeManager::SaveNewEntityInDB() { if ( !this->CheckEntityAlreadyExists< GoDBCellTypeRow >(this->m_NewCellType) ) { this->m_NewCellType.SaveInDB(this->m_DatabaseConnector); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void QGoDBCellTypeManager::ValidateName(std::string iName, std::string iDescription) { this->ValidateNameTemplate< GoDBCellTypeRow >(this->m_NewCellType, iName, iDescription); }GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBMeshManager.h0000755000175000017500000003702211667757442022404 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBMeshManager_h #define __QGoDBMeshManager_h #include "QGoTableWidget.h" #include "GoDBCollectionOfTraces.h" #include "GoDBTWContainerForMesh.h" #include "QGoDBTraceManager.h" #include "GoDBMeshRow.h" #include "MeshContainer.h" #include "QGoGUILibConfigure.h" /** \class QGoDBMeshManager \brief This class manages the database queries, the table widget and the data from the database in the Container for visu for the meshes \ingroup DB, GUI */ class QGOGUILIB_EXPORT QGoDBMeshManager:public QGoDBTraceManager { Q_OBJECT public: QGoDBMeshManager(int iImgSessionID, QWidget *iparent); ~QGoDBMeshManager(); /** \brief set the m_MeshContainerInfoForVisu to the iContainerForVisu \param[in] iContainerForVisu common container for the visu and database */ void SetMeshesInfoContainerForVisu(MeshContainer *iContainerForVisu); /** \brief get all the data from the database to load all the meshes for the imagingsession into the table widget and the container for the visu \param[in] iDatabaseConnector connection to the database */ void DisplayInfoAndLoadVisuContainerForAllMeshes(vtkMySQLDatabase *iDatabaseConnector); void DisplayInfoAndLoadVisuContainerForAllMeshesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); void AddInfoInTWAndVisuContainerForMeshesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); void RemoveTracesFromTWAndContainerForVisuForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); virtual void DisplayInfoForLastCreatedTrace(vtkMySQLDatabase *iDatabaseConnector); void DisplayInfoForLastCreatedMesh(vtkMySQLDatabase *iDatabaseConnector, GoFigureMeshAttributes *iMeshAttributes); virtual void DisplayInfoForExistingTrace(vtkMySQLDatabase *iDatabaseConnector, int iTraceID); void DisplayInfoForExistingTraceForMesh(vtkMySQLDatabase *iDatabaseConnector, int iTraceID, GoFigureMeshAttributes *iMeshAttributes); /** \brief display in the TW the volume and area extracted from iMeshAttributes * called when loading all meshes from database when opening an imagingsession \param[in] iMeshAttributes computed values for a mesh \param[in] iMeshID meshID of the mesh we want to display the volume and area */ void DisplayOnlyVolumeAreaForExistingMesh(GoFigureMeshAttributes *iMeshAttributes, unsigned iMeshID); unsigned int CreateNewMeshWithNoContourNoPoints( vtkMySQLDatabase *iDatabaseConnector); unsigned int SaveNewMeshFromVisu(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, int iTShift, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, GoFigureMeshAttributes *iMeshAttributes); unsigned int SaveNewMeshFromVisu(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, int iTShift, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, GoFigureMeshAttributes *iMeshAttributes, unsigned int iTrackID); unsigned int SaveNewMeshWithNoTrackFromVisu(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, int iTShift, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, GoFigureMeshAttributes *iMeshAttributes); void SaveGeneratedMeshFromVisu(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, GoFigureMeshAttributes *iMeshAttributes); /** \brief virtual pure method in QGoDBTraceManager */ std::list< unsigned int > UpdateTheTracesColor(vtkMySQLDatabase *iDatabaseConnector); /** \brief update the bounding boxes for the meshes with no points */ void UpdateBoundingBoxes(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs); //virtual pure method in QGoDBTraceManager virtual void UpdateTWAndContainerForImportedTraces( const std::vector< int > & iVectorImportedTraces, vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual void DeleteCheckedTraces(vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual std::list< unsigned int > GetListHighlightedIDs(); /** \brief set the m_SelectedCelltype to iCelltype \param[in] iCellType name of the celltype */ void SetSelectedCellType(std::string* iCellType); /** \brief set the m_SelectedSubCelltype to iSubCelltype \param[in] iSubCellType name of the subcelltype */ void SetSelectedSubCellType(std::string* iSubCellType); /** \brief get the info needed from the database for the meshes who belongs to the collectionIDs contained in iListCollectionIDs and create a new container for visu for these meshes \param[in] iDatabaseConnector connection to the database \param[in] iListCollectionIDs list of collectionIDs of the meshes needed \return a container for meshes for the visu */ MeshContainer* GetMeshesInfoFromDBAndCreateContainerForVisu( vtkMySQLDatabase* iDatabaseConnector, const std::list< unsigned int > & iListCollectionIDs); //method in QGoDBTraceManager virtual std::list< NameWithColorData > GetAllTraceIDsWithColor( vtkMySQLDatabase *iDatabaseConnector, std::string & ioIDToSelect); /** * \brief Get volume of checked mesh IDs */ std::list< std::pair > GetListVolumes(); /** * \brief Get volume of given mesh IDs */ std::list< std::pair > GetListVolumes( const std::list & iMeshIDs); /** * \brief Get volume of given mesh ID */ double GetVolume(unsigned int iMeshID); void CleanTWAndContainerForGivenTimePoint(vtkMySQLDatabase *iDatabaseConnector, const std::list& iTimePoints); void ModifyTrackIDInVisuContainer(unsigned int iTrackID, const std::list< unsigned int > & iToTrack, const std::list< unsigned int > & iToNull); public slots: /** \brief get the coordinate info for meshes needed for the visu for imported tracks \param[in] iMeshesIDs list of meshes IDs the info are needed \return a map with IDs as keys and info as value */ std::map GetMeshesInfoForImportedMesh( std::list iMeshesIDs); /** \brief check in the database if there is an existing mesh belonging to iTrackID with iTimePoint, if yes, reassign the trackID to 0 and return the ID of the mesh with the new trackID set to 0. \param[in] iDatabaseConnector connection to the database \param[in] iTrackID ID of the track \param[in] iTimePoint timepoint to be checked \return meshID of the mesh on the same timepoint which trackID is reassigned to 0 */ unsigned int ReassignTrackIDForPreviousMeshWithSameTimePoint( vtkMySQLDatabase *iDatabaseConnector,unsigned int iTrackID, unsigned int iTimePoint); /** \brief if the track has already a mesh assigned for the current timepoint, the track of the previous mesh will be reassigned to 0 and a message will be displayed in the statusbar \param[in] iTrackID ID of the track to be checked \param[in] iDatabaseConnector connection to the database \param[in] iShift value to be added to the current timepoint \return a message to be print in the status bar of the mainwindow, if no meshes reassigned, the message will be "" */ QString CheckExistingMeshesForTheTrack( unsigned int iTrackID, vtkMySQLDatabase* iDatabaseConnector, int iTCoord);//int iShift = 0); /** \overload */ QString CheckExistingMeshesForTheTrack( unsigned int iTrackID,vtkMySQLDatabase* iDatabaseConnector, std::list & ioListMeshIDs, std::list< unsigned int > & ioNullListMeshIDs); /** \brief check if in the iListMeshIDs, several have the same timepoint, if so, return the list of meshIDs that need to be reassigned to 0 and modify the ioListMeshIDsToBePartOfTrack with only one meshid (the max one of several meshid for the same timepoint) per timepoint \param[in] iDatabaseConnector connection to the database \param[in] iListMeshIDs list of the meshIDs to be checked \param[in,out] ioListMeshIDsToBePartOfTrack list of meshIDs with only one per timepoint \param[in,out] ioListMeshIDsToReassign list of meshIDs that will not be part of the track \return message to be printed in the status bar with the list of meshIDs that won't be part of the selected trackid */ std::string CheckListMeshesFromDifferentTimePoints( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListMeshIDs, std::list & ioListMeshIDsToBePartOfTrack, std::list & ioListMeshIDsToReassign); /** \brief for the track, get the list of its meshes with a timepoint inferior than the checked mesh \param[in] iTrackID ID of the track \param[in] iDatabaseConnector connection to the database \param[in] iListMeshesBelongingToTrack list of the meshes belonging to this track \return list of the meshes with a timepoint inferior than the checked mesh */ std::list GetMeshesWithTimePointInfToTheCheckedOne( unsigned int iTrackID, vtkMySQLDatabase* iDatabaseConnector, std::list iListMeshesBelongingToTrack); protected: GoDBTWContainerForMesh *m_TWContainer; MeshContainer *m_MeshContainerInfoForVisu; std::string* m_SelectedCellType; std::string* m_SelectedSubCellType; //virtual pure method in QGoDBTraceManager virtual void SetCollectionsTraceNames(); void PrintValuesForMeshWithNoPoints(unsigned int iTraceID); virtual void AddActionsContextMenu(QMenu *iMenu); //virtual pure method in QGoDBTraceManager virtual void DisplayInfoForAllTraces(vtkMySQLDatabase *iDatabaseConnector); //virtual pure method in QGoDBTraceManager virtual void DisplayInfoForTracesForSpecificTPs(vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); void AddInfoForMeshesInTWForSpecificTPs(vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs); void SetMeshBoundingBoxAndPoints(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, GoDBMeshRow & iMesh, GoFigureMeshAttributes *iMeshAttributes, int iShift = 0); //virtual pure method in QGoDBTraceManager virtual void GetTracesInfoFromDBAndModifyContainerForVisu( vtkMySQLDatabase* iDatabaseConnector, std::list iVectIDs = std::list< unsigned int >()); /** \brief check that there is one and only one mesh checked belonging to the track and return its ID and its timepoint \param[in] iDatabaseConnector connection to the database \param[in] iTrackID ID of the track the mesh belongs to \return a pair with the meshID as first and the timepoint as second */ std::pair GetInfoForTheOnlyOneCheckedMeshOfTheTrack( vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID); protected slots: //virtual pure method in QGoDBTraceManager virtual void UpdateHighlightedElementsInVisuContainer(int iTraceID); //virtual pure method in QGoDBTraceManager virtual void UpdateVisibleElementsInVisuContainer(int iTraceID); //virtual pure method in QGoDBTraceManager virtual void SetColorCoding(bool IsChecked); /** \brief update the celltype of the checked meshes with the selected one */ void UpdateCellType(); /** \brief update the subcelltype of the checked meshes with the selected one */ void UpdateSubCellType(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBColorManager.h0000755000175000017500000000637711667757442022577 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBColorManager_h #define __QGoDBColorManager_h #include "QGoDBNameDescEntityManager.h" #include "GoDBColorRow.h" #include "QGoDeleteFromListDialog.h" /** \class QGoDBColorManager \brief the QGoDBColorManager manages the interactions between the user and the database for the color DBTable (add a new one, delete...). \ingroup DB GUI */ class QGoDBColorManager:public QGoDBNameDescEntityManager { Q_OBJECT public: explicit QGoDBColorManager (QWidget *iParent = 0); typedef QGoDeleteFromListDialog::ItemColorComboboxData ItemColorComboboxData; ~QGoDBColorManager(); /** \brief ask the user the color he wants, the name, description of the new color and saves it in the database. \return ItemColorComboboxData with the data for the new color saved or with the name of the color empty if the user canceled the "add new" */ ItemColorComboboxData AddANewColor(vtkMySQLDatabase *iDatabaseConnector); virtual bool DeleteEntity(vtkMySQLDatabase *iDatabaseConnector); /** \brief get the list of the existing colors from the database \return a list of pair with the name and the QColor of each color */ std::list< ItemColorComboboxData > GetListExistingColors( vtkMySQLDatabase *iDatabaseConnector); protected: GoDBColorRow m_NewColor; ItemColorComboboxData m_NewColorData; //mother class method virtual void SaveNewEntityInDB(); protected slots: //mother class method virtual void ValidateName(std::string iName, std::string iDescription); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBLineageManager.cxx0000644000175000017500000005466011667757442023433 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBLineageManager.h" #include "GoDBLineageRow.h" #include "GoDBTrackRow.h" #include "GoDBTrackFamilyRow.h" #include #include // directory for export #include #include //writer #include "vtkSmartPointer.h" #include "vtkTree.h" #include "vtkTreeWriter.h" #include "vtkMutableDirectedGraph.h" #include "vtkGraphLayoutView.h" #include "LineageStructure.h" QGoDBLineageManager::QGoDBLineageManager(int iImgSessionID, QWidget *iparent) : QGoDBTraceManager(), m_LineageContainerInfoForVisu(NULL), m_TrackContainerInfoForVisu(NULL) { this->SetInfo(iImgSessionID, iparent); this->m_TWContainer = new GoDBTWContainerForLineage(iImgSessionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoDBLineageManager::~QGoDBLineageManager() { if ( this->m_TWContainer ) { delete this->m_TWContainer; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::SetLineagesInfoContainersForVisu( LineageContainer *iContainerForVisu, TrackContainer *iTrackContainerInfoForVisu) { this->SetTracesInfoContainerForVisuTemplate< LineageContainer >( iContainerForVisu, &this->m_LineageContainerInfoForVisu); this->m_TrackContainerInfoForVisu = iTrackContainerInfoForVisu; // Connect signals // actor picking in visualization QObject::connect( m_TrackContainerInfoForVisu, SIGNAL(UpdateLineageHighlightingFromTrackRootID(unsigned int)), this, SLOT( UpdateElementHighlighting(unsigned int) ) ); // for a list of lineages QObject::connect( m_LineageContainerInfoForVisu, SIGNAL( HighlightLineage(const unsigned int&, const bool&) ), m_TrackContainerInfoForVisu, SLOT( HighlightCollection(const unsigned int&, const bool&) ) ); QObject::connect( m_LineageContainerInfoForVisu, SIGNAL( ShowLineage(const unsigned int&, const bool&) ), m_TrackContainerInfoForVisu, SLOT( ShowCollection(const unsigned int&, const bool&) ) ); // export lineage QObject::connect( m_LineageContainerInfoForVisu, SIGNAL( ExportLineages() ), this, SLOT( ExportLineages() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::SetCollectionsTraceNames() { this->m_TraceName = "lineage"; this->m_CollectionName = "None"; this->m_CollectionOf = "track"; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::DisplayInfoForAllTraces( vtkMySQLDatabase *iDatabaseConnector) { this->DisplayInfoForAllTracesTemplate< GoDBTWContainerForLineage >( this->m_TWContainer, iDatabaseConnector, Qt::Unchecked); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::DisplayInfoForTracesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { (void) iListTPs; this->DisplayInfoForAllTraces(iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::DisplayInfoAndLoadVisuContainerForAllLineages( vtkMySQLDatabase *iDatabaseConnector) { this->m_Table->setSortingEnabled(false); std::vector< int > VectorIDs = this->m_TWContainer->GetAllTraceIDsInContainer(); std::list ListIDs(VectorIDs.begin(), VectorIDs.end()); std::list list_of_traces = this->m_CollectionOfTraces->GetListStructureFromDB( iDatabaseConnector, this->m_ImgSessionID, ListIDs); this->m_Table->DisplayColumnNames( this->m_TWContainer->GetListColumnsNamesAndToolTipsForTableWidget() ); std::list::iterator it = list_of_traces.begin(); while ( it != list_of_traces.end() ) { LineageStructure Lineage = *it; GoFigureLineageAttributes Attributes = m_TrackContainerInfoForVisu->UpdateDivisionsForALineage( Lineage.TrackRootID, Lineage.rgba); this->m_LineageContainerInfoForVisu->Insert(*it); this->m_TWContainer->SetLineageAttributes(Attributes); this->InsertLineageInTW(iDatabaseConnector, Lineage.TraceID); ++it; } this->m_Table->setSortingEnabled(true); this->m_Table->resizeColumnsToContents(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::InsertLineageInTW(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTraceID) { TWContainerType RowContainer = this->m_TWContainer->GetContainerForOneSpecificTrace(iDatabaseConnector, iTraceID); // insert is buggy on sorted table // 1- unsort (if sorted) // 2- insert // 3- sort (if sorted) bool sorting = this->m_Table->isSortingEnabled(); if(sorting) { this->m_Table->setSortingEnabled(false); } this->m_Table->InsertOnlyOneNewRow(RowContainer, this->m_TWContainer->GetIndexForGroupColor(this->m_TraceName), this->m_TWContainer->GetIndexForGroupColor(this->m_CollectionName), this->m_TraceName, this->m_CollectionName, Qt::Unchecked); if(sorting) { this->m_Table->setSortingEnabled(true); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::DisplayInfoForLastCreatedTrace( vtkMySQLDatabase *iDatabaseConnector) { this->DisplayInfoForLastCreatedTraceTemplate< GoDBTWContainerForLineage >( this->m_TWContainer, iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::DisplayInfoForExistingTrace( vtkMySQLDatabase *iDatabaseConnector, int iTraceID) { this->DisplayInfoForExistingTraceTemplate< GoDBTWContainerForLineage >( this->m_TWContainer, iDatabaseConnector, iTraceID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBLineageManager::CreateNewLineageWithTrackRoot( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackRoot) { GoDBLineageRow NewLineage; unsigned int NewLineageID = this->m_CollectionOfTraces->CreateCollectionWithNoTracesNoPoints< GoDBLineageRow >( iDatabaseConnector, *this->m_SelectedColorData, NewLineage); this->UpdateTrackRootSelectedLineage(iDatabaseConnector, NewLineageID, iTrackRoot); // pointer to double has to be deleted after usage... double* color = this->GetVectorFromQColor(this->m_SelectedColorData->second); this->m_LineageContainerInfoForVisu->InsertNewLineage(NewLineageID, color , iTrackRoot, true); delete[] color; this->DisplayInfoForLastCreatedTrace(iDatabaseConnector); return NewLineageID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoDBLineageManager::UpdateTheTracesColor( vtkMySQLDatabase *iDatabaseConnector) { this->UpdateTheTracesColorTemplate< GoDBLineageRow, LineageContainer >(iDatabaseConnector, this->m_LineageContainerInfoForVisu); std::list< unsigned int > oList = this->GetListHighlightedIDs(); std::list< unsigned int >::iterator it = oList.begin(); while( it != oList.end() ) { // pointer to double has to be deleted after usage... double* color = this->GetVectorFromQColor(this->m_SelectedColorData->second); unsigned int trackRoot = this->m_LineageContainerInfoForVisu->GetLineageTrackRootID(*it); m_TrackContainerInfoForVisu->UpdateCollectionColorsData( trackRoot, color); delete[] color; ++it; } return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::UpdateTWAndContainerForImportedTraces( const std::vector< int > & iVectorImportedTraces, vtkMySQLDatabase *iDatabaseConnector) { //this->UpdateTWAndContainerWithImportedTracesTemplate< // GoDBTWContainerForLineage >(this->m_TWContainer, // iVectorImportedTraces, iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::DeleteCheckedTraces(vtkMySQLDatabase *iDatabaseConnector) { this->DeleteListTraces(iDatabaseConnector, this->GetListHighlightedIDs() ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager:: DeleteListTraces(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTraces) { //delete the lineages from the visu, the database and the TW: this->DeleteTracesTemplate< LineageContainer >(iDatabaseConnector, this->m_LineageContainerInfoForVisu, iListTraces, false); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoDBLineageManager::GetListHighlightedIDs() { return this->m_LineageContainerInfoForVisu->GetHighlightedElementsTraceID(); } //------------------------------------------------------------------------- // From table widget //------------------------------------------------------------------------- void QGoDBLineageManager::UpdateHighlightedElementsInVisuContainer( int iTraceID) { // update lineage container element (invert highlighted boolean) this->m_LineageContainerInfoForVisu-> UpdateElementHighlightingWithGivenTraceID(iTraceID); //get root track id unsigned int trackRootID = this->m_LineageContainerInfoForVisu-> GetLineageTrackRootID(iTraceID); // is the lineage highlighted? bool highlighted = this->m_LineageContainerInfoForVisu-> GetLineageHighlighted(iTraceID); // update divisions this->m_TrackContainerInfoForVisu->HighlightCollection(trackRootID, highlighted); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::UpdateVisibleElementsInVisuContainer(int iTraceID) { // update container element (invert visible bool) this->m_LineageContainerInfoForVisu-> UpdateElementVisibilityWithGivenTraceID(iTraceID); //get root track id unsigned int trackRootID = this->m_LineageContainerInfoForVisu-> GetLineageTrackRootID(iTraceID); // is the lineage visible? bool visible = this->m_LineageContainerInfoForVisu-> GetLineageVisibile(iTraceID); // update divisions this->m_TrackContainerInfoForVisu->ShowCollection(trackRootID, visible); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::GetTracesInfoFromDBAndModifyContainerForVisu( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs) { std::list list_of_traces = this->m_CollectionOfTraces->GetListStructureFromDB( iDatabaseConnector, this->m_ImgSessionID, iListTraceIDs); std::list::iterator it = list_of_traces.begin(); while ( it != list_of_traces.end() ) { LineageStructure Lineage = *it; m_TrackContainerInfoForVisu->UpdateDivisionsForALineage( Lineage.TrackRootID, Lineage.rgba); this->m_LineageContainerInfoForVisu->Insert(*it); ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::SetColorCoding(bool IsChecked) { std::string ColumnName = ""; std::map Values; std::map NewValues; m_IsColorCodingOn = IsChecked; //create map track ID/field if (IsChecked) { Values = this->m_Table->GetTraceIDAndColumnsValues( this->m_TraceNameID, ColumnName); // change lineage id by track root id std::map::iterator trackRootIt = Values.begin(); while(trackRootIt != Values.end()) { unsigned int trackRoot = m_LineageContainerInfoForVisu->GetLineageTrackRootID(trackRootIt->first); NewValues.insert( std::pair(trackRoot, trackRootIt->second) ); ++trackRootIt; } vtkLookupTable* LUT = NULL; bool IsRandomIncluded = (ColumnName == this->m_TraceNameID) || (ColumnName == this->m_CollectionNameID); QGoColorCodingDialog::ColorWay UserColorway = QGoColorCodingDialog::GetColorWay( this->m_TraceName, &LUT, IsRandomIncluded, this->m_Table ); switch ( UserColorway ) { case QGoColorCodingDialog::Default: m_TrackContainerInfoForVisu->SetCollectionColorCode( ColumnName,NewValues ); break; case QGoColorCodingDialog::Random: m_TrackContainerInfoForVisu->SetDivisionRandomColor(ColumnName,NewValues ); break; case QGoColorCodingDialog::LUT: m_TrackContainerInfoForVisu->SetCollectionColorCode( ColumnName,NewValues ); m_TrackContainerInfoForVisu->SetLookupTableForAllDivisionsColorCoding(LUT); break; default: case QGoColorCodingDialog::Nothing: m_IsColorCodingOn = !IsChecked; break; } } else { m_TrackContainerInfoForVisu->SetCollectionColorCode( ColumnName, NewValues ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::UpdateTrackRootSelectedLineage( vtkMySQLDatabase* iDatabaseConnector, unsigned int iLineageID, unsigned int iTrackIDRoot) { GoDBLineageRow LastLineage; LastLineage.SetValuesForSpecificID(iLineageID, iDatabaseConnector); LastLineage.SetField("TrackIDRoot", iTrackIDRoot); LastLineage.SaveInDB(iDatabaseConnector); } //------------------------------------------------------------------------- // actor picking //------------------------------------------------------------------------- void QGoDBLineageManager:: UpdateElementHighlighting(unsigned int iTraceRootID) { unsigned int lineageID = this->m_LineageContainerInfoForVisu->GetTraceIDFromTrackRootID( iTraceRootID); this->m_LineageContainerInfoForVisu->UpdateElementHighlighting(lineageID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager:: ExportLineages() { //get path to export somewhere QString dir = QFileDialog::getExistingDirectory(NULL, tr("Choose Directory")); //get lineages info std::list rootIDs = this->m_LineageContainerInfoForVisu->GetListOfTrackRootIDs(); std::list lineageIDs = this->m_LineageContainerInfoForVisu->GetListOfLineageIDs(); std::list::iterator itLineage = lineageIDs.begin(); std::list::iterator itTrack = rootIDs.begin(); // export all the lineages while(itLineage != lineageIDs.end() ) { vtkMutableDirectedGraph* graph = m_TrackContainerInfoForVisu->ExportLineage(*itTrack); vtkSmartPointer tree = vtkSmartPointer::New(); tree->CheckedDeepCopy(graph); //save tree vtkSmartPointer writer = vtkSmartPointer::New(); writer->SetInput(tree); QString name(dir); name.append("/lineage_"); name.append( QString::number(*itLineage, 10) ); name.append(".vtk"); writer->SetFileName(name.toLocal8Bit().data()); writer->Write(); graph->Delete(); ++itLineage; ++itTrack; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager:: UpdateBoundingBoxes(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs, bool UpdateTW) { this->m_CollectionOfTraces->RecalculateDBBoundingBox( iDatabaseConnector, iListTracesIDs); std::list::const_iterator iter = iListTracesIDs.begin(); while(iter != iListTracesIDs.end() ) { std::list Listiter; Listiter.push_back(*iter); //need to check first that the lineage does exist, which corresponds to check if there are tracks that have this lineageid: if (!this->m_CollectionOfTraces->GetListTracesIDsFromThisCollectionOf(iDatabaseConnector, Listiter).empty()) { this->UpdateDivisionsInTrackContainer(*iter); if ( UpdateTW ) { this->DisplayInfoForExistingTrace(iDatabaseConnector, *iter); } } ++iter; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::UpdateDivisionsInTrackContainer(unsigned int iLineageID) { unsigned int root = this->m_LineageContainerInfoForVisu->GetLineageTrackRootID(iLineageID); double* color = this->m_LineageContainerInfoForVisu->GetLineageColor(iLineageID); GoFigureLineageAttributes Attributes; if(color) { Attributes = m_TrackContainerInfoForVisu->UpdateDivisionsForALineage(root, color); } else { Attributes = m_TrackContainerInfoForVisu->UpdateCollectionScalars( root ); } this->m_TWContainer->SetLineageAttributes(Attributes); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::DeleteTracesFromContextMenu() { std::list ListLineagesToDelete = this->GetListHighlightedIDs(); if ( QGoDBTraceManager::CheckThatThereAreTracesToDelete(ListLineagesToDelete) ) { emit NeedToGetDatabaseConnection(); this->DeleteDivisionsForLineages( this->m_DatabaseConnector, ListLineagesToDelete ); DBConnectionNotNeededAnymore(); emit CheckedTracesToDelete(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::DeleteDivisionsForLineages( vtkMySQLDatabase *iDatabaseConnector, const std::list & iLineagesID) { std::list TrackFamiliesToDelete = this->m_CollectionOfTraces->GetTrackFamiliesForLineages(iDatabaseConnector, iLineagesID); std::list::iterator iter = TrackFamiliesToDelete.begin(); while(iter != TrackFamiliesToDelete.end() ) { if (*iter != 0) { this->DeleteADivision(iDatabaseConnector, *iter); } ++iter; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBLineageManager::DeleteADivision( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackFamilyID) { GoDBTrackFamilyRow TrackFamily(iTrackFamilyID, iDatabaseConnector); //update the trackfamilyID of the daughter: GoDBTrackRow Daughter(TrackFamily.GetMapValue("TrackIDDaughter1"), iDatabaseConnector); Daughter.SetField("TrackFamilyID", 0); Daughter.SaveInDB(iDatabaseConnector); Daughter.SetValuesForSpecificID(TrackFamily.GetMapValue("TrackIDDaughter2"), iDatabaseConnector); Daughter.SetField("TrackFamilyID", 0); Daughter.SaveInDB(iDatabaseConnector); //delete the division in the visu this->m_TrackContainerInfoForVisu->DeleteADivision( TrackFamily.GetMapValue("TrackIDMother") ); //delete the division from the database: TrackFamily.DeleteFromDB(iDatabaseConnector); } GoFigure2-v0.9.0/Code/GUI/lib/DBManager/QGoDBMeshManager.cxx0000644000175000017500000011417711667757442022763 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBMeshManager.h" #include "GoDBMeshRow.h" #include #include QGoDBMeshManager::QGoDBMeshManager(int iImgSessionID, QWidget *iparent) : QGoDBTraceManager(), m_MeshContainerInfoForVisu(NULL), m_SelectedCellType(NULL), m_SelectedSubCellType(NULL) { this->SetInfo(iImgSessionID, iparent); this->m_TWContainer = new GoDBTWContainerForMesh(iImgSessionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoDBMeshManager::~QGoDBMeshManager() { if ( this->m_TWContainer ) { delete this->m_TWContainer; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::SetMeshesInfoContainerForVisu( MeshContainer *iContainerForVisu) { this->SetTracesInfoContainerForVisuTemplate< MeshContainer >( iContainerForVisu, &this->m_MeshContainerInfoForVisu); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::SetCollectionsTraceNames() { this->m_TraceName = "mesh"; this->m_CollectionName = "track"; this->m_CollectionOf = "contour"; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::DisplayInfoAndLoadVisuContainerForAllMeshes( vtkMySQLDatabase *iDatabaseConnector) { this->DisplayInfoAndLoadVisuContainerWithAllTraces< GoDBTWContainerForMesh >(this->m_TWContainer, iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::DisplayInfoAndLoadVisuContainerForAllMeshesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { this->DisplayInfoAndLoadVisuContainerWithAllTracesForSpecificTPs< ContourMeshContainer > (iDatabaseConnector, this->m_MeshContainerInfoForVisu, iListTPs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::AddInfoInTWAndVisuContainerForMeshesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { //this->AddInfoInTWAndContainerForVisuForSpecificTPs< ContourMeshContainer > // (iDatabaseConnector, this->m_ContourContainerInfoForVisu, iListTPs); this->AddInfoForMeshesInTWForSpecificTPs(iDatabaseConnector, iListTPs); std::list ListIDs = this->m_CollectionOfTraces->GetTraceIDsBelongingToListTimePoints( iDatabaseConnector, iListTPs); std::list list_of_traces = this->m_CollectionOfTraces-> GetListStructureFromDB( iDatabaseConnector, this->m_ImgSessionID, ListIDs); /** \todo Nico: implement a method that get list_of_traces as argument and as this list of structure in the container for visu */ } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::AddInfoForMeshesInTWForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { //int IndexShowColumn = this->m_TWContainer->GetIndexShowColumn(); /*this->AddInfoForTracesInTWForSpecificTPsTemplate( this->m_TWContainer, iDatabaseConnector, Qt::Unchecked, IndexShowColumn );*/ //load the container with the traces infos for the TW for the TimePoints contained //in iListTPs: TWContainerType RowContainer = this->m_TWContainer->GetContainerLoadedWithAllFromDB(iDatabaseConnector, iListTPs); this->m_Table->InsertNewRows(RowContainer, this->m_TWContainer->GetIndexForGroupColor(this->m_TraceName), this->m_TWContainer->GetIndexForGroupColor(this->m_CollectionName), this->m_TraceName, this->m_CollectionName, Qt::Unchecked); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::DisplayInfoForAllTraces( vtkMySQLDatabase *iDatabaseConnector) { int IndexShowColumn = this->m_TWContainer->GetIndexShowColumn(); this->DisplayInfoForAllTracesTemplate< GoDBTWContainerForMesh >( this->m_TWContainer, iDatabaseConnector, Qt::Unchecked, IndexShowColumn); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager:: DisplayInfoForTracesForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { int IndexShowColumn = this->m_TWContainer->GetIndexShowColumn(); this->DisplayInfoForTracesForSpecificTPsTemplate( this->m_TWContainer, iDatabaseConnector, Qt::Unchecked, iListTPs, IndexShowColumn); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager:: RemoveTracesFromTWAndContainerForVisuForSpecificTPs( vtkMySQLDatabase *iDatabaseConnector, const std::list & iListTPs) { this->RemoveTracesFromTWAndContainerForVisuForSpecificTPsTemplate< ContourMeshContainer > (iDatabaseConnector, this->m_MeshContainerInfoForVisu, iListTPs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::DisplayInfoForLastCreatedTrace( vtkMySQLDatabase *iDatabaseConnector) { this->DisplayInfoForLastCreatedTraceTemplate< GoDBTWContainerForMesh >( this->m_TWContainer, iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::DisplayOnlyVolumeAreaForExistingMesh( GoFigureMeshAttributes *iMeshAttributes, unsigned iMeshID) { if ( iMeshAttributes != 0 ) { std::vector< std::string > ColumnNames (2); std::vector< std::string > Values (2); ColumnNames.at(0) = "SurfaceArea"; Values.at(0) = ConvertToString< double >(iMeshAttributes->m_Area); ColumnNames.at(1) = "Volume"; Values.at(1) = ConvertToString< double >(iMeshAttributes->m_Volume); this->m_Table->AddValuesForID(ColumnNames, Values, iMeshID, "meshID"); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::DisplayInfoForLastCreatedMesh( vtkMySQLDatabase *iDatabaseConnector, GoFigureMeshAttributes *iMeshAttributes) { this->m_TWContainer->SetMeshAttributes(iMeshAttributes); this->DisplayInfoForLastCreatedTrace(iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::DisplayInfoForExistingTrace( vtkMySQLDatabase *iDatabaseConnector, int iTraceID) { this->DisplayInfoForExistingTraceTemplate< GoDBTWContainerForMesh >( this->m_TWContainer, iDatabaseConnector, iTraceID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::DisplayInfoForExistingTraceForMesh( vtkMySQLDatabase *iDatabaseConnector, int iTraceID, GoFigureMeshAttributes *iMeshAttributes) { this->m_TWContainer->SetMeshAttributes(iMeshAttributes); this->DisplayInfoForExistingTrace(iDatabaseConnector, iTraceID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::AddActionsContextMenu(QMenu *iMenu) { QGoDBTraceManager::AddActionsContextMenu(iMenu); this->AddSpecificActionsForContourMesh(iMenu); this->m_CheckedTracesMenu->addAction( tr("Add the selected CellType '%1' to the checked meshes") .arg( this->m_SelectedCellType->c_str() ), this, SLOT( UpdateCellType() ) ); this->m_CheckedTracesMenu->addAction( tr("Add the selected SubCellType '%1' to the checked meshes") .arg( this->m_SelectedSubCellType->c_str() ), this, SLOT( UpdateSubCellType() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBMeshManager::SaveNewMeshFromVisu( unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, int iTCoord,//int iTShift, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, GoFigureMeshAttributes *iMeshAttributes, unsigned int iTrackID) { GoDBMeshRow NewMesh(this->m_ImgSessionID); NewMesh.SetCellType(iDatabaseConnector, *this->m_SelectedCellType); NewMesh.SetSubCellType(iDatabaseConnector, *this->m_SelectedSubCellType); this->SetMeshBoundingBoxAndPoints(iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, iTraceNodes, iDatabaseConnector, NewMesh, iMeshAttributes, iTCoord); //save the intensities for each channel !!! unsigned int NewMeshID = this->m_CollectionOfTraces->CreateNewTraceInDB< GoDBMeshRow >( NewMesh, iDatabaseConnector, *this->m_SelectedColorData, iTrackID ); // pointer to double has to be deleted after usage... double *rgba = this->GetVectorFromQColor(this->m_SelectedColorData->second); this->m_MeshContainerInfoForVisu->UpdateCurrentElementFromDB( NewMeshID, rgba); this->m_MeshContainerInfoForVisu->UpdateCurrentElementCollection(iTrackID); delete[] rgba; this->DisplayInfoForLastCreatedMesh(iDatabaseConnector, iMeshAttributes); return NewMeshID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBMeshManager::SaveNewMeshFromVisu( unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, int iTCoord, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, GoFigureMeshAttributes *iMeshAttributes) { return SaveNewMeshFromVisu(iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, iTCoord, iTraceNodes, iDatabaseConnector, iMeshAttributes, ss_atoi(this->m_SelectedCollectionData->first) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBMeshManager::SaveNewMeshWithNoTrackFromVisu( unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, int iTShift, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, GoFigureMeshAttributes *iMeshAttributes) { return SaveNewMeshFromVisu(iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, iTShift, iTraceNodes, iDatabaseConnector, iMeshAttributes, 0 ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::SaveGeneratedMeshFromVisu(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, GoFigureMeshAttributes *iMeshAttributes) { unsigned int TraceID = this->m_MeshContainerInfoForVisu->m_CurrentElement.TraceID; GoDBMeshRow GeneratedMesh; GeneratedMesh.SetValuesForSpecificID(TraceID, iDatabaseConnector); this->SetMeshBoundingBoxAndPoints(iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, iTraceNodes, iDatabaseConnector, GeneratedMesh, iMeshAttributes); //save the intensity for each channel !!! GeneratedMesh.SaveInDB(iDatabaseConnector); this->DisplayInfoForExistingTraceForMesh(iDatabaseConnector, TraceID, iMeshAttributes); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBMeshManager::CreateNewMeshWithNoContourNoPoints( vtkMySQLDatabase *iDatabaseConnector) { GoDBMeshRow NewMesh; NewMesh.SetCellType(iDatabaseConnector, *this->m_SelectedCellType); NewMesh.SetSubCellType(iDatabaseConnector, *this->m_SelectedSubCellType); //unsigned int TrackID = 0; // if( this->m_SelectedCollectionData->first != "Add a new mesh ..." // && this->m_SelectedCollectionData->first != "Add a new track ...") // { // TrackID = ss_atoi(this->m_SelectedCollectionData->first); // } // if ( TrackID != 0 ) // { //NewMesh.SetCollectionID(TrackID); // } NewMesh.SetCollectionID( ss_atoi< unsigned int >(this->m_SelectedCollectionData->first) ); unsigned int NewMeshID = this->m_CollectionOfTraces->CreateCollectionWithNoTracesNoPoints< GoDBMeshRow >( iDatabaseConnector, *this->m_SelectedColorData, NewMesh, *this->m_CurrentTimePoint); // pointer to double has to be deleted after usage... double *color = this->GetVectorFromQColor(this->m_SelectedColorData->second); this->m_MeshContainerInfoForVisu->ResetCurrentElement(); this->m_MeshContainerInfoForVisu->UpdateCurrentElementFromDB( NewMeshID, color); delete[] color; this->m_MeshContainerInfoForVisu->InsertCurrentElement(); this->DisplayInfoForLastCreatedTrace(iDatabaseConnector); NameWithColorData NewMeshData(ConvertToString< unsigned int >(NewMeshID), this->m_SelectedColorData->second); emit AddNewTraceIDInTS(NewMeshData); return NewMeshID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoDBMeshManager::UpdateTheTracesColor( vtkMySQLDatabase *iDatabaseConnector) { return this->UpdateTheTracesColorTemplate< GoDBMeshRow, ContourMeshContainer >( iDatabaseConnector, this->m_MeshContainerInfoForVisu); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager:: UpdateBoundingBoxes(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListTracesIDs) { std::list< unsigned int > ListMeshesWithNoPoints = this->m_CollectionOfTraces->GetListTracesIDWithNoPoints( iListTracesIDs, iDatabaseConnector); if ( !ListMeshesWithNoPoints.empty() ) { QGoDBTraceManager::UpdateBoundingBoxes(iDatabaseConnector, ListMeshesWithNoPoints); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::SetMeshBoundingBoxAndPoints(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, GoDBMeshRow & iMesh, GoFigureMeshAttributes *iMeshAttributes, int iTCoord) //int iShift) { GoDBCoordinateRow coord_min = this->GetCoordinateFromInt(iXCoordMin, iYCoordMin, iZCoordMin, iTCoord);//*this->m_CurrentTimePoint + iShift); GoDBCoordinateRow coord_max = this->GetCoordinateFromInt(iXCoordMax, iYCoordMax, iZCoordMax, iTCoord);//*this->m_CurrentTimePoint + +iShift); iMesh.SetTheDataFromTheVisu(iDatabaseConnector, iTraceNodes, coord_min, coord_max, iMeshAttributes); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::UpdateTWAndContainerForImportedTraces( const std::vector< int > & iVectorImportedTraces, vtkMySQLDatabase *iDatabaseConnector) { this->UpdateTWAndContainerWithImportedTracesTemplate< GoDBTWContainerForMesh >(this->m_TWContainer, iVectorImportedTraces, iDatabaseConnector); //update the visualization and the data from visu in the container for visu: this->m_MeshContainerInfoForVisu-> UpdateVisualizationForGivenIDs< std::vector< int > >( iVectorImportedTraces); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::DeleteCheckedTraces(vtkMySQLDatabase *iDatabaseConnector) { this->DeleteTracesTemplate< ContourMeshContainer >(iDatabaseConnector, this->m_MeshContainerInfoForVisu); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoDBMeshManager::GetListHighlightedIDs() { return this->m_MeshContainerInfoForVisu->GetHighlightedElementsTraceID(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::UpdateHighlightedElementsInVisuContainer( int iTraceID) { this->m_MeshContainerInfoForVisu-> UpdateElementHighlightingWithGivenTraceID(iTraceID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::UpdateVisibleElementsInVisuContainer(int iTraceID) { this->m_MeshContainerInfoForVisu-> UpdateElementVisibilityWithGivenTraceID(iTraceID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::GetTracesInfoFromDBAndModifyContainerForVisu( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs) { this->GetTracesInfoFromDBAndModifyContainerForVisuTemplate< MeshContainer >( this->m_MeshContainerInfoForVisu, iDatabaseConnector, iListTraceIDs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- MeshContainer * QGoDBMeshManager::GetMeshesInfoFromDBAndCreateContainerForVisu( vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > & iListCollectionIDs) { std::list< unsigned int > ListMeshesInvolved = this->GetListTracesIDsBelongingToCollectionIDs(iDatabaseConnector, iListCollectionIDs); MeshContainer * oMeshContainer = new MeshContainer(this, NULL); std::list< ContourMeshStructure > ListMeshesInfo = this->m_CollectionOfTraces->GetListStructureFromDB< ContourMeshStructure >( iDatabaseConnector, this->m_ImgSessionID, ListMeshesInvolved); std::list< ContourMeshStructure >::iterator it = ListMeshesInfo.begin(); while ( it != ListMeshesInfo.end() ) { oMeshContainer->Insert(*it); ++it; } return oMeshContainer; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::map< unsigned int, double * > QGoDBMeshManager::GetMeshesInfoForImportedMesh( std::list< unsigned int > iMeshesIDs) { return this->m_MeshContainerInfoForVisu->GetMeshesPoints(iMeshesIDs); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::SetColorCoding(bool IsChecked) { this->SetColorCodingTemplate< ContourMeshContainer >( this->m_MeshContainerInfoForVisu, IsChecked); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::SetSelectedCellType(std::string *iCellType) { this->m_SelectedCellType = iCellType; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::SetSelectedSubCellType(std::string *iSubCellType) { this->m_SelectedSubCellType = iSubCellType; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::UpdateCellType() { emit NeedToGetDatabaseConnection(); std::list< unsigned int > ListCheckedMeshes = this->m_MeshContainerInfoForVisu->GetHighlightedElementsTraceID(); int CellTypeID = GoDBMeshRow::GetCellTypeID(this->m_DatabaseConnector, *this->m_SelectedCellType); this->m_CollectionOfTraces->UpdateValueForListTraces( this->m_DatabaseConnector, "CellTypeID", ConvertToString< int >(CellTypeID), ListCheckedMeshes); this->DisplayInfoForExistingTraces(this->m_DatabaseConnector, ListCheckedMeshes); emit DBConnectionNotNeededAnymore(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager::UpdateSubCellType() { emit NeedToGetDatabaseConnection(); std::list< unsigned int > ListCheckedMeshes = this->m_MeshContainerInfoForVisu->GetHighlightedElementsTraceID(); int SubCellTypeID = GoDBMeshRow::GetSubCellTypeID(this->m_DatabaseConnector, *this->m_SelectedSubCellType); this->m_CollectionOfTraces->UpdateValueForListTraces( this->m_DatabaseConnector, "SubCellularID", ConvertToString< int >(SubCellTypeID), ListCheckedMeshes); this->DisplayInfoForExistingTraces(this->m_DatabaseConnector, ListCheckedMeshes); emit DBConnectionNotNeededAnymore(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoDBMeshManager::ReassignTrackIDForPreviousMeshWithSameTimePoint(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID, unsigned int iTimePoint) { unsigned int oExistingMeshID = 0; //get meshID with same timepoint and same TrackID: std::list< unsigned int > ExistingMeshID = this->m_CollectionOfTraces->GetTraceIDsWithTimePointAndCollectionID( iDatabaseConnector, iTrackID, iTimePoint); if ( ExistingMeshID.empty() ) { return oExistingMeshID; } if ( ExistingMeshID.size() > 1 ) { std::cout << "there is more than 1 existing mesh for this track at this timepoint "; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return oExistingMeshID; } oExistingMeshID = ExistingMeshID.front(); GoDBMeshRow ExistingMesh(oExistingMeshID, iDatabaseConnector); // modify table widget and DB ExistingMesh.SetCollectionID(0); ExistingMesh.SaveInDB(iDatabaseConnector); // modify visu container as well m_MeshContainerInfoForVisu->AssignToGivenCollection(0, ExistingMeshID); this->DisplayInfoForExistingTrace(iDatabaseConnector, oExistingMeshID); //update // the // TW return oExistingMeshID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoDBMeshManager::CheckExistingMeshesForTheTrack( unsigned int iTrackID, vtkMySQLDatabase *iDatabaseConnector, int iTCoord) { QString MessageToPrint(""); if ( iTrackID != 0 ) //if the user has not created a track yet { unsigned int MeshIDKickedOut = this->ReassignTrackIDForPreviousMeshWithSameTimePoint( iDatabaseConnector, iTrackID, iTCoord); if ( MeshIDKickedOut != 0 ) { MessageToPrint = QString::number(MeshIDKickedOut); } } return MessageToPrint; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoDBMeshManager::CheckExistingMeshesForTheTrack( unsigned int iTrackID, vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > & ioListMeshIDs, std::list< unsigned int > & ioNullListMeshIDs) { QString MessageQString(""); if ( iTrackID != 0 ) { std::string MessageToPrint = ""; std::list< unsigned int > ListTimePoints = this->m_CollectionOfTraces->GetListTimePointsFromTraceIDs(iDatabaseConnector, ioListMeshIDs); if ( !ListTimePoints.empty() ) { std::string MeshIDToPrint = ""; std::list< unsigned int >::iterator iter = ListTimePoints.begin(); while ( iter != ListTimePoints.end() ) { unsigned int MeshIDKickedOut = this->ReassignTrackIDForPreviousMeshWithSameTimePoint( iDatabaseConnector, iTrackID, *iter); if ( MeshIDKickedOut != 0 ) { ioNullListMeshIDs.push_back(MeshIDKickedOut); MeshIDToPrint += ConvertToString< unsigned int >(MeshIDKickedOut); MeshIDToPrint += ", "; } ++iter; } if ( !MeshIDToPrint.empty() ) { MeshIDToPrint = MeshIDToPrint.substr(0, MeshIDToPrint.size() - 2); MessageToPrint += "The trackID of the meshes "; MessageToPrint += MeshIDToPrint; MessageToPrint += " have been reassigned to 0"; } } MessageQString = MessageToPrint.c_str(); } return MessageQString; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoDBMeshManager::CheckListMeshesFromDifferentTimePoints( vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListMeshIDs, std::list< unsigned int > & ioListMeshIDsToBePartOfTrack, std::list< unsigned int > & ioListMeshIDsToReassign) { std::string MessageToPrint = ""; ioListMeshIDsToBePartOfTrack = iListMeshIDs; std::list< unsigned int >::iterator iter; if ( !iListMeshIDs.empty() ) { std::list< unsigned int > TimePointsWithSeveralMeshes = this->m_CollectionOfTraces->GetTimePointWithSeveralTracesFromTheList( iDatabaseConnector, iListMeshIDs); iter = TimePointsWithSeveralMeshes.begin(); while ( iter != TimePointsWithSeveralMeshes.end() ) { int MaxMeshIDForTimePoint = this->m_CollectionOfTraces->GetMaxTraceIDsForSpecificTimePoint( iDatabaseConnector, iListMeshIDs, *iter); if ( MaxMeshIDForTimePoint != -1 ) { std::list< unsigned int > TraceIDs = this->m_CollectionOfTraces->GetNonMaxTraceIDsForSpecificTimePoint( iDatabaseConnector, iListMeshIDs, *iter, MaxMeshIDForTimePoint); std::copy( TraceIDs.begin(), TraceIDs.end(), std::back_inserter(ioListMeshIDsToReassign) ); std::list< unsigned int >::iterator iterTraceIDToRemove = TraceIDs.begin(); while ( iterTraceIDToRemove != TraceIDs.end() ) { std::list< unsigned int >::iterator Find = std::find(ioListMeshIDsToBePartOfTrack.begin(), ioListMeshIDsToBePartOfTrack.end(), *iterTraceIDToRemove); ioListMeshIDsToBePartOfTrack.erase(Find); ++iterTraceIDToRemove; } } ++iter; } if ( !ioListMeshIDsToReassign.empty() ) { MessageToPrint = "Warning: the meshIDs "; std::list< unsigned int >::iterator iterIDs = ioListMeshIDsToReassign.begin(); while ( iterIDs != ioListMeshIDsToReassign.end() ) { std::string temp = ConvertToString< unsigned int >(*iterIDs); MessageToPrint += temp; MessageToPrint += ", "; ++iterIDs; } MessageToPrint = MessageToPrint.substr(0, MessageToPrint.size() - 1); MessageToPrint += "have not been reassigned "; MessageToPrint += "to the trackID because several meshes were selected for the same "; MessageToPrint += "timepoints "; iter = TimePointsWithSeveralMeshes.begin(); while ( iter != TimePointsWithSeveralMeshes.end() ) { std::string temp = ConvertToString< unsigned int >(*iter); MessageToPrint += temp; MessageToPrint += ", "; ++iter; } MessageToPrint = MessageToPrint.substr(0, MessageToPrint.size() - 2); } } return MessageToPrint; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > QGoDBMeshManager::GetMeshesWithTimePointInfToTheCheckedOne( unsigned int iTrackID, vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListMeshesBelongingToTrack) { std::list< unsigned int > oListMeshesTimePointInf = std::list< unsigned int >(); std::pair< unsigned int, unsigned int > InfoSplitMesh = this->GetInfoForTheOnlyOneCheckedMeshOfTheTrack(iDatabaseConnector, iTrackID); if ( InfoSplitMesh.first != 0 ) { oListMeshesTimePointInf = this->m_CollectionOfTraces->GetTraceIDsWithTimePointInf( iDatabaseConnector, iListMeshesBelongingToTrack, InfoSplitMesh.second); //oListMeshesTimePointSup.push_back(InfoSplitMesh.first); } return oListMeshesTimePointInf; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::pair< unsigned int, unsigned int > QGoDBMeshManager::GetInfoForTheOnlyOneCheckedMeshOfTheTrack( vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID) { std::pair< unsigned int, unsigned int > oInfo = std::pair< unsigned int, unsigned int >(0, 0); std::list< unsigned int > ListCheckedMeshes = this->m_MeshContainerInfoForVisu->GetHighlightedElementsTraceID(); std::list< unsigned int > ListCheckedMeshesBelongingToTrackID = std::list< unsigned int >(); if ( !ListCheckedMeshes.empty() ) { ListCheckedMeshesBelongingToTrackID = this->m_CollectionOfTraces->GetTraceIDsBelongingToCollectionID( iDatabaseConnector, ListCheckedMeshes, iTrackID); } if ( ListCheckedMeshesBelongingToTrackID.size() != 1 ) { QMessageBox msgBox; msgBox.setText( tr("Please select one and only one Mesh where to split the Track") ); msgBox.exec(); return oInfo; } unsigned int CheckedMesh = ListCheckedMeshesBelongingToTrackID.front(); oInfo.first = CheckedMesh; std::list< unsigned int > MeshesIDs; MeshesIDs.push_back(CheckedMesh); std::list< unsigned int > ListTimePoints = this->m_CollectionOfTraces->GetTimePointsForTraceIDs(iDatabaseConnector, MeshesIDs); if ( ListTimePoints.size() != 1 ) { std::cout << "more than one timepoint"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return oInfo; } oInfo.second = ListTimePoints.front(); return oInfo; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< QGoDBTraceManager::NameWithColorData > QGoDBMeshManager::GetAllTraceIDsWithColor( vtkMySQLDatabase *iDatabaseConnector, std::string & ioIDToSelect) { ioIDToSelect = this->m_LastSelectedTraceAsCollection; return this->m_CollectionOfTraces->GetTracesIDsWithColorForATimePoint( iDatabaseConnector, *this->m_CurrentTimePoint); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< std::pair > QGoDBMeshManager:: GetListVolumes() { std::list< std::pair > oList; QGoTableWidget* tableWidget = this->GetTableWidget(); std::list list = this->GetListHighlightedIDs(); std::list::iterator it = list.begin(); while(it!=list.end()) { double volume = (tableWidget->GetValue( *it, "mesh", "Volume" )).toDouble(); int trackID = (tableWidget->GetValue( *it, "mesh", "trackID" )).toInt(); std::pair trackAndVolume(trackID, volume); oList.push_back(trackAndVolume); ++it; } return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< std::pair > QGoDBMeshManager:: GetListVolumes(const std::list & iMeshIDs) { std::list< std::pair > oList; QGoTableWidget* tableWidget = this->GetTableWidget(); std::list::const_iterator it = iMeshIDs.begin(); while(it!=iMeshIDs.end()) { double volume = (tableWidget->GetValue( *it, "mesh", "Volume" )).toDouble(); int trackID = (tableWidget->GetValue( *it, "mesh", "trackID" )).toInt(); std::pair trackAndVolume(trackID, volume); oList.push_back(trackAndVolume); ++it; } return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- double QGoDBMeshManager:: GetVolume(unsigned int iMeshID) { return (this->GetTableWidget()->GetValue( iMeshID, "mesh", "Volume" )).toDouble(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager:: CleanTWAndContainerForGivenTimePoint(vtkMySQLDatabase *iDatabaseConnector, const std::list& iTimePoints) { this->RemoveTracesFromTWAndContainerForVisuForSpecificTPsTemplate( iDatabaseConnector, this->m_MeshContainerInfoForVisu, iTimePoints); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBMeshManager:: ModifyTrackIDInVisuContainer(unsigned int iTrackID, const std::list< unsigned int > & iToTrack, const std::list< unsigned int > & iToNull) { m_MeshContainerInfoForVisu->AssignToGivenCollection(iTrackID, iToTrack); m_MeshContainerInfoForVisu->AssignToGivenCollection(0, iToNull); } GoFigure2-v0.9.0/Code/GUI/lib/QGoTabImageViewElementBase.h0000644000175000017500000001256611667757442022643 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTabImageViewElementBase_h #define __QGoTabImageViewElementBase_h #include #include "vtkSmartPointer.h" #include "QGoTabElementBase.h" #include "QGoGUILibConfigure.h" class ContourContainer; class MeshContainer; class vtkPolyData; class vtkContourWidget; class vtkOrientedGlyphContourRepresentation; class vtkDataSet; class vtkProperty; // class vtkQuadricLODActor; class vtkActor; class QGoNavigationDockWidget; class QGoContourManualSegmentationWidget; /** \class QGoTabImageViewElementBase \brief \example GUI/lib/qgotabimageviewelementbase.cxx */ class QGOGUILIB_EXPORT QGoTabImageViewElementBase:public QGoTabElementBase { Q_OBJECT public: /** \brief Constructor */ explicit QGoTabImageViewElementBase(QWidget *parent = 0); /** \brief Destructor */ virtual ~QGoTabImageViewElementBase(); typedef QGoTabElementBase::QGoDockWidgetStatusPair QGoDockWidgetStatusPair; /** \brief Update the rendering of the tab */ virtual void Update() = 0; /** \brief */ virtual void SetColor(const bool & iColor); /** \brief Write Settings */ virtual void WriteSettings(); /** \brief Read Settings */ virtual void ReadSettings(); /** \brief Validate one contour traced by using the ContourWidget.*/ virtual void ValidateContour(const int & iId); public slots: /** \brief Change the background color. */ void ChangeBackgroundColor(); /** \brief Show all channels if iChecked is true.*/ virtual void ShowAllChannels(bool iChecked) = 0; /** \brief Show only one channel (iChannel).*/ virtual void ShowOneChannel(int iChannel) = 0; /** \brief Activate the manual segmentation editor (ContourWidget).*/ void ActivateManualSegmentationEditor(const bool & iActivate); /** \brief Validate contour traced in the ContourWidget.*/ virtual void ValidateContour(); /** \brief Reinitialize contour in the ContourWidget (delete contour, * and restart with no contours. * */ void ReinitializeContour(); /** \brief Change contour representation property (color, line width, etc.) */ void ChangeContourRepresentationProperty(); /** \brief Re-edit the iId^th contour. */ void ReEditContour(const unsigned int & iId); virtual void TakeSnapshot() = 0; protected: bool m_Color; QColor m_BackgroundColor; unsigned int m_ContourId; bool m_ReEditContourMode; double m_LinesWidth; QColor m_LinesColor; QColor m_NodesColor; QColor m_ActiveNodesColor; QHBoxLayout *m_LayOut; QAction * m_TakeSnapshotAction; std::vector< vtkSmartPointer< vtkContourWidget > > m_ContourWidget; std::vector< vtkSmartPointer< vtkOrientedGlyphContourRepresentation > > m_ContourRepresentation; ContourContainer * m_ContourContainer; MeshContainer * m_MeshContainer; QGoNavigationDockWidget * m_NavigationDockWidget; QGoContourManualSegmentationWidget *m_ManualSegmentationWidget; virtual void CreateManualSegmentationdockWidget(); virtual void CreateToolsActions(); virtual void GetBackgroundColorFromImageViewer() = 0; virtual void SetBackgroundColorToImageViewer() = 0; virtual int *GetImageCoordinatesFromWorldCoordinates(double pos[3]) = 0; virtual void RemoveActorFromViewer(const int & iId, vtkActor *iActor) = 0; virtual void DisplayActorInViewer(const int & iId, vtkActor *iActor) = 0; // virtual std::vector< vtkQuadricLODActor* > virtual std::vector< vtkActor * > AddContour(vtkPolyData *dataset, vtkProperty *property = NULL) = 0; virtual void SetSlice(int iDir, int *iIdx) = 0; private: Q_DISABLE_COPY(QGoTabImageViewElementBase); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoImageView2D.h0000644000175000017500000000550511667757442020270 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoImageView2D_h #define __QGoImageView2D_h #include #include #include "SnapshotHelper.h" #include "QGoImageView.h" class vtkImageData; class vtkViewImage2DCollection; class QVTKWidget; class vtkEventQtSlotConnect; /** \class QGoImageView2D \brief Widget to visualize a 2D image (represented as vtkImageData). \example GUI/lib/qgoimageview2d.cxx */ class QGOGUILIB_EXPORT QGoImageView2D:public QGoImageView { Q_OBJECT public: explicit QGoImageView2D(QWidget *parent = 0); ~QGoImageView2D(); void SetImage(vtkImageData *iImage); QVTKInteractor * GetInteractor(const int & i = 0); void Update(); void setupUi(QWidget *parent); void retranslateUi(QWidget *parent); virtual void ChangeCursorShape(QCursor iCursorShape); public slots: QString SnapshotViewXY( const GoFigure::FileType & iType, const QString & iBaseName = tr("Snapshot") ); protected: QHBoxLayout * m_LayOut; QVTKWidget * m_QVTKWidgetXY; vtkEventQtSlotConnect *m_VTKEventQtConnector; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoNetworkUtilities.cxx.in0000644000175000017500000000577111667757442022537 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoNetworkUtilities.h" #include #include #include #include #include QGoNetworkUtilities::QGoNetworkUtilities(QObject *iParent) : QObject(iParent), m_Reply(0) { m_Manager = new QNetworkAccessManager(this); QObject::connect( m_Manager, SIGNAL( finished(QNetworkReply *) ), this, SLOT( DisplayResults(QNetworkReply *) ) ); } QGoNetworkUtilities::~QGoNetworkUtilities() { // segfault here ... if ( m_Reply ) { delete m_Reply; m_Reply = 0; } } void QGoNetworkUtilities::CheckForUpdates() { // address QString address("http://gofigure2.sourceforge.net/check_update.php?version="); address.append("@GOFIGURE2_VERSION@"); QUrl url(address); m_Reply = m_Manager->get( QNetworkRequest(url) ); } void QGoNetworkUtilities::DisplayResults(QNetworkReply *reply) { QString response; bool ok = ( reply->error() == QNetworkReply::NoError ); // no error received? if ( ok ) { // read data from QNetworkReply here QByteArray bytes = reply->readAll(); response = QString(bytes); } // Some http error received //else // { // ok = false; // } emit CheckForUpdatesDone(response, ok); }GoFigure2-v0.9.0/Code/GUI/lib/QGoSelectedColorComboBox.h0000755000175000017500000000456211667757442022412 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSelectedColorComboBox_h #define __QGoSelectedColorComboBox_h #include "QGoColorComboBox.h" /** \class QGoSelectedColorComboBox \brief This class enables the Combobox to display item with colors icon for the color and sends a signal when "add new color " is clicked by the user \ingroup GUI */ class QGOGUILIB_EXPORT QGoSelectedColorComboBox:public QGoColorComboBox { Q_OBJECT public: explicit QGoSelectedColorComboBox(QWidget *iparent = 0); virtual ~QGoSelectedColorComboBox(); signals: void AddNewColorActivated(); protected slots: virtual void ActionWhenNewOneRequested(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoDockWidget.h0000644000175000017500000000447511667757442020256 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDockWidget_h #define __QGoDockWidget_h #include #include #include "QGoGUILibConfigure.h" /** \class QGoDockWidget \brief inherits from Qt QDockWidget.toggle action reimplemented in order the state is saved when changing tabs \ingroup GUI */ class QGOGUILIB_EXPORT QGoDockWidget:public QDockWidget { Q_OBJECT public: explicit QGoDockWidget(QWidget* iParent = 0); virtual ~QGoDockWidget(); QAction* toggleViewAction(); protected: QAction* m_ToggleAction; void closeEvent(QCloseEvent *iEvent); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoTabImageViewNDBase.cxx0000644000175000017500000001300511667757442022113 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTabImageViewNDBase.h" #include "QGoNavigationDockWidget.h" #include "vtkImageData.h" #include "vtkSmartPointer.h" #include "vtkImageExtractComponents.h" //-------------------------------------------------------------------------- QGoTabImageViewNDBase::QGoTabImageViewNDBase(QWidget *iParent) : QGoTabImageViewElementBase(iParent), m_Image(0) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoTabImageViewNDBase:: ~QGoTabImageViewNDBase() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * \brief Set the image to be displaid * \param[in] iImage */ void QGoTabImageViewNDBase::SetImage(vtkImageData *iImage) { if ( !iImage ) { std::cerr << "QGoTabImageViewNDBase::SetImage( 0x0 )" << std::endl; return; } m_Image = iImage; int n = m_Image->GetNumberOfScalarComponents(); //this->m_NavigationDockWidget->SetNumberOfChannels(n); if ( n != 1 ) { if ( ( n == 3 ) || ( n == 4 ) ) { //this->m_NavigationDockWidget->SetChannel( 0, tr("Red") ); //this->m_NavigationDockWidget->SetChannel( 1, tr("Green") ); //this->m_NavigationDockWidget->SetChannel( 2, tr("Blue") ); if ( n == 4 ) { //this->m_NavigationDockWidget->SetChannel( 3, tr("Alpha") ); } } else { for ( int i = 0; i < n; i++ ) { //this->m_NavigationDockWidget->SetChannel(i); } } } int extent[6]; m_Image->GetExtent(extent); this->SetImageToImageViewer(m_Image); this->m_NavigationDockWidget->SetXMinimumAndMaximum(extent[0], extent[1]); this->m_NavigationDockWidget->SetXSlice( ( extent[0] + extent[1] ) / 2 ); this->m_NavigationDockWidget->SetYMinimumAndMaximum(extent[2], extent[3]); this->m_NavigationDockWidget->SetYSlice( ( extent[2] + extent[3] ) / 2 ); this->m_NavigationDockWidget->SetZMinimumAndMaximum(extent[4], extent[5]); this->m_NavigationDockWidget->SetZSlice( ( extent[4] + extent[5] ) / 2 ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkImageData * QGoTabImageViewNDBase::GetImage() { return m_Image; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * \brief * \param[in] iChecked */ void QGoTabImageViewNDBase::ShowAllChannels(bool iChecked) { if ( iChecked ) { this->SetImageToImageViewer(m_Image); } else { int ch = 0;//this->m_NavigationDockWidget->GetCurrentChannel(); if ( ch != -1 ) { vtkSmartPointer< vtkImageExtractComponents > extract = vtkSmartPointer< vtkImageExtractComponents >::New(); extract->SetInput(m_Image); extract->SetComponents(ch); extract->Update(); this->SetImageToImageViewer( extract->GetOutput() ); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * \brief * \param[in] iChannel */ void QGoTabImageViewNDBase::ShowOneChannel(int iChannel) { if ( m_Image ) { if ( iChannel != -1 ) { vtkSmartPointer< vtkImageExtractComponents > extract = vtkSmartPointer< vtkImageExtractComponents >::New(); extract->SetInput(m_Image); extract->SetComponents(iChannel); extract->Update(); this->SetImageToImageViewer( extract->GetOutput() ); } } } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/QGoColorCodingDialog.cxx0000644000175000017500000001202411667757442022114 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoColorCodingDialog.h" #include #include #include QGoColorCodingDialog::QGoColorCodingDialog(std::string iTraceName, bool iRandomIncluded, QWidget *iParent) : QDialog(iParent) { this->SetUpUi(iTraceName, iRandomIncluded); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoColorCodingDialog::~QGoColorCodingDialog() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoColorCodingDialog::OpenLUTDialog() { this->m_LUT = QGoLUTDialog::GetLookupTable( this, tr("Choose your range of colors") ); if ( this->m_LUT != NULL ) { this->accept(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoColorCodingDialog::SetUpUi(std::string iTraceName, bool iRandomIncluded) { QLabel *ChooseYourWay = new QLabel( tr("Choose how you want to color your %1s :").arg( iTraceName.c_str() ) ); m_DefaultButton = new QRadioButton(tr("Default"), this); m_DefaultButton->setChecked(true); m_LUTButton = new QRadioButton(tr("Choose a range of colors"), this); QVBoxLayout *VLayout = new QVBoxLayout(this); VLayout->addWidget(ChooseYourWay); VLayout->addWidget(m_DefaultButton); VLayout->addWidget(m_LUTButton); if ( iRandomIncluded ) { m_RandomButton = new QRadioButton(tr("Randomly"), this); VLayout->addWidget(m_RandomButton); } QDialogButtonBox *ButtonBox = new QDialogButtonBox(this); ButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); VLayout->addWidget(ButtonBox); QObject::connect( this->m_LUTButton, SIGNAL( clicked() ), this, SLOT( OpenLUTDialog() ) ); QObject::connect( ButtonBox, SIGNAL( accepted() ), this, SLOT( accept() ) ); QObject::connect( ButtonBox, SIGNAL( rejected() ), this, SLOT( reject() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoColorCodingDialog::ColorWay QGoColorCodingDialog::GetColorWay( std::string iTraceName, vtkLookupTable **ioLUT, bool iRandomIncluded, QWidget *iiParent) { QGoColorCodingDialog *ColorDialog = new QGoColorCodingDialog(iTraceName, iRandomIncluded, iiParent); ColorWay oNameWay = QGoColorCodingDialog::Nothing; if ( ColorDialog->exec() == QDialog::Accepted ) { if ( ColorDialog->m_DefaultButton->isChecked() ) { oNameWay = QGoColorCodingDialog::Default; } if ( iRandomIncluded ) { if ( ColorDialog->m_RandomButton->isChecked() ) { oNameWay = QGoColorCodingDialog::Random; } } if ( ColorDialog->m_LUTButton->isChecked() ) { oNameWay = QGoColorCodingDialog::LUT; *ioLUT = ColorDialog->m_LUT; ColorDialog->accept(); } } return oNameWay; }GoFigure2-v0.9.0/Code/GUI/lib/QGoCreateMeshDialog.cxx0000644000175000017500000001325111667757442021735 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoCreateMeshDialog.h" QGoCreateMeshDialog::QGoCreateMeshDialog(QWidget *iParent) : QDialog(iParent) { /*this->VLayoutLabel = new QVBoxLayout; this->VLayoutCombobox = new QVBoxLayout; this->VLayoutDescription = new QVBoxLayout; this->HorizontalLayout = new QHBoxLayout;*/ //this->HorizontalSpacer = new QSpacerItem; this->GridLayout = new QGridLayout; this->LineCellType = new QLabel( tr("Select the Cell Type:") ); this->LineSubCellType = new QLabel( tr("Select the SubCellular type:") ); this->LineColor = new QLabel( tr("Select the color") ); this->SelectCellType = new QComboBox; this->SelectSubCellType = new QComboBox; this->SelectColor = new QComboBox; this->ScrollDescrCell = new QScrollArea; this->ScrollDescrSubCell = new QScrollArea; this->ScrollDescrColor = new QScrollArea; this->DescriptionCell = new QLineEdit; this->DescriptionSubCell = new QLineEdit; this->DescriptionColor = new QLineEdit; this->ScrollDescrCell->setWidget(this->DescriptionCell); this->ScrollDescrSubCell->setWidget(this->DescriptionSubCell); this->ScrollDescrColor->setWidget(this->DescriptionColor); //this->DescriptionCell = new QTextEdit; //this->DescriptionSubCell = new QTextEdit; //this->DescriptionColor = new QTextEdit; this->ButtonBox = new QDialogButtonBox; this->OkButton = new QPushButton( tr("OK") ); this->CancelButton = new QPushButton( tr("Cancel") ); this->NewCellType = new QPushButton( tr("New One") ); this->NewSubCellType = new QPushButton( tr("New One") ); this->NewColor = new QPushButton( tr("New One") ); this->ButtonBox->addButton(OkButton, QDialogButtonBox::AcceptRole); this->ButtonBox->addButton(CancelButton, QDialogButtonBox::RejectRole); /*this->VLayoutLabel->addWidget(this->LineCellType); this->VLayoutLabel->addWidget(this->LineSubCellType); this->VLayoutLabel->addWidget(this->LineColor); this->VLayoutCombobox->addWidget(this->SelectCellType); this->VLayoutCombobox->addWidget(this->SelectSubCellType); this->VLayoutCombobox->addWidget(this->SelectColor); this->VLayoutDescription->addWidget(this->DescriptionCell); this->VLayoutDescription->addWidget(this->DescriptionSubCell); this->VLayoutDescription->addWidget(this->DescriptionColor); this->HorizontalLayout->addLayout(this->VLayoutLabel); this->HorizontalLayout->addLayout(this->VLayoutCombobox); this->HorizontalLayout->addLayout(this->VLayoutDescription); this->HorizontalLayout->addWidget(this->ButtonBox); this->setLayout(this->HorizontalLayout);*/ this->GridLayout->addWidget(this->LineCellType, 1, 1); this->GridLayout->addWidget(this->LineSubCellType, 2, 1); this->GridLayout->addWidget(this->LineColor, 3, 1); this->GridLayout->addWidget(this->SelectCellType, 1, 2); this->GridLayout->addWidget(this->SelectSubCellType, 2, 2); this->GridLayout->addWidget(this->SelectColor, 3, 2); /*this->GridLayout->addWidget(this->DescriptionCell,1,3); this->GridLayout->addWidget(this->DescriptionSubCell,2,3); this->GridLayout->addWidget(this->DescriptionColor,3,3);*/ //this->GridLayout->addWidget(this->ScrollDescrCell,1,3); //this->GridLayout->addWidget(this->ScrollDescrSubCell,2,3); //this->GridLayout->addWidget(this->ScrollDescrColor,3,3); this->GridLayout->addWidget(this->NewCellType, 1, 4); this->GridLayout->addWidget(this->NewSubCellType, 2, 4); this->GridLayout->addWidget(this->NewColor, 3, 4); this->GridLayout->addWidget(this->ButtonBox, 4, 1); this->setLayout(this->GridLayout); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoCreateMeshDialog::~QGoCreateMeshDialog() { } //-------------------------------------------------------------------------- //--------------------------------------------------------------------------GoFigure2-v0.9.0/Code/GUI/lib/QGoTrackViewDockWidget.cxx0000644000175000017500000002274711667757442022453 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTrackViewDockWidget.h" #include "ctkDoubleRangeSlider.h" #include #include #include #include #include //------------------------------------------------------------------------- QGoTrackViewDockWidget::QGoTrackViewDockWidget( QWidget *iParent) : QGoDockWidget(iParent) { this->SetUpUi(); QIcon trackicon; trackicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/TrackView.png") ), QIcon::Normal, QIcon::Off); this->m_ToggleAction->setIcon(trackicon); this->m_ToggleAction->setToolTip("Track View"); this->setWindowTitle("Track View"); // appearance QObject::connect( this->m_linewidthSpinBox, SIGNAL( valueChanged(double)), this, SLOT(lineWidthValueChanged(double)) ); QObject::connect( this->m_glyph, SIGNAL( toggled(bool) ), this, SLOT( Glyphs(bool) ) ); QObject::connect( this->m_glyphSpinBox, SIGNAL( valueChanged(double) ), this, SLOT( glyphValueChanged(double) ) ); QObject::connect( this->m_tube, SIGNAL( toggled(bool) ), this, SLOT( Tubes(bool) ) ); QObject::connect( this->m_tubeSpinBox, SIGNAL( valueChanged(double) ), this, SLOT( tubeValueChanged(double) ) ); // color code QObject::connect( this->m_time, SIGNAL( toggled(bool) ), this, SLOT( ColorCodeTracksByTime(bool) ) ); QObject::connect( this->m_speed, SIGNAL( toggled(bool) ), this, SLOT( ColorCodeTracksBySpeed(bool) ) ); QObject::connect( this->m_real, SIGNAL( toggled(bool) ), this, SLOT( ColorCodeTracksByOriginalColor(bool) ) ); /* // double slider ctkDoubleRangeSlider *rangeSlider = new ctkDoubleRangeSlider(Qt::Horizontal , this->dockWidgetContents); gridLayout->addWidget(rangeSlider, 2, 0, 1, 1); */ } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoTrackViewDockWidget:: ~QGoTrackViewDockWidget() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackViewDockWidget::lineWidthValueChanged(double iValue) { if ( !this->m_tube->isChecked() ) { emit UpdateTracksRepresentation( 0, 0, iValue ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackViewDockWidget::glyphValueChanged(double) { //to avoid useless update if ( this->m_glyph->isChecked() ) { Glyphs(true); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackViewDockWidget::Glyphs(bool iActivated) { if ( iActivated ) { emit UpdateTracksRepresentation( this->m_glyphSpinBox->value(), this->m_tubeSpinBox->value() * this->m_tube->isChecked(), this->m_linewidthSpinBox->value() ); } else { emit UpdateTracksRepresentation( 0, this->m_tubeSpinBox->value() * this->m_tube->isChecked(), this->m_linewidthSpinBox->value() ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackViewDockWidget::tubeValueChanged(double) { //to avoid useless update if ( this->m_tube->isChecked() ) { Tubes(true); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackViewDockWidget::Tubes(bool iActivated) { if ( iActivated ) { emit UpdateTracksRepresentation( this->m_glyphSpinBox->value() * this->m_glyph->isChecked(), this->m_tubeSpinBox->value(), this->m_linewidthSpinBox->value() ); } else { emit UpdateTracksRepresentation(this->m_glyphSpinBox->value() * this->m_glyph->isChecked(), 0, this->m_linewidthSpinBox->value() ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackViewDockWidget::ColorCodeTracksByTime(bool iChecked) { if ( iChecked ) { emit ChangeColorCode("TemporalInformation"); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackViewDockWidget::ColorCodeTracksBySpeed(bool iChecked) { if ( iChecked ) { emit ChangeColorCode("SpeedInformation"); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackViewDockWidget::ColorCodeTracksByOriginalColor(bool iChecked) { if ( iChecked ) { emit ChangeColorCode("Original"); } } //------------------------------------------------------------------------- void QGoTrackViewDockWidget::SetUpUi() { QWidget* TrackViewWidget = new QWidget; this->m_glyph = new QCheckBox(tr("Glyphs"), this ); this->m_tube = new QCheckBox(tr ("Tubes"), this ); this->m_glyphSpinBox = new QDoubleSpinBox(this); this->m_tubeSpinBox = new QDoubleSpinBox(this); this->m_linewidthSpinBox = new QDoubleSpinBox(this); this->SetDoubleSpinBox(this->m_glyphSpinBox, 0., 99., 3. ); this->SetDoubleSpinBox(this->m_tubeSpinBox, 0., 99., 3. ); this->SetDoubleSpinBox(this->m_linewidthSpinBox, 0., 10., 1. ); QVBoxLayout* Vlayout = new QVBoxLayout; QLabel* linewidthLabel = new QLabel( tr( "Line Width" ), this ); QLabel* Element = new QLabel(tr("Element:"), this ); QLabel* Radius = new QLabel (tr("Radius:"), this ); QGridLayout* GridLayout = new QGridLayout; GridLayout->addWidget(Element, 0, 0); GridLayout->addWidget(Radius, 0, 1); GridLayout->addWidget(linewidthLabel, 1, 0 ); GridLayout->addWidget(this->m_linewidthSpinBox, 1, 1 ); GridLayout->addWidget(this->m_glyph, 2, 0); GridLayout->addWidget(this->m_glyphSpinBox, 2, 1); GridLayout->addWidget(this->m_tube, 3, 0); GridLayout->addWidget(this->m_tubeSpinBox, 3, 1); Vlayout->addLayout(GridLayout); QLabel* Blank = new QLabel(tr(" ") ); Vlayout->addWidget(Blank); this->m_real = new QRadioButton(tr("Original Color") ); this->m_time = new QRadioButton(tr("Time Color Code") ); this->m_speed = new QRadioButton(tr("Speed Color Code") ); this->m_real->setChecked(true); QVBoxLayout* VColorCodeLayout = new QVBoxLayout; VColorCodeLayout->addWidget(this->m_real); VColorCodeLayout->addWidget(this->m_time); VColorCodeLayout->addWidget(this->m_speed); Vlayout->addLayout(VColorCodeLayout, 1); TrackViewWidget->setLayout(Vlayout); this->setWidget(TrackViewWidget); TrackViewWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTrackViewDockWidget::SetDoubleSpinBox(QDoubleSpinBox* iSpinBox, double Min, double Max, double Value ) { iSpinBox->setDecimals(2); iSpinBox->setMaximum(Max); iSpinBox->setMinimum(Min); iSpinBox->setValue(Value); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/Watershed.h0000644000175000017500000000523511667757442017544 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __Watershed_h #define __Watershed_h #include "QGoSeedAlgorithmBase.h" #include "QGoGUILibConfigure.h" class vtkImageExport; class vtkImageData; /** * \class QGoAboutWidget * \brief About Widget which includes the list of authors, licenses, * copyrights, dates, versions... */ class QGOGUILIB_EXPORT Watershed:public QGoSeedAlgorithmBase { Q_OBJECT public: /** \brief Constructor */ explicit Watershed(); /** \brief Destructor */ ~Watershed(); virtual vtkImageData * Apply(); /*void setOrigin(double* iOrigin); void setSeedPosition(double* iSeedPosition); void setIterations(int iIterations); void setRadius(double iRadius); void setCurvature(int iCurvature); void setCenter(double* iCenter); void setDimension(int iDimension);*/ private: /*double m_Radius; int m_Iterations; int m_Curvature; double m_Center[3]; unsigned int m_Dimension;*/ }; #endif GoFigure2-v0.9.0/Code/GUI/lib/LineageViewer/0000755000175000017500000000000011667757442020166 5ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/lib/LineageViewer/QGoLineageViewerWidget.h0000644000175000017500000001062511667757442024644 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef QGoLineageViewerWidget_H #define QGoLineageViewerWidget_H #include #include "vtkSmartPointer.h" class vtkObject; // Forward Qt class declarations class Ui_QGoLineageViewerWidget; //table view class vtkQtTreeView; //graph view class vtkGraphLayoutView; class vtkTreeLayoutStrategy; class vtkLookupTable; // connection between graph and table class vtkAnnotationLink; class vtkEventQtSlotConnect; class vtkMutableDirectedGraph; class vtkTree; class vtkDoubleArray; // EXPERIMENTAL // back plane class vtkDelaunay2D; class vtkGraphToPolyData; class vtkPolyDataMapper; class vtkActor; class QGoLineageViewerWidget : public QDockWidget { Q_OBJECT public: QGoLineageViewerWidget( QWidget * iParent = 0 ); ~QGoLineageViewerWidget(); private: /* * */ void ConfigureGraphView(); /* * */ void ConfigureTableView(); /* * */ void ConnectQtButtons(); /* * */ void FillQtComboBoxes(); void UpdateTree(vtkIdType iParentID, vtkIdType iOldID, vtkSmartPointer iOldTree, vtkSmartPointer iNewGraph, vtkDoubleArray* iTrackIDArray, unsigned int iDepth, vtkDoubleArray* iDepthArray); void UpdateGraph(); vtkSmartPointer m_Tree; vtkSmartPointer m_Graph; std::list< std::pair< QString,vtkSmartPointer > > m_ListOfTrees; vtkSmartPointer m_treeTableView; vtkSmartPointer m_treeGraphView; vtkSmartPointer m_annotationLink; vtkSmartPointer m_connect; vtkSmartPointer m_lut; vtkSmartPointer m_treeLayoutStrategy; // Experimental stuff... vtkSmartPointer m_backPlane; vtkSmartPointer m_graphToPolyData; vtkSmartPointer m_planeMapper; vtkSmartPointer m_planeActor; Ui_QGoLineageViewerWidget *ui; private slots: void slotAddLineage(); void slotDeleteLineage(); void selectionChanged(vtkObject*, unsigned long,void* ,void* ); void slotEnableScale(int state); void slotChangeScale(QString array); void slotEnableColorCode(int state); void slotChangeColorCode(QString array); void slotEnableLabel(int state); void slotChangeLabel(QString array); void slotEnableRadialLayout(int state); void slotChangeRadialLayout(int angle); void slotEnableLog(int state); void slotChangeLog(double angle); void slotEnableBackPlane(int state); }; #endif // QGoLineageViewerWidget_H GoFigure2-v0.9.0/Code/GUI/lib/LineageViewer/QGoLineageViewerWidget.cxx0000644000175000017500000004643311667757442025225 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "ui_QGoLineageViewerWidget.h" #include "QGoLineageViewerWidget.h" // QT general #include // Delete Lineage #include #include // tab view #include // graph view #include "vtkGraphLayoutView.h" #include "vtkRenderWindow.h" #include "vtkTreeLayoutStrategy.h" // color coding #include "vtkLookupTable.h" #include "vtkViewTheme.h" // create the tree #include "vtkAdjacentVertexIterator.h" #include "vtkMutableDirectedGraph.h" #include "vtkStringArray.h" #include "vtkDoubleArray.h" #include "vtkPoints.h" #include "vtkTree.h" // get data representation #include "vtkDataRepresentation.h" // get vertex data #include "vtkDataSetAttributes.h" //connect table and graph #include "vtkAnnotationLink.h" #include // back plane #include "vtkDelaunay2D.h" #include "vtkGraphToPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRendererCollection.h" //reader #include #include #include "vtkTreeReader.h" //---------------------------------------------------------------------------- // Constructor QGoLineageViewerWidget:: QGoLineageViewerWidget( QWidget* iParent) : QDockWidget( iParent ) { this->ui = new Ui_QGoLineageViewerWidget; this->ui->setupUi(this); // we nee a graph as input of the graph view m_Graph = vtkSmartPointer::New(); // we need a tree as input for the table m_Tree = vtkSmartPointer::New(); m_Tree->CheckedDeepCopy(m_Graph); //Create the table View this->m_treeTableView = vtkSmartPointer::New(); this->ConfigureTableView(); //Create the graph View this->m_treeGraphView = vtkSmartPointer::New(); this->ConfigureGraphView(); this->FillQtComboBoxes(); // add link table and graph annotations this->m_annotationLink = vtkSmartPointer::New(); this->m_treeGraphView->GetRepresentation()->SetAnnotationLink(this->m_annotationLink); this->m_treeTableView->GetRepresentation()->SetAnnotationLink(this->m_annotationLink); // connect table and graph this->m_connect = vtkSmartPointer::New(); this->m_connect->Connect(this->m_treeTableView->GetRepresentation(), vtkCommand::SelectionChangedEvent, this, SLOT(selectionChanged(vtkObject*, unsigned long, void*, void*))); this->m_connect->Connect(this->m_treeGraphView->GetRepresentation(), vtkCommand::SelectionChangedEvent, this, SLOT(selectionChanged(vtkObject*, unsigned long, void*, void*))); this->ConnectQtButtons(); /////// EXPERIMENTAL /////// // create the back plane //this->m_backPlane = vtkSmartPointer::New(); //this->m_graphToPolyData = vtkSmartPointer::New(); //this->m_graphToPolyData->SetInput(graph); //this->m_graphToPolyData->Update(); //this->m_planeMapper = vtkSmartPointer::New(); //this->m_planeActor = vtkSmartPointer::New(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- QGoLineageViewerWidget::~QGoLineageViewerWidget() { } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::ConfigureGraphView() { this->m_treeGraphView->AddRepresentationFromInput(m_Graph); this->m_treeGraphView->SetEdgeSelection(false); this->m_treeGraphView->SetLayoutStrategyToTree(); this->m_treeGraphView->ResetCamera(); this->m_treeGraphView->SetInteractor( this->ui->graphViewWidget->GetInteractor() ); this->ui->graphViewWidget->SetRenderWindow( this->m_treeGraphView->GetRenderWindow() ); // create LUT this->m_lut = vtkSmartPointer::New(); this->m_lut->SetHueRange(0.667, 0.0); this->m_lut->Build(); // create theme vtkSmartPointer theme = vtkSmartPointer::New(); theme->SetPointLookupTable(this->m_lut); theme->SetCellLookupTable(this->m_lut); this->m_treeGraphView->ApplyViewTheme(theme); // create the layout strategy this->m_treeLayoutStrategy = vtkSmartPointer::New(); this->m_treeLayoutStrategy->SetAngle(90); this->m_treeLayoutStrategy->SetRadial(false); this->m_treeLayoutStrategy->SetLogSpacingValue(1); this->m_treeGraphView->SetLayoutStrategy(this->m_treeLayoutStrategy); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::ConfigureTableView() { QGridLayout* tableLayout = new QGridLayout(this->ui->tableFrame); tableLayout->addWidget(this->m_treeTableView->GetWidget()); this->m_treeTableView->AddRepresentationFromInput(m_Tree); this->m_treeTableView->ColorByArrayOn(); this->m_treeTableView->SetShowRootNode(false); this->m_treeTableView->Update(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::ConnectQtButtons() { // add a lineage connect(this->ui->addLineagePushButton, SIGNAL(pressed()), this, SLOT(slotAddLineage())); connect(this->ui->deleteLineagePushButton, SIGNAL(pressed()), this, SLOT(slotDeleteLineage())); // color coding connect(this->ui->colorCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotEnableColorCode(int))); connect(this->ui->colorComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotChangeColorCode(QString))); // scaling connect(this->ui->scaleCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotEnableScale(int))); connect(this->ui->scaleComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotChangeScale(QString))); // labeling connect(this->ui->labelCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotEnableLabel(int))); connect(this->ui->labelComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotChangeLabel(QString))); // radial rendering connect(this->ui->radialCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotEnableRadialLayout(int))); connect(this->ui->radialSlider, SIGNAL(valueChanged(int)), this, SLOT(slotChangeRadialLayout(int))); // log rendering connect(this->ui->logCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotEnableLog(int))); connect(this->ui->logSpinBox, SIGNAL(valueChanged(double)), this, SLOT(slotChangeLog(double))); // back plane connect(this->ui->backCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotEnableBackPlane(int))); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::FillQtComboBoxes() { // Fill combo boxes // Update combo boxes (fill content with arrays names) int numberOfArrays = m_Graph->GetVertexData()->GetNumberOfArrays(); this->ui->colorComboBox->clear(); this->ui->scaleComboBox->clear(); this->ui->labelComboBox->clear(); // fill comboxes according to the data for(int i=0;iGetVertexData()->GetArrayName(i); this->ui->labelComboBox->addItem(name); // if data array (i.e. numbers), add it if(m_Graph->GetVertexData()->GetArray(name)) { this->ui->colorComboBox->addItem(name); this->ui->scaleComboBox->addItem(name); } } // requiered to properly initialize the view since the scaling changes // when we fill the combo box this->slotEnableScale(false); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::selectionChanged(vtkObject*, unsigned long, void* vtkNotUsed(clientData), void* callData) { this->m_treeTableView->Update(); this->m_treeGraphView->Render(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotAddLineage() { QStringList files = QFileDialog::getOpenFileNames( NULL, tr("Select lineages")); for( int i = 0; i < files.size(); i++ ) { vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(files[i].toLocal8Bit().data()); reader->Update(); vtkSmartPointer tree = vtkSmartPointer::New(); tree->CheckedDeepCopy(reader->GetOutput()); // update list of graphs std::pair > treePair; treePair.first = files[i]; treePair.second = tree; m_ListOfTrees.push_back(treePair); } UpdateGraph(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::UpdateGraph() { // create New graph vtkSmartPointer newGraph = vtkSmartPointer::New(); vtkIdType rootID = newGraph->AddVertex(); // info vtkSmartPointer id = vtkSmartPointer::New(); id->SetName("Track ID"); id->InsertValue(rootID, 0); vtkSmartPointer depth = vtkSmartPointer::New(); depth->SetName("Lineage Depth"); depth->InsertValue(rootID, 0); // fill the new graph std::list > >::iterator it = m_ListOfTrees.begin(); while(it != m_ListOfTrees.end()) { UpdateTree( rootID, // new ID it->second->GetRoot(), // old ID it->second, // old graph newGraph, // new graph id, // Track ID array 1, depth); // original depth, depth array ++it; } newGraph->GetVertexData()->AddArray(id); newGraph->GetVertexData()->AddArray(depth); m_Graph->CheckedDeepCopy(newGraph); m_Tree->CheckedDeepCopy(newGraph); this->ConfigureTableView(); this->ConfigureGraphView(); this->FillQtComboBoxes(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::UpdateTree(vtkIdType iParentID, vtkIdType iOldID, vtkSmartPointer iOldTree, vtkSmartPointer iNewGraph, vtkDoubleArray* iTrackIDArray, unsigned int iDepth, vtkDoubleArray* iDepthArray) { // build new tree vtkIdType newRoot = iNewGraph->AddChild(iParentID); // update information array vtkDataArray* id = iOldTree->GetVertexData()->GetArray("Track ID"); double value = id->GetTuple1(iOldID); iTrackIDArray->InsertValue( newRoot, value ); iDepthArray->InsertValue(newRoot, iDepth); // go through tree vtkSmartPointer it = vtkSmartPointer::New(); iOldTree->GetChildren(iOldID, it); while(it->HasNext()) { UpdateTree(newRoot, it->Next() , iOldTree, iNewGraph, iTrackIDArray, iDepth+1, iDepthArray); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotDeleteLineage() { bool ok; QStringList lineages; std::list > >::iterator it = m_ListOfTrees.begin(); while(it != m_ListOfTrees.end()) { lineages << it->first; ++it; } QString item = QInputDialog::getItem(this, tr("Lineage selection"), tr("Please select the lineage you want to delete"), lineages, 0, false, &ok); // Remove from the list it = m_ListOfTrees.begin(); while(it != m_ListOfTrees.end()) { if( ! it->first.compare(item) ) // compare returns 0 if QStrings are equal { m_ListOfTrees.erase(it); break; } ++it; } // update the graph UpdateGraph(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotEnableColorCode(int state) { this->m_treeGraphView->SetColorVertices(state); //update visu this->m_treeGraphView->Render(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotChangeColorCode(QString array) { this->m_treeGraphView->SetVertexColorArrayName(array.toLocal8Bit().data()); this->m_treeGraphView->SetEdgeColorArrayName(array.toLocal8Bit().data()); //update visu this->m_treeGraphView->Render(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotEnableScale(int state) { //scale this->m_treeLayoutStrategy->SetDistanceArrayName (state ? this->ui->scaleComboBox->currentText().toLocal8Bit().data() : NULL); //update visu this->m_treeGraphView->ResetCamera(); this->m_treeGraphView->Render(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotChangeScale(QString array) { this->m_treeLayoutStrategy->SetDistanceArrayName(array.toLocal8Bit().data()); //update visu this->m_treeGraphView->ResetCamera(); this->m_treeGraphView->Render(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotEnableLabel(int state) { //scale this->m_treeGraphView->SetVertexLabelVisibility(state); //update visu this->m_treeGraphView->Render(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotChangeLabel(QString array) { this->m_treeGraphView->SetVertexLabelArrayName(array.toLocal8Bit().data()); //update visu this->m_treeGraphView->Render(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotEnableRadialLayout(int state) { if(!state) { this->m_treeLayoutStrategy->SetAngle(90); } else { this->m_treeLayoutStrategy->SetAngle( this->ui->radialSlider->value() ); } //radial layout this->m_treeLayoutStrategy->SetRadial(state); //update visu this->m_treeGraphView->ResetCamera(); this->m_treeGraphView->Render(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotChangeRadialLayout(int angle) { if(this->ui->radialCheckBox->isChecked() ) { // change the layout angle this->m_treeLayoutStrategy->SetAngle( angle ); //update visu this->m_treeGraphView->ResetCamera(); this->m_treeGraphView->Render(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotEnableLog(int state) { if(!state) { this->m_treeLayoutStrategy->SetLogSpacingValue(1); } else { this->m_treeLayoutStrategy->SetLogSpacingValue( this->ui->logSpinBox->value() ); } //update visu this->m_treeGraphView->ResetCamera(); this->m_treeGraphView->Render(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotChangeLog(double angle) { if(this->ui->logCheckBox->isChecked() ) { // change the layout angle this->m_treeLayoutStrategy->SetLogSpacingValue( angle ); //update visu this->m_treeGraphView->ResetCamera(); this->m_treeGraphView->Render(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void QGoLineageViewerWidget::slotEnableBackPlane(int state) { if(state) { //this->m_backPlane->SetInput( // this->m_graphToPolyData->GetOutput()); this->m_planeMapper->SetInput( this->m_graphToPolyData->GetOutput()); this->m_planeActor->SetMapper(this->m_planeMapper); this->ui->graphViewWidget->GetRenderWindow()->GetRenderers() ->GetFirstRenderer()->AddActor(this->m_planeActor); } else { this->ui->graphViewWidget->GetRenderWindow()->GetRenderers() ->GetFirstRenderer()->RemoveActor(this->m_planeActor); } //update visu this->m_treeGraphView->Render(); } //---------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/LineageViewer/QGoLineageViewerWidget.ui0000644000175000017500000002221611667757442025031 0ustar mathieumathieu QGoLineageViewerWidget 0 0 441 561 QDockWidget::AllDockWidgetFeatures Lineage Viewer false QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable Qt::AllDockWidgetAreas Table QFrame::StyledPanel QFrame::Raised false QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable Qt::AllDockWidgetAreas Graph QFrame::StyledPanel QFrame::Raised 1 1 300 150 false QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable Qt::AllDockWidgetAreas Paramters QFrame::StyledPanel QFrame::Raised Radial Layout 360 360 Qt::Horizontal 360 360 Log 0.100000000000000 0.100000000000000 1.000000000000000 Color Code Scale Label false Back Plane Add Lineage Delete Lineage QVTKWidget QWidget
QVTKWidget.h
GoFigure2-v0.9.0/Code/GUI/lib/ConversionLsmToMegaThread.cxx0000644000175000017500000002530411667757442023216 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ConversionLsmToMegaThread.h" #include "LSMToMegaCapture.h" #include "vtkLSMReader.h" #include #include #include #include #include #include #include "vtkImageWriterHelper.h" #include "vtkExtractVOI.h" #include "vtkImageData.h" #include "vtkLSMReader.h" #include "vtkSmartPointer.h" #include "vtkPNGWriter.h" #include "vtkTIFFWriter.h" #include //------------------------------------------------------------------------- //------------------------------------------------------------------------- ConversionLsmToMegaThread::ConversionLsmToMegaThread () : m_BaseName(""), m_LsmPath(""), m_MegaPath(""), m_FileType(GoFigure::PNG), m_LSMReaders(0), m_Plaque (0), m_Row(0), m_Column (0), m_XTile(0), m_YTile(0), m_ZTile (0), m_XOverlap(0), m_YOverlap(0), m_ZOverlap(0), m_NumberOfChannels(0), m_NumberOfTimePoints(0), m_Dim(0) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- ConversionLsmToMegaThread::~ConversionLsmToMegaThread() { if ( !m_LSMReaders.empty() ) { for ( unsigned int i = 0; i < m_LSMReaders.size(); i++ ) { m_LSMReaders[i]->Delete(); } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ConversionLsmToMegaThread::run() { // Allocate memory to avoid automatic suppression at the end of this function /** * \todo Reimplement these methods in this function only get lsm reader from there, no conversion */ LSMToMegaCapture *converter = new LSMToMegaCapture; converter->SetFileName(m_LsmPath); converter->SetOutputFileType(m_FileType); m_LSMReaders = converter->GetLSMReaders(); m_NumberOfChannels = m_LSMReaders[0]->GetNumberOfChannels(); m_NumberOfTimePoints = m_LSMReaders[0]->GetNumberOfTimePoints(); int dim[5]; m_LSMReaders[0]->GetDimensions(dim); m_Dim = dim[2]; // Start conversion emit InitialisationProgressSent(); //converter.Export( m_MegaPath ); this->ExportWithReimplemented(m_MegaPath); // send message "conversion terminated" emit ConversionTerminatedSent(); } void ConversionLsmToMegaThread::SetBaseName(std::string iBaseName) { m_BaseName = iBaseName; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ConversionLsmToMegaThread::SetLsmPath(std::string iLsmPath) { m_LsmPath = iLsmPath; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ConversionLsmToMegaThread::SetMegaPath(std::string iMegaPath) { m_MegaPath = iMegaPath; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ConversionLsmToMegaThread::SetOutputFileType(const GoFigure::FileType & iFileType) { m_FileType = iFileType; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ConversionLsmToMegaThread::ExportWithReimplemented(std::string iMegaPath) { double spacing[3]; m_LSMReaders[0]->GetVoxelSizes(spacing); int dim[5]; m_LSMReaders[0]->GetDimensions(dim); std::string headerfilename = iMegaPath; headerfilename += m_BaseName; headerfilename += ".meg"; std::ofstream file( headerfilename.c_str() ); file << "MegaCapture" << std::endl; file << "" << std::endl; file << "Version 3.0" << std::endl; file << "ExperimentTitle " << std::endl; file << "ExperimentDescription "; if ( m_LSMReaders[0]->GetDescription() ) { file << m_LSMReaders[0]->GetDescription(); } file << std::endl; file << "TimeInterval " << m_LSMReaders[0]->GetTimeInterval() << std::endl; file << "Objective " << m_LSMReaders[0]->GetObjective() << std::endl; file << "VoxelSizeX " << spacing[0] * 1000000 << std::endl; file << "VoxelSizeY " << spacing[1] * 1000000 << std::endl; file << "VoxelSizeZ " << spacing[2] * 1000000 << std::endl; file << "DimensionX " << dim[0] << std::endl; file << "DimensionY " << dim[1] << std::endl; file << "DimensionPL " << m_Plaque << std::endl; file << "DimensionCO " << m_Column << std::endl; file << "DimensionRO " << m_Row << std::endl; file << "DimensionZT " << m_ZTile << std::endl; file << "DimensionYT " << m_YTile << std::endl; file << "DimensionXT " << m_XTile << std::endl; file << "DimensionTM " << m_NumberOfTimePoints << std::endl; file << "DimensionZS " << dim[2] << std::endl; file << "DimensionCH " << m_NumberOfChannels << std::endl; unsigned int i, j, k; for ( i = 0; i < m_NumberOfChannels; i++ ) { int r = m_LSMReaders[0]->GetChannelColorComponent(i, 0); int g = m_LSMReaders[0]->GetChannelColorComponent(i, 1); int b = m_LSMReaders[0]->GetChannelColorComponent(i, 2); std::ostringstream channelColor; channelColor << "ChannelColor" << std::setw(2) << std::setfill('0') << i; file << channelColor.str() << " " << r * 256 * 256 + g * 256 + b << std::endl; //send signal for progress bar emit ProgressSent(); } file << "ChannelDepth 8" << std::endl; file << "FileType PNG" << std::endl; file << "" << std::endl; if ( m_NumberOfChannels > 1 ) { for ( i = 1; i < m_NumberOfChannels; i++ ) { m_LSMReaders.push_back( vtkLSMReader::New() ); m_LSMReaders[i]->SetFileName( m_LsmPath.c_str() ); m_LSMReaders[i]->SetUpdateChannel(i); //send signal for progress bar emit ProgressSent(); } } int extent[6]; char timeStr[100] = ""; struct stat buf; if ( !stat(m_LsmPath.c_str(), &buf) ) { strftime( timeStr, 100, "%Y-%m-%d %H:%M:%S", localtime(&buf.st_mtime) ); } for ( i = 0; i < m_NumberOfTimePoints; i++ ) { for ( k = 0; k < m_NumberOfChannels; k++ ) { m_LSMReaders[k]->SetUpdateTimePoint(i); //send signal for progress bar emit ProgressSent(); } for ( j = 0; j < m_NumberOfChannels; j++ ) { m_LSMReaders[j]->Update(); vtkImageData *image3d = m_LSMReaders[j]->GetOutput(); image3d->GetExtent(extent); for ( k = 0; k < static_cast< unsigned int >( dim[2] ); k++ ) { std::stringstream filename; filename << m_BaseName << "-PL" << setfill('0') << setw(2) << m_Plaque; filename << "-CO" << setfill('0') << setw(2) << m_Column; filename << "-RO" << setfill('0') << setw(2) << m_Row; filename << "-ZT" << setfill('0') << setw(2) << m_ZTile; filename << "-YT" << setfill('0') << setw(2) << m_YTile; filename << "-XT" << setfill('0') << setw(2) << m_XTile; filename << "-TM" << setfill('0') << setw(4) << i; filename << "-ch" << setfill('0') << setw(2) << j; filename << "-zs" << setfill('0') << setw(4) << k; switch ( m_FileType ) { default: case GoFigure::PNG: { filename << ".png"; break; } case GoFigure::TIFF: { filename << ".tiff"; break; } } file << "" << std::endl; file << "Filename " << filename.str() << std::endl; file << "DateTime " << timeStr << std::endl; file << "StageX 1000" << std::endl; file << "StageY -1000" << std::endl; file << "Pinhole 44.216" << std::endl; file << "" << std::endl; vtkSmartPointer< vtkExtractVOI > extract = vtkSmartPointer< vtkExtractVOI >::New(); extract->SetSampleRate(1, 1, 1); extract->SetInput(image3d); extract->SetVOI(extent[0], extent[1], extent[2], extent[3], k, k); extract->Update(); vtkImageData *image2d = extract->GetOutput(); std::string final_filename = iMegaPath; final_filename += filename.str(); switch ( m_FileType ) { default: case GoFigure::PNG: { vtkWriteImage< vtkPNGWriter >(image2d, final_filename); break; } case GoFigure::TIFF: { vtkWriteImage< vtkTIFFWriter >(image2d, final_filename); break; } } //send signal for progress bar emit ProgressSent(); } } } file.close(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int ConversionLsmToMegaThread::GetNumberOfPoints() { int total = m_NumberOfChannels * m_NumberOfTimePoints + m_NumberOfChannels + m_NumberOfTimePoints * m_NumberOfChannels * m_Dim; return total; } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/CMakeLists.txt0000644000175000017500000003356711667757442020216 0ustar mathieumathieuIF( WIN32 ) IF( NOT CYGWIN ) IF( NOT MINGW ) IF( BUILD_SHARED_LIBS ) ADD_DEFINITIONS( -DQGoGUI_EXPORT ) ENDIF( BUILD_SHARED_LIBS ) ENDIF( NOT MINGW ) ENDIF( NOT CYGWIN ) ENDIF( WIN32 ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/QGoGUILibConfigure.h.in ${CMAKE_CURRENT_BINARY_DIR}/QGoGUILibConfigure.h @ONLY IMMEDIATE ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/QGoAboutWidget.cxx.in ${CMAKE_CURRENT_BINARY_DIR}/QGoAboutWidget.cxx @ONLY IMMEDIATE ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/QGoNetworkUtilities.cxx.in ${CMAKE_CURRENT_BINARY_DIR}/QGoNetworkUtilities.cxx @ONLY IMMEDIATE ) SET( QGoGUILIB_SRC QGoImageView.cxx QGoImageView2D.cxx QGoImageView3D.cxx QGoPrintDatabase.cxx QGoImageInfo.cxx QGoLUTDialog.cxx TraceEditing/QGoManualSegmentationSettingsDialog.cxx QGoTabElementBase.cxx QGoTabImageView2D.cxx QGoTabImageView3D.cxx QGoTabImageView3DwT.cxx QGoTabImageViewElementBase.cxx QGoTabImageViewNDBase.cxx QGoNavigationDockWidget.cxx QSplitterChild.cxx QGoTableWidget.cxx SnapshotHelper.cxx QGoCreateMeshDialog.cxx QGoLsmToMegaExportDialog.cxx ConversionLsmToMegaThread.cxx QTextEditChild.cxx QGoNameDescriptionInputDialog.cxx QGoDockWidgetStatus.cxx QGoDeleteFromListDialog.cxx QGoTraceSettingsWidget.cxx QGoColorComboBox.cxx QGoSelectedColorComboBox.cxx QGoCollectionColorComboBox.cxx QGoComboBox.cxx QGoColorCodingDialog.cxx QGoDockWidget.cxx QGoToolBarStatus.cxx # trace containers VisualizationTraceContainers/ContourContainer.cxx VisualizationTraceContainers/MeshContainer.cxx VisualizationTraceContainers/ContourMeshContainer.cxx VisualizationTraceContainers/TrackContainer.cxx VisualizationTraceContainers/LineageContainer.cxx # Wizard Wizard/QGoDBInitializationWizard.cxx Wizard/QGoDBInitCreateUserPage.cxx Wizard/QGoDBInitCreateAuthorsPage.cxx Wizard/QGoDBInitCreateMicroscopePage.cxx Wizard/QGoOpenCreateImgSessionPage.cxx Wizard/QGoOpenCreateProjectPage.cxx Wizard/QGoConnectServerPage.cxx Wizard/QGoCreateImgSessionPage.cxx Wizard/QGoWizardDB.cxx # DB Managers DBManager/QGoDBTraceManager.cxx DBManager/QGoDBContourManager.cxx DBManager/QGoDBMeshManager.cxx DBManager/QGoDBTrackManager.cxx DBManager/QGoDBLineageManager.cxx DBManager/QGoDBNameDescEntityManager.cxx DBManager/QGoDBCellTypeManager.cxx DBManager/QGoDBSubCellTypeManager.cxx DBManager/QGoDBColorManager.cxx DBManager/QGoDBBookmarkManager.cxx # for the tracks QGoTrackViewDockWidget.cxx QGoTrackEditingWidget.cxx #for the lineages QGoLineageViewDockWidget.cxx #--manual segmentation-- TraceEditing/QGoContourManualSegmentation.cxx TraceEditing/QGoContourManualSegmentationWidget.cxx TraceEditing/QGoFilterChanAndVese.cxx TraceEditing/QGoFilterShape.cxx TraceEditing/QGoFilterWatershed.cxx TraceEditing/QGoTraceEditingWidget.cxx TraceEditing/QGoModesManagerWidget.cxx TraceEditing/QGoAlgorithmsManagerWidget.cxx TraceEditing/QGoAlgorithmWidget.cxx TraceEditing/QGoMeshEditingWidgetManager.cxx TraceEditing/QGoContourEditingWidgetManager.cxx TraceEditing/QGoTraceEditingWidgetManager.cxx TraceEditing/QGoSegmentationAlgo.cxx TraceEditing/QGoContourLevelSetAlgo.cxx TraceEditing/QGoMeshLevelSetAlgo.cxx TraceEditing/QGoMeshShapeAlgo.cxx TraceEditing/QGoMeshWaterShedAlgo.cxx TraceEditing/QGoMeshSplitDanielssonDistanceAlgo.cxx TraceEditing/QGoMeshMergeConvexHullAlgo.cxx TraceEditing/QGoWaterShedAlgo.cxx TraceEditing/QGoSetOfContoursWaterShedAlgo.cxx TraceEditing/QGoSetOfContoursLevelSetAlgo.cxx TraceEditing/QGoLevelSetAlgo.cxx TraceEditing/QGoShapeAlgo.cxx TraceEditing/QGoSplitDanielssonDistanceAlgo.cxx TraceEditing/QGoMergeConvexHullAlgo.cxx TraceEditing/QGoSetOfContoursShapeAlgo.cxx TraceEditing/QGoSemiAutoSegmentationAlgo.cxx TraceEditing/QGoSplitSegmentationAlgo.cxx TraceEditing/QGoFilterSemiAutoBase.cxx # transfer function widget TransferFunctionEditor/QGoTransferFunctionDockWidget.cxx TransferFunctionEditor/GoTransferFunctionEditorWidget.cxx TransferFunctionEditor/GoTransferFunctionWidget.cxx TransferFunctionEditor/hoverpoints.cpp # lineage viewer LineageViewer/QGoLineageViewerWidget.cxx ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/QGoAboutWidget.cxx ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/QGoNetworkUtilities.cxx ) SET_SOURCE_FILES_PROPERTIES( QGoTabElementBase.cxx QGoTabImageViewNDBase.cxx QGoTabImageViewElementBase.cxx QGoImageView.cxx QGoFilterSemiAutoBase.cxx DBManager/QGoDBTraceManager.cxx QGoDBNameDescEntityManager.cxx QGoColorComboBox.cxx ABSTRACT ) IF( BUILD_COMPARETOOL ) SET( QGoGUILIB_SRC ${QGoGUILIB_SRC} SynchronizedViews/QGoSynchronizedView.cxx SynchronizedViews/QGoSynchronizedView2D.cxx SynchronizedViews/QGoSynchronizedView3D.cxx SynchronizedViews/QGoSynchronizedView2DCallbacks.cxx SynchronizedViews/QGoSynchronizedView3DCallbacks.cxx SynchronizedViews/QGoSynchronizedViewManager.cxx ) ENDIF( BUILD_COMPARETOOL ) #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- #ADD THIS SRCS IF ENABLE_VIDEO_RECORD is ON IF( ENABLE_VIDEO_RECORD_FFMPEG ) SET(QGoGUILIB_SRC ${QGoGUILIB_SRC} Video/vtkRenderWindowMovieRecorder.cxx Video/vtkFFMPEGRenderWindowRecorder.cxx Video/QGoVideoRecorder.cxx ) ENDIF( ENABLE_VIDEO_RECORD_FFMPEG ) #ADD THIS SRCS IF ENABLE_VIDEO_RECORD is ON IF( ENABLE_VIDEO_RECORD_AVI ) SET(QGoGUILIB_SRC ${QGoGUILIB_SRC} Video/vtkRenderWindowMovieRecorder.cxx Video/vtkAVIRenderWindowRecorder.cxx Video/QGoVideoRecorder.cxx ) ENDIF( ENABLE_VIDEO_RECORD_AVI ) #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- SET( QGoGUILIB_HDRS QGoImageView.h QGoImageView2D.h QGoImageView3D.h QGoImageInfo.h QGoLUTDialog.h TraceEditing/QGoManualSegmentationSettingsDialog.h QGoPrintDatabase.h QGoTabElementBase.h QGoTabImageView2D.h QGoTabImageView3D.h QGoTabImageView3DwT.h QGoTabImageViewElementBase.h QGoTabImageViewNDBase.h QGoNavigationDockWidget.h QSplitterChild.h QGoTableWidget.h QGoCreateMeshDialog.h QGoLsmToMegaExportDialog.h ConversionLsmToMegaThread.h QTextEditChild.h QGoNameDescriptionInputDialog.h QGoDockWidgetStatus.h QGoDeleteFromListDialog.h QGoTraceSettingsWidget.h QGoAboutWidget.h QGoNetworkUtilities.h QGoColorComboBox.h QGoSelectedColorComboBox.h QGoCollectionColorComboBox.h QGoComboBox.h QGoColorCodingDialog.h QGoDockWidget.h QGoToolBarStatus.h # Trace containers VisualizationTraceContainers/ContourContainer.h VisualizationTraceContainers/MeshContainer.h VisualizationTraceContainers/ContourMeshContainer.h VisualizationTraceContainers/TrackContainer.h VisualizationTraceContainers/LineageContainer.h # Wizard Wizard/QGoConnectServerPage.h Wizard/QGoCreateImgSessionPage.h Wizard/QGoOpenCreateImgSessionPage.h Wizard/QGoOpenCreateProjectPage.h Wizard/QGoWizardDB.h Wizard/QGoDBInitializationWizard.h Wizard/QGoDBInitCreateUserPage.h Wizard/QGoDBInitCreateAuthorsPage.h Wizard/QGoDBInitCreateMicroscopePage.h # DB Manager DBManager/QGoDBBookmarkManager.h DBManager/QGoDBNameDescEntityManager.h DBManager/QGoDBCellTypeManager.h DBManager/QGoDBSubCellTypeManager.h DBManager/QGoDBColorManager.h DBManager/QGoDBTraceManager.h DBManager/QGoDBContourManager.h DBManager/QGoDBMeshManager.h DBManager/QGoDBTrackManager.h DBManager/QGoDBLineageManager.h # for the tracks QGoTrackViewDockWidget.h QGoTrackEditingWidget.h # for the lineages: QGoLineageViewDockWidget.h #--manual segmentation-- TraceEditing/QGoContourManualSegmentation.h TraceEditing/QGoContourManualSegmentationWidget.h TraceEditing/QGoFilterChanAndVese.h TraceEditing/QGoFilterShape.h TraceEditing/QGoFilterWatershed.h TraceEditing/QGoFilterWatershed.h TraceEditing/QGoTraceEditingWidget.h TraceEditing/QGoModesManagerWidget.h TraceEditing/QGoAlgorithmsManagerWidget.h TraceEditing/QGoAlgorithmWidget.h TraceEditing/QGoMeshEditingWidgetManager.h TraceEditing/QGoContourEditingWidgetManager.h TraceEditing/QGoSegmentationAlgo.h TraceEditing/QGoSemiAutoSegmentationAlgo.h TraceEditing/QGoSplitSegmentationAlgo.h TraceEditing/QGoTraceEditingWidgetManager.h TraceEditing/QGoFilterSemiAutoBase.h # transfer function widget TransferFunctionEditor/QGoTransferFunctionDockWidget.h TransferFunctionEditor/GoTransferFunctionEditorWidget.h TransferFunctionEditor/GoTransferFunctionWidget.h TransferFunctionEditor/hoverpoints.h # lineage viewer LineageViewer/QGoLineageViewerWidget.h ) IF( BUILD_COMPARETOOL ) SET( QGoGUILIB_HDRS ${QGoGUILIB_HDRS} SynchronizedViews/QGoSynchronizedView.h SynchronizedViews/QGoSynchronizedView2D.h SynchronizedViews/QGoSynchronizedView3D.h SynchronizedViews/QGoSynchronizedView2DCallbacks.h SynchronizedViews/QGoSynchronizedView3DCallbacks.h SynchronizedViews/QGoSynchronizedViewManager.h ) ENDIF( BUILD_COMPARETOOL ) #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- # ADD THIS HEADERS IF ENABLE_VIDEO_RECORD_FFMPEG IS ON IF( ENABLE_VIDEO_RECORD_FFMPEG ) SET(QGoGUILIB_HDRS ${QGoGUILIB_HDRS} Video/QGoVideoRecorder.h ) ENDIF( ENABLE_VIDEO_RECORD_FFMPEG ) # ADD THIS HEADERS IF ENABLE_VIDEO_RECORD_AVI IS ON IF( ENABLE_VIDEO_RECORD_AVI ) SET(QGoGUILIB_HDRS ${QGoGUILIB_HDRS} Video/QGoVideoRecorder.h ) ENDIF( ENABLE_VIDEO_RECORD_AVI ) #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- SET( QGoGUILIB_UI #base dockwidget Resources/SegmentationDockWidgetBase.ui #segmentation widget #Resources/SegmentationSeedBaseWidget.ui # manual contour segmentation dock widget Resources/ManualSegmentationSettingsDlg.ui Resources/ContourManualSegmentationWidget.ui # other Resources/NavigationDockWidget.ui Resources/TransferFunctionDockWidget.ui Resources/LsmToMegaExportDialog.ui Resources/QNameDescriptionInputDialog.ui # for tracks Resources/TrackEditingWidget.ui # lineage viewer LineageViewer/QGoLineageViewerWidget.ui ) IF( BUILD_COMPARETOOL ) SET( QGoGUILIB_UI ${QGoGUILIB_UI} Resources/QGoSynchronizedView.ui ) ENDIF( BUILD_COMPARETOOL ) #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- # ADD THIS UI IF ENABLE_VIDEO_RECORD_FFMPEG IS ON IF( ENABLE_VIDEO_RECORD_FFMPEG ) SET(QGoGUILIB_UI ${QGoGUILIB_UI} Resources/NewVideoRecorderDockWidget.ui ) ENDIF( ENABLE_VIDEO_RECORD_FFMPEG ) # ADD THIS UI IF ENABLE_VIDEO_RECORD_AVI IS ON IF( ENABLE_VIDEO_RECORD_AVI ) SET(QGoGUILIB_UI ${QGoGUILIB_UI} Resources/NewVideoRecorderDockWidget.ui ) ENDIF( ENABLE_VIDEO_RECORD_AVI ) #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- QT4_WRAP_UI( QGoGUILIB_UI_H ${QGoGUILIB_UI} ) QT4_WRAP_CPP( QGoGUILIB_MOC ${QGoGUILIB_HDRS} ) QT4_ADD_RESOURCES( QGoGUI_QRC ${QGoResourceFile} ) SET_SOURCE_FILES_PROPERTIES( ${QGoGUILIB_SRC} PROPERTIES OBJECT_DEPENDS "${QGoGUILIB_UI_H}" ) SET_SOURCE_FILES_PROPERTIES( ${QGoGUILIB_MOC} PROPERTIES OBJECT_DEPENDS "${QGoGUILIB_UI_H}" ) ADD_LIBRARY( QGoGui ${QGoGUILIB_SRC} ${QGoGUILIB_MOC} ${QGoGUI_QRC} ) SET( QGoGUI_LIBS ${ITK_LIBRARIES} QVTK QGoIO vtkRenderingAddOn2 PoissonReconstruction ctk itkQt ) TARGET_LINK_LIBRARIES( QGoGui ${QGoGUI_LIBS} ) SET_TARGET_PROPERTIES( QGoGui PROPERTIES VERSION ${GOFIGURE2_LIB_VERSION} SOVERSION ${GOFIGURE2_LIB_VERSION} ) # Runtime INSTALL( TARGETS QGoGui EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} NAMELINK_SKIP COMPONENT Libraries ) # Development INSTALL( TARGETS QGoGui EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries NAMELINK_ONLY ) FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE( GLOB __source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/*.txx" ) FILE( GLOB __binary_file_h "${CMAKE_CURRENT_BINARY_DIR}/*.h" ) FILE( GLOB __binary_file_txx "${CMAKE_CURRENT_BINARY_DIR}/*.txx" ) FILE( GLOB __source_video_h "${CMAKE_CURRENT_SOURCE_DIR}/Video/*.h" ) FILE( GLOB __binary_video_h "${CMAKE_CURRENT_BINARY_DIR}/Video/*.h" ) FILE( GLOB __source_sync_h "${CMAKE_CURRENT_SOURCE_DIR}/SynchronizedViews/*.h" ) FILE( GLOB __binary_sync_h "${CMAKE_CURRENT_BINARY_DIR}/SynchronizedViews/*.h" ) FILE( GLOB __source_tracevisu_h "${CMAKE_CURRENT_SOURCE_DIR}/VisualizationTraceContainers/*.h" ) FILE( GLOB __source_trace_visu_txx "${CMAKE_CURRENT_SOURCE_DIR}/VisualizationTraceContainers/*.txx" ) FILE( GLOB __binary_tracevisu_h "${CMAKE_CURRENT_BINARY_DIR}/VisualizationTraceContainers/*.h" ) FILE( GLOB __binary_tracevisu_txx "${CMAKE_CURRENT_BINARY_DIR}/VisualizationTraceContainers/*.txx" ) FILE( GLOB __source_wizard_h "${CMAKE_CURRENT_SOURCE_DIR}/Wizard/*.h" ) FILE( GLOB __binary_tracevisu_h "${CMAKE_CURRENT_BINARY_DIR}/Wizard/*.h" ) INSTALL( FILES ${__source_file_h} ${__source_file_txx} ${__binary_file_h} ${__binary_file_txx} ${__source_video_h} ${__binary_video_h} ${__source_sync_h} ${__binary_sync_h} ${__source_tracevisu_h} ${__source_trace_visu_txx} ${__binary_tracevisu_h} ${__binary_tracevisu_txx} ${__source_wizard_h} ${__binary_tracevisu_h} ${QGoGUILIB_UI_H} DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Code/GUI/lib/QTextEditChild.h0000644000175000017500000000453411667757442020436 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QTextEditChild_h #define __QTextEditChild_h #include /** \class QTextEditChild \brief in the QTextEdit class, there is no method to have a restriction on the number of characters the user can enter, that's the reason for the creation of this class */ class QTextEditChild:public QTextEdit { Q_OBJECT public: explicit QTextEditChild(QWidget *iParent = 0, int iNumberMaxCharacters = 1000); virtual ~QTextEditChild(); protected: int m_MaxCharacters; protected slots: void RestrainInputCharacters(); private: Q_DISABLE_COPY(QTextEditChild); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoDockWidgetStatus.h0000644000175000017500000000621111667757442021450 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDockWidgetStatus_h #define __QGoDockWidgetStatus_h #include #include #include #include "QGoDockWidget.h" class QGoDockWidgetStatus:public QObject { Q_OBJECT public: explicit QGoDockWidgetStatus(QGoDockWidget *iW); explicit QGoDockWidgetStatus(const QGoDockWidgetStatus & iS); explicit QGoDockWidgetStatus(QGoDockWidget *iW, Qt::DockWidgetArea iArea, const bool & iVisibility, const bool & iAttached, QMainWindow* iMainWindow = 0); virtual ~QGoDockWidgetStatus(); QGoDockWidget *m_DockWidget; /** \brief Position */ Qt::DockWidgetArea m_Area; Qt::DockWidgetArea m_DefaultArea; /** \brief is Visible */ bool m_Visibility; /** \brief Attached to QGoMainWindow*/ bool m_Attached; /** \brief which main window the dock widget belongs to*/ QMainWindow* m_MainWindow; public slots: /** \brief set the area of the m_dockwidget*/ void SetArea(Qt::DockWidgetArea iArea); /** \brief set the visibility of the m_dockwidget*/ void SetVisibility(bool iVisibility); /** \brief set the floated status of the m_dockwidget*/ void SetAttached(bool iAttached); protected: /** \brief set the signal slots connections to update m_visibility, m_Attached and m_Area*/ void SetConnections(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoNavigationDockWidget.h0000644000175000017500000001143111667757442022264 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoNavigationDockWidget_h #define __QGoNavigationDockWidget_h #include #include "ui_NavigationDockWidget.h" #include "GoFigureGlobalDefinition.h" #include "QGoDockWidget.h" #include "QGoGUILibConfigure.h" class QHBoxLayout; class QVBoxLayout; class QPushButton; class QCheckBox; /** \class QGoNavigationDockWidget * \brief Dock Widget for browsing images (changing slice, time point...) * \ingroup GUI */ class QGOGUILIB_EXPORT QGoNavigationDockWidget: public QGoDockWidget, private Ui::NavigationDockWidget { Q_OBJECT public: /** \brief Constructor */ explicit QGoNavigationDockWidget( QWidget *parent = 0, const GoFigure::TabDimensionType & iDim = GoFigure::THREE_D_WITH_T); /** \brief Destructor */ ~QGoNavigationDockWidget(); /** \brief Set the extent of the images in the X direction * \param[in] iMin XMin * \param[in] iMax XMax */ void SetXMinimumAndMaximum(const int & iMin, const int & iMax); /** \brief Set the extent of the images in the Y direction * \param[in] iMin YMin * \param[in] iMax YMax */ void SetYMinimumAndMaximum(const int & iMin, const int & iMax); /** \brief Set the extent of the images in the Z direction * \param[in] iMin ZMin * \param[in] iMax ZMax */ void SetZMinimumAndMaximum(const int & iMin, const int & iMax); /** \brief Set the extent of the images in the Time * \param[in] iMin TMin * \param[in] iMax TMax */ void SetTMinimumAndMaximum(const int & iMin, const int & iMax); // new channels representation void AddChannel(const QString& iName, const QColor& iColor,const unsigned int& iNumber, const bool& iChecked); void ModifyChannel(QString iName, QColor iColor); void VisibilityListChannels(const bool& iVisibility); void AddDoppler(const QString& iName, const QColor& iColor,const unsigned int& iNumber, const bool& iChecked); void VisibilityListDoppler(const bool& iVisibility); void setChannelName(QString iChannelName); void DeleteDopplerWidgets(); public slots: /** Set X Slice */ void SetXSlice(int iSlice); /** Set Y Slice */ void SetYSlice(int iSlice); /** Set Z Slice */ void SetZSlice(int iSlice); /** Set Time Point */ void SetTSlice(int iSlice); /** Move to the previous time point using shortcuts */ void MoveToPreviousTimePoint(); /** Move to the next time point using shortcuts */ void MoveToNextTimePoint(); void UpdateWidget(int); void visibilityChanged(bool); int GetFirstVisibleChannel(); signals: void XSliceChanged(int Slice); void YSliceChanged(int Slice); void ZSliceChanged(int Slice); void TSliceChanged(int Slice); void ModeChanged(int Mode); void StepChanged(int Step); void visibilityChanged(QString, bool); void openTransferFunctionEditor(QString); void DopplerSizeChanged(int iSize); protected: GoFigure::TabDimensionType m_Dimension; private: QList m_ListPushButtons; QList m_ListCheckBoxes; QList m_ListDoppler; bool m_Classic; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoTabImageView3DwT.h0000644000175000017500000005250311667757442021233 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTabImageView3DwT_h #define __QGoTabImageView3DwT_h #include "QGoTabElementBase.h" #include "GoFigureFileInfoMultiIndexContainerHelper.h" #include "itkMegaCaptureReader.h" #include "ContourContainer.h" #include "MeshContainer.h" #include "TrackContainer.h" #include "TraceContainerBase.h" #include "QGoPrintDatabase.h" #include "GoFigureMeshAttributes.h" #include #include #include #include "vtkSmartPointer.h" #include "GoImageProcessor.h" // base segmentation dock widget class QGoContourEditingWidgetManager; class QGoMeshEditingWidgetManager; //class QGoContourSegmentationBaseDockWidget; //class QGoMeshSegmentationBaseDockWidget; //track dockwidget class QGoTrackViewDockWidget; //lineage dock widget class QGoLineageViewDockWidget; // lineage viewer class QGoLineageViewerWidget; class QGoImageView3D; class QGoNavigationDockWidget; class QGoTransferFunctionDockWidget; class GoTransferFunctionEditorWidget; class QGoPrintDatabase; #if defined ENABLEFFMPEG || defined ENABLEAVI class QGoVideoRecorder; #endif /* ENABLEFFMPEG */ class vtkLSMReader; class vtkImageData; class vtkMySQLDatabase; class vtkProperty; // class vtkQuadricLODActor; class vtkActor; class vtkViewImage2D; class vtkProp3D; class QGoSeedsSegmentation; #include "QGoGUILibConfigure.h" /** \class QGoTabImageView3DwT \brief \example GUI/lib/qgotabimageview3dwt.cxx */ class QGOGUILIB_EXPORT QGoTabImageView3DwT : public QGoTabElementBase { Q_OBJECT public: /** * \brief Default Constructor * \param parent */ explicit QGoTabImageView3DwT(QWidget *parent = 0); /** * \brief Destructor */ virtual ~QGoTabImageView3DwT(); typedef QGoTabElementBase::QGoDockWidgetStatusPair QGoDockWidgetStatusPair; typedef QGoPrintDatabase::NamesDescrContainerType NamesDescrContainerType; typedef QGoPrintDatabase::IDWithColorData IDWithColorData; /** * \brief * \return */ GoFigure::TabDimensionType GetTabDimensionType() const; /** * * \param[in] iReader * \param[in] iTimePoint */ void SetLSMReader(vtkLSMReader *iReader, const int & iTimePoint); /** * * \param[in] iContainer MegaCapture file container * \param[in] iFileType file type (PNG, JPEG...) * \param[in] iHeader path to MegaCapture header * \param[in] iTimePoint Time point */ void SetMegaCaptureFile( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const GoFigure::FileType & iFileType, const std::string & iHeader, const unsigned int & iTimePoint); /** * \brief * \param parent */ void setupUi(QWidget *parent); void CreateModeToolBar(QMenu* iMenu, QToolBar* iToolBar); /** * \brief * \param parent */ void retranslateUi(QWidget *parent); /** * */ virtual void WriteSettings() {} /** * */ virtual void ReadSettings() {} ContourContainer * GetContourContainer() { return m_ContourContainer; } MeshContainer * GetMeshContainer() { return m_MeshContainer; } TrackContainer * GetTrackContainer() { return m_TrackContainer; } template< class TIndex > void AddMeshFromNodes( typename ContourMeshContainer::MultiIndexContainerType::index< TIndex >::type::iterator iIt ) { VisualizeMesh< TIndex >(iIt); } template< class TIndex > void AddTrackFromNodes( typename TrackContainer::MultiIndexContainerType::index< TIndex >::type::iterator iIt ) { VisualizeTrack< TIndex >(iIt); } //------------------------------------------------------------------------- template< class TIndex > void AddContourFromNodes( typename ContourContainer::MultiIndexContainerType::index< TIndex >::type::iterator iIt ) { vtkPolyData *nodes = iIt->Nodes; if ( nodes->GetNumberOfPoints() > 2 ) { int dir = ContourMeshContainer::ComputeDirectionFromContour(nodes); if ( dir != -1 ) { m_ImageView->EnableContourWidget(true); m_ImageView->InitializeContourWidgetNodes(dir, nodes); vtkPolyData *contour = m_ImageView->GetContourRepresentationAsPolydata(dir); VisualizeContour< TIndex >(iIt, contour); m_ImageView->InitializeContourWidgetNodes(dir, NULL); m_ImageView->EnableContourWidget(false); } } } int GetSliceViewXY() const; int GetSliceViewXZ() const; int GetSliceViewYZ() const; int GetTimePoint() const; int GetTimeInterval() const; //QGoTraceManualEditingWidget * GetTraceManualEditingWidget(); QGoPrintDatabase *m_DataBaseTables; GoFigureMeshAttributes ComputeMeshAttributes(vtkPolyData *iMesh, const bool& iIntensity, const unsigned int& iTCoord ); void InitializeToolsForTracesToolBar(QMenu* iMenu, QToolBar* iToolBar); void InitializeTraceSettingsToolBar(QToolBar* iToolBar); /** \brief Creates actors for the contours which are at the given time points in the container. The actors are not visible by default. (see ShowTraces) \param[in] iTPointToLoad Time points to be used to create actors. */ void CreateContoursActorsFromVisuContainer( std::list iTPointToLoad); void CreateContoursActorsFromVisuContainer(); /** \brief Creates actors for the meshes which are at the given time points in the container. The actors are not visible by default. (see ShowTraces) \param[in] iTPointToLoad Time points to be used to create actors. */ void CreateMeshesActorsFromVisuContainer( std::list iTPointToLoad); void CreateMeshesActorsFromVisuContainer(); /** \brief Show traces from container which are at the given time point. Only updates contours and meshes since tracks and lineages go over several time points. \param[in] iTimePoint Visible time point. */ void ShowTraces(const unsigned int& iTimePoint); void UpdateTFEditor(); signals: void TimePointChanged(int TimePoint); void SliceViewXYChanged(int Slice); void SliceViewXZChanged(int Slice); void SliceViewYZChanged(int Slice); void FullScreenViewChanged(int FullScreen); void UpdateBookmarkOpenActions(std::vector< QAction * > ); void ContourRepresentationPropertiesChanged(); void StartMeshSegmentation(vtkPoints *iPoints); void StartContourSegmentation(vtkPoints *iPoints); void RequestedPolydatas(std::list< vtkPolyData* >); public slots: void AdjustWindowLevel(double iMin, double iMax); void SetTimePoint(const int &); void TakeSnapshot(); void SetSliceView(); void GoToDefaultMenu(bool iEnable = false); void updatePoints(QString, std::map< unsigned int, unsigned int >, QColor, int, int, int); #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) void SetRendererWindow(int); #endif /* ENABLEVIDEORECORD */ QString SnapshotViewXY( GoFigure::FileType iType, QString iBaseName = QString("snapshot-xy-") ); QString SnapshotViewXZ( GoFigure::FileType iType, QString BaseName = QString("snapshot-xz-") ); QString SnapshotViewYZ( GoFigure::FileType iType, QString iBaseName = QString("snapshot-yz-") ); QString SnapshotViewXYZ( GoFigure::FileType iType, QString iBaseName = QString("snapshot-xyz-") ); void SetSliceViewXY(int ); void SetSliceViewXZ(int ); void SetSliceViewYZ(int ); void SetFullScreenView(int iS); void Quadview(); void FullScreenViewXY(); void FullScreenViewXZ(); void FullScreenViewYZ(); void FullScreenViewXYZ(); //void ChangeLookupTable(); void ChangeBackgroundColor(); void ModeChanged(int iChannel); void StepChanged(int iStep); void DopplerSizeChanged( int iSize); void ValidateContour(int iTCoord); int SaveAndVisuContour(int iTCoord, vtkPolyData *iView = NULL); //void SaveAndVisuContoursList(std::vector* iContours); /** \brief Save a mesh in the database and render the mesh * at the given time point. * \param[in] iCollection Collection ID we want the mesh to belong to. * if -1, we get the collection ID from the trace editing widget. \todo to be renamed */ void SaveAndVisuMesh(vtkPolyData *iView, unsigned int iTCoord, int iCollection = -1); /** \brief Save a mesh in the database and render the mesh. * at the current time point */ void SaveInDBAndRenderMeshForVisu( std::vector iVectPolydata, int iTCoord); void SplitInDBAndRenderMeshForVisu( std::vector iVectPolydata); void MergeInDBAndRenderMeshForVisu( vtkPolyData * iVectPolydata); void SaveInDBAndRenderSetOfContoursForVisu( std::vector >, int); void SaveInDBAndRenderContourForVisu( std::vector iVectPolydata, int iTCoord); void ReEditContour(const unsigned int & iId); void HighlightPickedActor(); void VisibilityPickedActor(); void Change3DPerspectiveToAxial(); void Change3DPerspectiveToCoronal(); void Change3DPerspectiveToSagittal(); void CreateMeshFromSelectedContours(std::list< unsigned int > ListContourIDs, int iMeshID); void AddContourForMeshToContours(vtkPolyData *); void visibilityChanged(QString iName, bool iVisibility); void updateSlot(); void PolydatasRequested(); protected: QGoImageView3D * m_ImageView; vtkProperty *m_HighlightedContoursProperty; vtkProperty *m_HighlightedMeshesProperty; GoImageProcessor* m_ImageProcessor; // TODO Nicolas don't need it... itk::MegaCaptureReader::Pointer m_MegaCaptureReader; GoFigureFileInfoHelperMultiIndexContainer m_FileList; GoFigure::FileType m_FileType; QColor m_BackgroundColor; QAction * m_BackgroundColorAction; QAction * m_TakeSnapshotAction; QToolBar* m_TraceSettingsToolBar; float m_IntersectionLineWidth; int m_PCoord; int m_RCoord; int m_CCoord; int m_XTileCoord; int m_YTileCoord; int m_ZTileCoord; int m_TCoord; QGoNavigationDockWidget *m_NavigationDockWidget; QGoTransferFunctionDockWidget *m_TransferFunctionDockWidget; // base segmentation dockwidget for contours //QGoContourSegmentationBaseDockWidget *m_ContourSegmentationDockWidget; // base segmentation dockwidget for meshes //QGoMeshSegmentationBaseDockWidget *m_MeshSegmentationDockWidget; QGoMeshEditingWidgetManager* m_MeshEditingWidget; QGoContourEditingWidgetManager* m_ContourEditingWidget; QGoTrackViewDockWidget* m_TrackViewDockWidget; QGoLineageViewDockWidget* m_LineageViewDockWidget; QGoLineageViewerWidget* m_QGoLineageViewerWidget; QGoTraceSettingsWidget* m_TraceSettingsWidget; std::vector< vtkPoints* > m_Seeds; //std::vector m_OrderedSeeds; ContourContainer *m_ContourContainer; MeshContainer *m_MeshContainer; TrackContainer *m_TrackContainer; LineageContainer *m_LineageContainer; //bool m_TraceWidgetRequiered; /// \todo remove m_FFMPEGWriter and m_AVIWriter from this class #if defined ENABLEFFMPEG || defined ENABLEAVI QGoVideoRecorder *m_VideoRecorderWidget; #endif /* ENABLEFFMPEG || ENABLEAVI */ void SaveContour(vtkPolyData *contour, vtkPolyData *contour_nodes, int iTCoord); std::vector< vtkActor * > VisualizeTrace(vtkPolyData *iTrace, double* iRGBA); //int VisualizeContour(const int& iContourID, // const unsigned int& iTCoord, vtkPolyData* contour, // vtkPolyData* contour_nodes, const double iRGBA[4]); template< class TIndex > void VisualizeContour( typename ContourContainer::MultiIndexContainerType::template index< TIndex >::type::iterator iIt, vtkPolyData *iContour) { if ( ( iContour->GetNumberOfPoints() > 2 ) && ( m_TCoord >= 0 ) ) { bool visibility = ( static_cast< unsigned int >( m_TCoord ) == iIt->TCoord ); bool highlighted = false; vtkPolyData *contour_copy = vtkPolyData::New(); contour_copy->DeepCopy(iContour); AddTraceIDIntoPolydata(contour_copy, iIt->TraceID, "CONTOUR"); VisualizeTraceBase< ContourContainer, TIndex >( m_ContourContainer, iIt, highlighted, visibility, contour_copy ); contour_copy->Delete(); } } template< class TIndex > void VisualizeMesh( typename MeshContainer::MultiIndexContainerType::template index< TIndex >::type::iterator iIt) { if ( iIt->Nodes ) { bool highlighted = false; bool visibility = false; AddTraceIDIntoPolydata(iIt->Nodes, iIt->TraceID, "MESH"); VisualizeTraceBase< MeshContainer, TIndex >( m_MeshContainer, iIt, highlighted, visibility ); } } template< class TIndex > void VisualizeTrack( typename TrackContainer::MultiIndexContainerType::template index< TIndex >::type::iterator iIt) { if ( iIt->Nodes ) { bool highlighted = false; bool visibility = false; AddTraceIDIntoPolydata(iIt->Nodes, iIt->TraceID, "TRACK"); VisualizeTraceBase< TrackContainer, TIndex >( m_TrackContainer, iIt, highlighted, visibility ); } } template< class TContainer, class TIndex > void VisualizeTraceBase( TContainer* iContainer, typename TContainer::MultiIndexContainerType::template index< TIndex >::type::iterator iIt, const double & iHighlighted, const double & iVisible, vtkPolyData* iContour = NULL ) { const double *iRgba = iIt->rgba; vtkProperty *mesh_property = vtkProperty::New(); mesh_property->SetColor(iRgba[0], iRgba[1], iRgba[2]); mesh_property->SetOpacity(iRgba[3]); vtkPolyData* temp = iIt->Nodes; if( iContour ) { temp = iContour; } std::vector< vtkActor * > mesh_actor = this->AddContour( temp, mesh_property ); mesh_property->Delete(); iContainer->template UpdateVisualizationForGivenElement< TIndex >( iIt, mesh_actor, iHighlighted, iVisible ); } template void CreateConnectionsTraceEditingWidget(int iTimeMin, int iTimeMax, T* iTraceWidget) { m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus( iTraceWidget->GetDockWidget(), Qt::LeftDockWidgetArea, false, true), iTraceWidget->GetDockWidget()) ); QObject::connect(iTraceWidget, SIGNAL(UpdateSeeds() ), this, SLOT(UpdateSeeds() ) ); QObject::connect(iTraceWidget, SIGNAL(ClearAllSeeds() ), this->m_ImageView, SLOT(ClearAllSeeds() ) ); QObject::connect( iTraceWidget, SIGNAL( SetSeedInteractorBehaviour(bool) ), this, SLOT( SeedInteractorBehavior(bool) ) ); } std::vector< int > GetBoundingBox(vtkPolyData *contour); void CreateContour(vtkPolyData *contour_nodes, vtkPolyData *iView); /** * \brief Save mesh in Database * \param[in] iMesh mesh to be saved * \param[in] iTCoord */ void SaveMesh(vtkPolyData *iMesh, int iTCoord, int iCollectionID = -1); void GetBackgroundColorFromImageViewer(); void SetBackgroundColorToImageViewer(); void CreateAllViewActions(); void CreateTracesActions(); void CreateToolsActions(); void CreateBookmarkActions(); //void CreateModeActions(); void CreateVisuDockWidget(); // segmentation dockwidgets //void CreateContourSegmentationDockWidget(); void CreateContourEditingDockWidget(int iTimeMin, int iTimeMax); //void CreateMeshSegmentationDockWidget(); void CreateMeshEditingDockWidget(int iTimeMin, int iTimeMax); void CreateDataBaseTablesConnection(); #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) void CreateVideoRecorderWidget(); #endif /* ENABLEVIDEORECORD */ int *GetImageCoordinatesFromWorldCoordinates(double pos[3]); // std::vector< vtkQuadricLODActor* > std::vector< vtkActor * > AddContour(vtkPolyData *dataset, vtkProperty *property = NULL); // TODO remove megacapture void UpdateImage(); // TODO remove megacaptureZz void BuildDopplerWidget(); /** \brief give the adress for the contours, meshes and tracks container to the QGoPrintDatabase */ void SetTheContainersForDB(); protected slots: void AddBookmark(); void GetTheRelatedToDBActions(); void GetTheOpenBookmarksActions(); void OpenExistingBookmark(); /** \brief slot connected to the toggleaction of the TW, the contour and mesh editing, update the trace and collection name of the trace settings toolbar and widget and check if the trace settings toolbar needs to be shown/hidden */ void SetTraceSettingsToolBarVisible(bool IsVisible); void UpdateSeeds(); void GoToLocation(int iX, int iY, int iZ, int iT); void GoToRealLocation(double iX, double iY, double iZ, int iT); /** * \brief Mouse interaction style allows contours segmentation, according to * the selected type of segmentation */ void ManualInteractorBehavior(bool); /** * \brief Mouse interaction style allows meshes segmentation, according to * the selected type of segmentation */ void SeedInteractorBehavior(bool); /** * \brief Mouse interaction style set as default */ virtual void DefaultInteractorBehavior(bool); /** * \brief Mouse interaction style allows user to zoom in/out volume with all * buttons */ virtual void ZoomInteractorBehavior(bool); /** * \brief Mouse interaction style allows user to Translate volume with all buttons */ virtual void TranslateInteractorBehavior(bool); /** * \brief Mouse interaction style allows user to pick contours */ // void ContourPickingInteractorBehavior(bool); /** * \brief Mouse interaction style allows user to pick contours */ void ActorPickingInteractorBehavior(bool); void DistanceWidgetInteractorBehavior(bool); void AngleWidgetInteractorBehavior(bool); void Box3DPicking(bool); void PlaneWidgetInteractorBehavior(bool); void ImportContours(); void ImportMeshes(); void ImportTracks(); /** \brief access to the megacapture reader to get the entity of interest images through time. updates the navigation widget. */ void StartDopplerView(); /** \brief give the adress for the contours, meshes and tracks container to the QGoPrintDatabase, and make the connection for the status bar once the database variables have been set for the QGoPrintDatabase */ void SetDatabaseContainersAndDelayedConnections(); void AddTraceIDIntoPolydata( vtkPolyData* iPolydata, unsigned int iTraceID, const char* iTrace); /** \brief depending on the doppler/classic mode, update the TimePoints and channels of the mesh and contour widget */ void UpdateTracesEditingWidget(); void EnableVolumeRendering(bool iEnable); void MoveToNextTimePoint(); void MoveToPreviousTimePoint(); private: void InitializeImageRelatedWidget(); void SetUpShortcuts(); void CreateDopplerTFEditor(); void createTransferFunctionEditor(QString iName); std::vector< QString > GetChannelNames(); bool m_VolumeRenderingEnabled; Q_DISABLE_COPY(QGoTabImageView3DwT); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoImageInfo.cxx0000644000175000017500000006546611667757442020452 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoImageInfo.h" #include QGoImageInfo::QGoImageInfo(QWidget *iParent) : QWidget(iParent) { setupUi(this); } QGoImageInfo::~QGoImageInfo() { } void QGoImageInfo::setupUi(QWidget *ImageInfo) { if ( ImageInfo->objectName().isEmpty() ) { ImageInfo->setObjectName( QString::fromUtf8("ImageInfo") ); } ImageInfo->resize(293, 315); QSizePolicy tsizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); tsizePolicy.setHorizontalStretch(0); tsizePolicy.setVerticalStretch(0); tsizePolicy.setHeightForWidth( ImageInfo->sizePolicy().hasHeightForWidth() ); ImageInfo->setSizePolicy(tsizePolicy); verticalLayout = new QVBoxLayout(ImageInfo); verticalLayout->setContentsMargins(3, -1, 3, -1); scrollArea = new QScrollArea(ImageInfo); scrollArea->setWidgetResizable(true); scrollAreaWidgetContents = new QWidget(); scrollAreaWidgetContents->setGeometry( QRect(0, 0, 281, 301) ); gridLayout = new QGridLayout(scrollAreaWidgetContents); TImageStaticlabel = new QLabel(scrollAreaWidgetContents); QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); sizePolicy1.setHeightForWidth( TImageStaticlabel->sizePolicy().hasHeightForWidth() ); TImageStaticlabel->setSizePolicy(sizePolicy1); gridLayout->addWidget(TImageStaticlabel, 0, 0, 1, 1); TImageLabel = new QLabel(scrollAreaWidgetContents); gridLayout->addWidget(TImageLabel, 0, 1, 1, 1); DimensionStaticLabel = new QLabel(scrollAreaWidgetContents); sizePolicy1.setHeightForWidth( DimensionStaticLabel->sizePolicy().hasHeightForWidth() ); DimensionStaticLabel->setSizePolicy(sizePolicy1); gridLayout->addWidget(DimensionStaticLabel, 1, 0, 1, 1); DimensionLabel = new QLabel(scrollAreaWidgetContents); QSizePolicy sizePolicy2(QSizePolicy::Expanding, QSizePolicy::Preferred); sizePolicy2.setHorizontalStretch(0); sizePolicy2.setVerticalStretch(0); sizePolicy2.setHeightForWidth( DimensionLabel->sizePolicy().hasHeightForWidth() ); DimensionLabel->setSizePolicy(sizePolicy2); gridLayout->addWidget(DimensionLabel, 1, 1, 1, 1); ChannelStaticLabel = new QLabel(scrollAreaWidgetContents); sizePolicy1.setHeightForWidth( ChannelStaticLabel->sizePolicy().hasHeightForWidth() ); ChannelStaticLabel->setSizePolicy(sizePolicy1); gridLayout->addWidget(ChannelStaticLabel, 2, 0, 1, 1); ChannelLabel = new QLabel(scrollAreaWidgetContents); sizePolicy2.setHeightForWidth( ChannelLabel->sizePolicy().hasHeightForWidth() ); ChannelLabel->setSizePolicy(sizePolicy2); gridLayout->addWidget(ChannelLabel, 2, 1, 1, 1); SpacingStaticLabel = new QLabel(scrollAreaWidgetContents); sizePolicy1.setHeightForWidth( SpacingStaticLabel->sizePolicy().hasHeightForWidth() ); SpacingStaticLabel->setSizePolicy(sizePolicy1); gridLayout->addWidget(SpacingStaticLabel, 4, 0, 1, 1); SpacingLabel = new QLabel(scrollAreaWidgetContents); sizePolicy2.setHeightForWidth( SpacingLabel->sizePolicy().hasHeightForWidth() ); SpacingLabel->setSizePolicy(sizePolicy2); gridLayout->addWidget(SpacingLabel, 4, 1, 1, 1); PPositionLabel = new QLabel(scrollAreaWidgetContents); gridLayout->addWidget(PPositionLabel, 7, 1, 1, 1); WPositionStaticLabel = new QLabel(scrollAreaWidgetContents); QSizePolicy sizePolicy3(QSizePolicy::Preferred, QSizePolicy::Fixed); sizePolicy3.setHorizontalStretch(0); sizePolicy3.setVerticalStretch(0); sizePolicy3.setHeightForWidth( WPositionStaticLabel->sizePolicy().hasHeightForWidth() ); WPositionStaticLabel->setSizePolicy(sizePolicy3); gridLayout->addWidget(WPositionStaticLabel, 8, 0, 1, 1); WPositionLabel = new QLabel(scrollAreaWidgetContents); sizePolicy2.setHeightForWidth( WPositionLabel->sizePolicy().hasHeightForWidth() ); WPositionLabel->setSizePolicy(sizePolicy2); gridLayout->addWidget(WPositionLabel, 8, 1, 1, 1); TTimeStaticLabel = new QLabel(scrollAreaWidgetContents); sizePolicy3.setHeightForWidth( TTimeStaticLabel->sizePolicy().hasHeightForWidth() ); TTimeStaticLabel->setSizePolicy(sizePolicy3); gridLayout->addWidget(TTimeStaticLabel, 9, 0, 1, 1); TTimeLabel = new QLabel(scrollAreaWidgetContents); sizePolicy2.setHeightForWidth( TTimeLabel->sizePolicy().hasHeightForWidth() ); TTimeLabel->setSizePolicy(sizePolicy2); gridLayout->addWidget(TTimeLabel, 9, 1, 1, 1); TValueStaticLabel = new QLabel(scrollAreaWidgetContents); sizePolicy3.setHeightForWidth( TValueStaticLabel->sizePolicy().hasHeightForWidth() ); TValueStaticLabel->setSizePolicy(sizePolicy3); gridLayout->addWidget(TValueStaticLabel, 11, 0, 1, 1); TValueLabel = new QLabel(scrollAreaWidgetContents); gridLayout->addWidget(TValueLabel, 11, 1, 1, 1); ValueStaticLabel = new QLabel(scrollAreaWidgetContents); sizePolicy1.setHeightForWidth( ValueStaticLabel->sizePolicy().hasHeightForWidth() ); ValueStaticLabel->setSizePolicy(sizePolicy1); gridLayout->addWidget(ValueStaticLabel, 12, 0, 1, 1); ValueLabel = new QLabel(scrollAreaWidgetContents); sizePolicy2.setHeightForWidth( ValueLabel->sizePolicy().hasHeightForWidth() ); ValueLabel->setSizePolicy(sizePolicy2); gridLayout->addWidget(ValueLabel, 12, 1, 1, 1); SizeStaticLabel = new QLabel(scrollAreaWidgetContents); sizePolicy1.setHeightForWidth( SizeStaticLabel->sizePolicy().hasHeightForWidth() ); SizeStaticLabel->setSizePolicy(sizePolicy1); gridLayout->addWidget(SizeStaticLabel, 3, 0, 1, 1); SizeLabel = new QLabel(scrollAreaWidgetContents); sizePolicy2.setHeightForWidth( SizeLabel->sizePolicy().hasHeightForWidth() ); SizeLabel->setSizePolicy(sizePolicy2); gridLayout->addWidget(SizeLabel, 3, 1, 1, 1); TimeStaticLabel = new QLabel(scrollAreaWidgetContents); sizePolicy3.setHeightForWidth( TimeStaticLabel->sizePolicy().hasHeightForWidth() ); TimeStaticLabel->setSizePolicy(sizePolicy3); gridLayout->addWidget(TimeStaticLabel, 10, 0, 1, 1); TimeLabel = new QLabel(scrollAreaWidgetContents); sizePolicy2.setHeightForWidth( TimeLabel->sizePolicy().hasHeightForWidth() ); TimeLabel->setSizePolicy(sizePolicy2); gridLayout->addWidget(TimeLabel, 10, 1, 1, 1); TPositionLabel = new QLabel(scrollAreaWidgetContents); sizePolicy2.setHeightForWidth( TPositionLabel->sizePolicy().hasHeightForWidth() ); TPositionLabel->setSizePolicy(sizePolicy2); gridLayout->addWidget(TPositionLabel, 6, 1, 1, 1); TPositionStaticLabel = new QLabel(scrollAreaWidgetContents); sizePolicy1.setHeightForWidth( TPositionStaticLabel->sizePolicy().hasHeightForWidth() ); TPositionStaticLabel->setSizePolicy(sizePolicy1); gridLayout->addWidget(TPositionStaticLabel, 6, 0, 1, 1); MemoryStaticLabel = new QLabel(scrollAreaWidgetContents); sizePolicy1.setHeightForWidth( MemoryStaticLabel->sizePolicy().hasHeightForWidth() ); MemoryStaticLabel->setSizePolicy(sizePolicy1); gridLayout->addWidget(MemoryStaticLabel, 5, 0, 1, 1); MemoryLabel = new QLabel(scrollAreaWidgetContents); sizePolicy2.setHeightForWidth( MemoryLabel->sizePolicy().hasHeightForWidth() ); MemoryLabel->setSizePolicy(sizePolicy2); gridLayout->addWidget(MemoryLabel, 5, 1, 1, 1); PPositionStaticLabel = new QLabel(scrollAreaWidgetContents); sizePolicy3.setHeightForWidth( PPositionStaticLabel->sizePolicy().hasHeightForWidth() ); PPositionStaticLabel->setSizePolicy(sizePolicy3); gridLayout->addWidget(PPositionStaticLabel, 7, 0, 1, 1); scrollArea->setWidget(scrollAreaWidgetContents); verticalLayout->addWidget(scrollArea); retranslateUi(ImageInfo); QMetaObject::connectSlotsByName(ImageInfo); } // setupUi void QGoImageInfo::retranslateUi(QWidget *Form) { Form->setWindowTitle( QApplication::translate("Form", "Form", 0, QApplication::UnicodeUTF8) ); TImageStaticlabel->setText( QApplication::translate("Form", "\n" "\n" "

" "Image :

", 0, QApplication::UnicodeUTF8) ); DimensionStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" " Dimension :

", 0, QApplication::UnicodeUTF8) ); DimensionLabel->setText( QString() ); SizeStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" " Size :

", 0, QApplication::UnicodeUTF8) ); SizeLabel->setText( QString() ); SpacingLabel->setText( QString() ); MemoryLabel->setText( QString() ); PPositionLabel->setText( QString() ); WPositionLabel->setText( QString() ); TimeLabel->setText( QString() ); SpacingStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" " Spacing :

", 0, QApplication::UnicodeUTF8) ); MemoryStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" " Memory :

", 0, QApplication::UnicodeUTF8) ); TPositionStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" "Position :

", 0, QApplication::UnicodeUTF8) ); PPositionStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" " Position (pixel) :

", 0, QApplication::UnicodeUTF8) ); WPositionStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" " Position (um) :

", 0, QApplication::UnicodeUTF8) ); ChannelStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" " # Channels :

", 0, QApplication::UnicodeUTF8) ); TTimeStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" "Time :

", 0, QApplication::UnicodeUTF8) ); TValueStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" "Value :

", 0, QApplication::UnicodeUTF8) ); ValueStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" " Pixel value :

", 0, QApplication::UnicodeUTF8) ); ValueLabel->setText( QString() ); ChannelLabel->setText( QString() ); TimeStaticLabel->setText( QApplication::translate("Form", "\n" "\n" "

" " Time Point :

", 0, QApplication::UnicodeUTF8) ); Q_UNUSED(Form); } // retranslateUi void QGoImageInfo::setDimension(const unsigned int & dim) { m_Dimension = dim; this->DimensionLabel->setText( QString("%1").arg(m_Dimension) ); m_Size.resize(dim); m_Spacing.resize(dim); bool space_time = ( dim > 3 ); this->TTimeStaticLabel->setVisible(space_time); this->TTimeLabel->setVisible(space_time); this->TimeStaticLabel->setVisible(space_time); this->TimeLabel->setVisible(space_time); if ( space_time ) { m_PPos.resize(3); m_WPos.resize(3); } else { m_PPos.resize(dim); m_WPos.resize(dim); } } void QGoImageInfo::setNumberOfChannels(const unsigned int & channel) { m_Channel = channel; this->ChannelLabel->setText( QString("%1").arg(m_Channel) ); m_Value.resize(m_Channel); } void QGoImageInfo::setMemory(const unsigned long & iMem) { m_Memory = iMem; if ( static_cast< double >( m_Memory ) > 1e12 ) { this->MemoryLabel->setText( QString("%1 TB").arg(1e-12 * static_cast< double >( m_Memory ), 0, 'g', 3) ); } else { if ( static_cast< double >( m_Memory ) > 1e9 ) { this->MemoryLabel->setText( QString("%1 GB").arg(1e-9 * static_cast< double >( m_Memory ), 0, 'g', 3) ); } else { if ( static_cast< double >( m_Memory ) > 1e6 ) { this->MemoryLabel->setText( QString("%1 MB").arg(1e-6 * static_cast< double >( m_Memory ), 0, 'g', 3) ); } else { if ( static_cast< double >( m_Memory ) > 1e3 ) { this->MemoryLabel->setText( QString("%1 KB").arg(1e-3 * static_cast< double >( m_Memory ), 0, 'g', 3) ); } else { this->MemoryLabel->setText( QString("%1").arg(m_Memory) ); } } } } } void QGoImageInfo::setSize(const std::vector< unsigned int > & iSize) { if ( !m_Size.empty() ) { if ( iSize.size() == m_Dimension ) { m_Size = iSize; this->SizeLabel->setText( ConvertToQString(m_Size) ); } else { std::cout << "iSize.size() != " << m_Dimension << std::endl; } } else { std::cout << "Please setDimension first!" << std::endl; } } void QGoImageInfo::setSpacing(const std::vector< float > & iSpacing) { if ( !m_Spacing.empty() ) { if ( iSpacing.size() == m_Dimension ) { m_Spacing = iSpacing; this->SpacingLabel->setText( ConvertToQString(m_Spacing) ); } else { std::cout << "iSpacing.size() != " << m_Dimension << std::endl; } } else { std::cout << "Please setDimension first!" << std::endl; } } void QGoImageInfo::setPixelPosition(const std::vector< unsigned int > & iPos) { if ( !m_PPos.empty() ) { unsigned int len = ( m_Dimension > 3 ) ? 3 : m_Dimension; if ( iPos.size() == len ) { m_PPos = iPos; this->PPositionLabel->setText( ConvertToQString(m_PPos) ); } else { std::cout << "iPos.size() != " << len << std::endl; } } else { std::cout << "Please setDimension first!" << std::endl; } } void QGoImageInfo::setWorldPosition(const std::vector< float > & iPos) { if ( !m_WPos.empty() ) { unsigned int len = ( m_Dimension > 3 ) ? 3 : m_Dimension; if ( iPos.size() == len ) { m_WPos = iPos; this->WPositionLabel->setText( ConvertToQString(m_WPos) ); } else { std::cout << "iPos.size() != " << len << std::endl; } } else { std::cout << "Please setDimension first!" << std::endl; } } void QGoImageInfo::setTimePoint(const float & iTime) { m_TimePoint = iTime; this->TimeLabel->setText( QString("%1").arg(m_TimePoint) ); } void QGoImageInfo::setValue(const std::vector< float > & iVal) { QString val; if ( !m_Value.empty() ) { if ( iVal.size() == m_Channel ) { m_Value = iVal; this->ValueLabel->setText( ConvertToQString(m_Value) ); } else { std::cout << "iVal.size() != " << m_Channel << std::endl; } } else { std::cout << "Please setDimension first!" << std::endl; } }GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/0000755000175000017500000000000011667757442020002 5ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoFilterWatershed.cxx0000644000175000017500000001477311667757442024245 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoFilterWatershed.h" #include "QGoGUILibConfigure.h" // for apply method #include "vtkImageExport.h" #include "vtkImageData.h" #include "vtkMetaImageWriter.h" // ITK filter #include "itkImageFileWriter.h" #include "itkWatershedBasedCellSegmentation.h" #include "itkImage.h" #include "itkVTKImageImport.h" // to cut #include "vtkPlane.h" #include "vtkCutter.h" // to translate #include "vtkTransform.h" #include "vtkTransformPolyDataFilter.h" #include "GoImageProcessor.h" //-------------------------------------------------------------------------- QGoFilterWatershed::QGoFilterWatershed(QObject *iParent, int iDimension) : QGoFilterSemiAutoBase(iParent) { m_Image3D = itk::Image< int, 3 >::New(); m_Image2D = itk::Image< int, 2 >::New(); m_Dimension = iDimension; m_TreshMin = 10; m_TreshMax = 30; m_CorrTresh = 0.50; m_Alpha = 1.5; m_Beta = 3.0; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoFilterWatershed:: ~QGoFilterWatershed() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoFilterWatershed::Filter2D(double *iCenter, const int & iOrientation) { (void)iCenter; (void)iOrientation; /* const int dimension = 2; // useful to translate the polydata afterwards setCenter(iCenter); vtkImageData* slice = vtkImageData::New(); // Extract one slice if dimenesion == 2 vtkImageData* input = extractOneSlice(getInput(), iCenter, iOrientation); slice->DeepCopy(input); input->Delete(); // Recompute new center double* newOrigin = slice->GetOrigin(); double center[3]; switch (iOrientation) { case 0: { center[0] = iCenter[0] + newOrigin[0]; center[1] = iCenter[1] + newOrigin[1]; center[2] = 0.; break; } case 1: { center[0] = iCenter[0] + newOrigin[0]; center[1] = iCenter[2] + newOrigin[1]; center[2] = 0.; break; } case 2: { center[0] = iCenter[1] + newOrigin[0]; center[1] = iCenter[2] + newOrigin[1]; center[2] = 0.; break; } default: { break; } } // run filter typedef itk::Image FeatureImageType; typedef itk::Image OutputImageType; //VTK to ITK //--------------------------------------------------------- FeatureImageType::Pointer itkImage = ConvertVTK2ITK( slice ); // Extract ROI //--------------------------------------------------------- FeatureImageType::Pointer test2 = ExtractROI(itkImage, center, getRadius()); // Apply filter // Apply LevelSet segmentation filter //--------------------------------------------------------- typedef itk::ChanAndVeseSegmentationFilter SegmentationFilterType; FeatureImageType::PointType pt; SegmentationFilterType::Pointer filter = SegmentationFilterType::New(); filter->SetFeatureImage(test2); filter->SetPreprocess(1); pt[0] = center[0]; pt[1] = center[1]; pt[2] = center[2]; filter->SetCenter(pt); filter->SetRadius(getRadius()); filter->SetNumberOfIterations(m_Iterations); filter->SetCurvatureWeight(m_Curvature); filter->Update(); OutputImageType::Pointer test3 = filter->GetOutput(); // Convert output //--------------------------------------------------------- vtkImageData* itk2vtk = ConvertITK2VTK(test3); setOutput(itk2vtk); itk2vtk->Delete(); vtkPolyData* reconstructed = ReconstructContour( getOutput(), 0. ); // Translate to real location (i.e. see_pos[]) vtkTransform* t = vtkTransform::New(); t->Translate(getCenter()[0], getCenter()[1], getCenter()[2]); vtkTransformPolyDataFilter* tf = vtkTransformPolyDataFilter::New(); tf->SetTransform(t); tf->SetInput( reconstructed ); tf->Update(); vtkPolyData* contour = vtkPolyData::New(); contour->DeepCopy( tf->GetOutput() ); tf->Delete(); t->Delete(); reconstructed->Delete(); emit ContourCreated( contour ); */ } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector > QGoFilterWatershed:: ApplyFilterSetOf2D(double iRadius, int iThresMin, int iThresMax, double iCorrTresh, double iAlpha, double iBeta, int iSampling, std::vector< vtkPoints* >* iPoints, GoImageProcessor* iImages, int iChannel) { std::vector > oSetOfContours = std::vector >(); return oSetOfContours; } GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSetOfContoursShapeAlgo.cxx0000644000175000017500000000661011667757442025501 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSetOfContoursShapeAlgo.h" #include "QGoFilterShape.h" #include "GoImageProcessor.h" QGoSetOfContoursShapeAlgo::QGoSetOfContoursShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) :QGoShapeAlgo(iSeeds, iParent) { m_Sampling = new QGoAlgoParameter("Sampling", false, 0, 999, 3); this->m_AlgoWidget->AddParameter(m_Sampling); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoSetOfContoursShapeAlgo::~QGoSetOfContoursShapeAlgo() { this->DeleteParameters(); delete m_Sampling; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoSetOfContoursShapeAlgo::ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn) { std::vector NewContours = std::vector(); return NewContours; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector > QGoSetOfContoursShapeAlgo:: ApplyAlgoSeveralSeeds( GoImageProcessor* iImages, std::string iChannel) { std::vector > NewContours; QGoFilterShape ShapeFilter; //double *center = new double[3]; /*NewContours = ShapeFilter.ApplyFilterSetOf2D(this->m_Radius->GetValue(), this->m_Shape->Getvalue(), this->m_Sampling->GetValue(), this->m_Seeds, iImages, iChannel );*/ return NewContours; } GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshWaterShedAlgo.cxx0000644000175000017500000000732611667757442024453 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoMeshWaterShedAlgo.h" #include "QGoFilterWatershed.h" QGoMeshWaterShedAlgo:: QGoMeshWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, int iMaxThreshold, QWidget* iParent) :QGoWaterShedAlgo(iSeeds, iMaxThreshold, iParent) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoMeshWaterShedAlgo:: ~QGoMeshWaterShedAlgo() { this->DeleteParameters(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoMeshWaterShedAlgo:: ApplyAlgo(GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn) { std::vector oNewMeshes = std::vector(); if ( this->m_Radius->GetValue() <= 0 ) { std::cerr << "Radius should be > 0 " << std::endl; return oNewMeshes; } double Center[3]; std::vector CenterVect(3); // LOOP FOR EACH SEED for( size_t id = 0; id < this->m_Seeds->size(); id++ ) { for ( int i = 0; i < (*this->m_Seeds)[id]->GetNumberOfPoints(); i++ ) { (*this->m_Seeds)[id]->GetPoint(i, Center); CenterVect[0] = Center[0]; CenterVect[1] = Center[1]; CenterVect[2] = Center[2]; vtkPolyData* temp_output = this->ApplyWaterShedFilter< unsigned char >( CenterVect, //cente iImages->getImageITK< unsigned char, 3>(iChannel, iIsInvertedOn)); //input raw image if(temp_output->GetNumberOfCells() > 0) { oNewMeshes.push_back( temp_output ); } /* else { std::cout << "No polydata could be generated - check parameters" << std::endl; temp_output->Delete(); }*/ } } return oNewMeshes; } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoLevelSetAlgo.h0000644000175000017500000000532511667757442023115 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoLevelSetAlgo_h #define __QGoLevelSetAlgo_h #include "QGoSemiAutoSegmentationAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" class GoImageProcessor; /** \class QGoLevelSetAlgo \brief class to be the interface between the levelset algo for meshes, contours and set of contours and GoFigure */ class QGoLevelSetAlgo: public QGoSemiAutoSegmentationAlgo { public: QGoLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); virtual ~QGoLevelSetAlgo(); virtual std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false ) = 0; protected: QGoAlgoParameter* m_Curvature; QGoAlgoParameter* m_Iterations; virtual void SetAlgoWidget(QWidget* iParent = 0); virtual void DeleteParameters(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoFilterShape.cxx0000644000175000017500000003031111667757442023341 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoFilterShape.h" #include "QGoGUILibConfigure.h" // Shapes to be generated #include "vtkPolyData.h" #include "vtkPointData.h" #include "vtkPlane.h" // To deal with borders is mesh is on a border #include "vtkClipPolyData.h" // To extract 2D contours #include "vtkCutter.h" #include "vtkBox.h" //Sphere #include "vtkSphereSource.h" //Cube #include "vtkCubeSource.h" #include "vtkTriangleFilter.h" //cylinder #include "vtkCylinderSource.h" //#include "vtkTriangleFilter.h" #include "GoImageProcessor.h" //-------------------------------------------------------------------------- QGoFilterShape::QGoFilterShape(QObject *iParent, int iDimension) : QGoFilterSemiAutoBase(iParent) { m_Dimension = iDimension; QString name = "Shape "; if ( m_Dimension < 2 ) { name.append( QString::number(m_Dimension + 2, 10) ); name.append("D"); } else { name = "2D Shapes in 1 mesh"; } //setName(name); //QGoContourSemiAutoShapeWidget *widget = // new QGoContourSemiAutoShapeWidget(NULL); //setWidget(widget); m_Shape = 0; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoFilterShape:: ~QGoFilterShape() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyData * QGoFilterShape::Apply() { // Radius has to be > 0 if ( getRadius() <= 0 ) { std::cerr << "Radius should be > 0 " << std::endl; return NULL; } double *center2 = new double[3]; // update the pointed value of the seeds emit UpdateSeeds(); // LOOP FOR EACH SEED for ( int i = 0; i < getPoints()->GetNumberOfPoints(); i++ ) { getPoints()->GetPoint(i, center2); // useful to translate the polydata afterwards setCenter(center2); // need a switch depending on shape vtkPolyData *testing = NULL; switch ( m_Shape ) { case 0: testing = GenerateSphere( getCenter(), getRadius(), this->getInput() ); break; case 1: testing = GenerateCube( getCenter(), getRadius(), this->getInput() ); break; //case 2: // testing = GenerateCylinder(getCenter()); // break; default: break; } if ( m_Dimension == 0 ) { // Extract each slice according top the sampling vtkPlane *implicitFunction = vtkPlane::New(); implicitFunction->SetNormal(0, 0, 1); implicitFunction->SetOrigin(center2[0], center2[1], center2[2]); vtkCutter *cutter = vtkCutter::New(); cutter->SetInput(testing); cutter->SetCutFunction(implicitFunction); cutter->Update(); vtkPolyData *output = ReorganizeContour( cutter->GetOutput() ); emit ContourCreated(output); implicitFunction->Delete(); cutter->Delete(); testing->Delete(); } else // if dimension == 1, create a mesh { if ( m_Dimension == 1 ) { emit MeshCreated(testing, this->getChannel() - 1); } else { //emit CreateEmptyMesh(); // Extract each slice according top the sampling vtkPlane *implicitFunction = vtkPlane::New(); implicitFunction->SetNormal(0, 0, 1); vtkCutter *cutter = vtkCutter::New(); cutter->SetInput(testing); cutter->SetCutFunction(implicitFunction); double step = 2. * getRadius() / static_cast< double >( getSampling() + 1 ); for ( int j = 0; j < getSampling(); ++j ) { implicitFunction ->SetOrigin( ( center2[0] - getRadius() + static_cast< double >( j + 1 ) * step ), ( center2[1] - getRadius() + static_cast< double >( j + 1 ) * step ), ( center2[2] - getRadius() + static_cast< double >( j + 1 ) * step ) ); cutter->Update(); vtkPolyData *output = ReorganizeContour( cutter->GetOutput() ); emit AddContourForMeshToContours(output); } implicitFunction->Delete(); cutter->Delete(); testing->Delete(); emit CreateCorrespondingMesh( getSampling() ); } } } emit SegmentationFinished(); delete[] center2; return NULL; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoFilterShape::ConnectSignals(int iFilterNumber) { QGoFilterSemiAutoBase::ConnectSignals(iFilterNumber); // connect specific QObject::connect( getWidget(), SIGNAL( Shape(int) ), this, SLOT( setShape(int) ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoFilterShape::setShape(int iShape) { m_Shape = iShape; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyData * QGoFilterShape::GenerateSphere(double *iCenter, double iRadius, vtkSmartPointer< vtkImageData > iImage) { // create sphere geometry vtkSphereSource *sphere = vtkSphereSource::New(); sphere->SetRadius( iRadius ); sphere->SetCenter(iCenter); sphere->Update(); sphere->GetOutput()->GetPointData()->SetNormals(NULL); // Deal with borders vtkBox *implicitFunction = vtkBox::New(); //implicitFunction->SetBounds( this->getInput()->GetBounds() ); implicitFunction->SetBounds( iImage->GetBounds() ); vtkClipPolyData *cutter = vtkClipPolyData::New(); cutter->SetInput( sphere->GetOutput() ); cutter->InsideOutOn(); cutter->SetClipFunction(implicitFunction); cutter->Update(); vtkPolyData *output = vtkPolyData::New(); output->DeepCopy( cutter->GetOutput() ); implicitFunction->Delete(); cutter->Delete(); sphere->Delete(); return output; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyData * QGoFilterShape::GenerateCube(double *iCenter, double iRadius, vtkSmartPointer< vtkImageData > iImage) { // time consuming /* double* bounds = this->getInput()->GetBounds(); double radius = this->getRadius(); double xmin = iCenter[0] - radius; double xmax = iCenter[0] + radius; double ymin = iCenter[1] - radius; double ymax = iCenter[1] + radius; double zmin = iCenter[2] - radius; double zmax = iCenter[2] + radius; // Check Borders if( xmin < bounds[0]) { xmin = bounds[0]; } if( ymin < bounds[2]) { ymin = bounds[2]; } if( zmin < bounds[4]) { zmin = bounds[4]; } if( xmax > bounds[1]) { xmax = bounds[1]; } if( ymax > bounds[3]) { ymax = bounds[3]; } if( zmax > bounds[5]) { zmax = bounds[5]; } */ // create cube geometry vtkCubeSource *cube = vtkCubeSource::New(); cube->SetCenter(iCenter); cube->SetXLength( 2 * iRadius); cube->SetYLength( 2 * iRadius); cube->SetZLength( 2 * iRadius); cube->Update(); cube->GetOutput()->GetPointData()->SetNormals(NULL); vtkTriangleFilter *triangle = vtkTriangleFilter::New(); triangle->SetInput( cube->GetOutput() ); triangle->Update(); // Deal with borders vtkBox *implicitFunction = vtkBox::New(); implicitFunction->SetBounds( iImage->GetBounds() ); vtkClipPolyData *cutter = vtkClipPolyData::New(); cutter->SetInput( triangle->GetOutput() ); cutter->InsideOutOn(); cutter->SetClipFunction(implicitFunction); cutter->Update(); vtkPolyData *output = vtkPolyData::New(); output->DeepCopy( cutter->GetOutput() ); implicitFunction->Delete(); cutter->Delete(); triangle->Delete(); cube->Delete(); return output; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyData * QGoFilterShape::GenerateCylinder(double *iCenter) { // create cube geometry vtkCylinderSource *cylinder = vtkCylinderSource::New(); cylinder->SetHeight( 2 * getRadius() ); cylinder->SetRadius( getRadius() ); cylinder->SetCenter(iCenter); cylinder->SetResolution(10); cylinder->Update(); cylinder->GetOutput()->GetPointData()->SetNormals(NULL); vtkTriangleFilter *triangle = vtkTriangleFilter::New(); triangle->SetInput( cylinder->GetOutput() ); vtkPolyData *output = vtkPolyData::New(); output->DeepCopy( triangle->GetOutput() ); triangle->Delete(); cylinder->Delete(); return output; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector QGoFilterShape::ApplyFilter3D( double iRadius, std::vector< vtkPoints* >* iPoints, std::string iShape, GoImageProcessor* iImages, int iChannel) { std::vector oMeshes = std::vector(); if ( iRadius <= 0 ) { std::cerr << "Radius should be > 0 " << std::endl; return oMeshes; } vtkImageData* temp_image = iImages->getImageBW(iChannel); double center2[3]; for ( size_t id = 0; id < iPoints->size(); id++ ) { // LOOP FOR EACH SEED for ( vtkIdType i = 0; i < (*iPoints)[id]->GetNumberOfPoints(); i++ ) { (*iPoints)[id]->GetPoint(i, center2); // useful to translate the polydata afterwards setCenter(center2); vtkPolyData * MeshPolydata = NULL; if (iShape == "Sphere") { MeshPolydata = GenerateSphere( center2, iRadius, temp_image ); } else { if (iShape == "Cube") { MeshPolydata = GenerateCube( center2, iRadius, temp_image ); } else { std::cout<<"doesn't know the chosen shape "; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } } oMeshes.push_back(MeshPolydata); } } return oMeshes; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector > QGoFilterShape:: ApplyFilterSetOf2D(double iRadius, std::string iShape, int iSampling, std::vector< vtkPoints* >* iPoints, GoImageProcessor* iImages, int iChannel) { std::vector > oSetOfContours = std::vector >(); return oSetOfContours; } GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoContourWaterShedAlgo.cxx0000644000175000017500000000573311667757442025210 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoContourWaterShedAlgo.h" #include "QGoFilterWatershed.h" QGoContourWaterShedAlgo::QGoContourWaterShedAlgo(QWidget* iParent) :QGoWaterShedAlgo(iParent) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoContourWaterShedAlgo::~QGoContourWaterShedAlgo() { this->DeleteParameters(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoContourWaterShedAlgo::ApplyAlgo( vtkPoints* iSeeds, std::vector >* iImages, int iChannel) { QGoFilterWatershed WatershedFilter; std::vector NewContours = WatershedFilter.ApplyFilter3D(this->m_Radius->GetValue(), this->m_ThresMin->GetValue(), this->m_ThresMax->GetValue(), this->m_CorrThres->GetValue(),this->m_Alpha->GetValue(),this->m_Beta->GetValue(), iSeeds, iImages, iChannel); return NewContours; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSetOfContoursShapeAlgo.h0000644000175000017500000000526511667757442025133 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSetOfContoursShapeAlgo_h #define __QGoSetOfContoursShapeAlgo_h #include "QGoShapeAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" class GoImageProcessor; /** \class QGoSetOfContoursShapeAlgo \brief class to be the interface between the shape algo for set of contours and GoFigure */ class QGoSetOfContoursShapeAlgo: public QGoShapeAlgo { public: QGoSetOfContoursShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); ~QGoSetOfContoursShapeAlgo(); std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false); std::vector > ApplyAlgoSeveralSeeds( GoImageProcessor* iImages, std::string iChannel); protected: QGoAlgoParameter* m_Sampling; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoAlgoParameter.h0000644000175000017500000001315011667757442023305 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoAlgoParameter_h #define __QGoAlgoParameter_h #include #include #include #include #include #include /** \brief specialized class for a parameter to be added in an algorithm widget */ template< class T > class QGoAlgoParameter { public: QGoAlgoParameter() {}; ~QGoAlgoParameter(){}; protected: T m_Value; T m_DefaultValue; std::string m_ParamName; }; //------------------------------------------------------------------------- //------------------------------------------------------------------------- template<> class QGoAlgoParameter< int > { public: typedef QSpinBox RepresentationType; QGoAlgoParameter(std::string iParamName, bool iAdvParam, int iMin, int iMax, int iDefaultValue = 0, int iDefaultStep= 1) { m_ParamName = iParamName; m_Box = new RepresentationType; m_AdvParam = iAdvParam; SetRangeValues(iMin, iMax, iDefaultValue, iDefaultStep); }; ~QGoAlgoParameter() { /*if (m_Box != NULL) { delete m_Box; }*/ }; std::string m_ParamName; bool m_AdvParam; RepresentationType* m_Box; int GetValue() { return m_Box->value(); }; protected: void SetRangeValues(int iMin, int iMax, int iDefaultValue, int iDefaultStep) { m_Box->setRange(iMin, iMax); m_Box->setSingleStep(iDefaultStep); if (iDefaultValue != 0) { m_Box->setValue(iDefaultValue); } }; }; //------------------------------------------------------------------------- //------------------------------------------------------------------------- template<> class QGoAlgoParameter< double > { public: typedef QDoubleSpinBox RepresentationType; QGoAlgoParameter(std::string iParamName, bool iAdvParam, double iMin, double iMax, int iNbDecimal, double iDefaultValue = 0, double iDefaultStep = 0.1) { m_ParamName = iParamName; m_Box = new RepresentationType; m_AdvParam = iAdvParam; SetRangeValues(iMin, iMax, iNbDecimal, iDefaultValue, iDefaultStep); }; ~QGoAlgoParameter() { /*if (m_Box != NULL) { delete m_Box; }*/ }; std::string m_ParamName; bool m_AdvParam; RepresentationType* m_Box; double GetValue() { return m_Box->value(); }; protected: void SetRangeValues(double iMin, double iMax, int iNbDecimal, double iDefaultValue, double iDefaultStep) { m_Box->setRange(iMin, iMax); m_Box->setDecimals(iNbDecimal); m_Box->setSingleStep(iDefaultStep); if (iDefaultValue != 0) { m_Box->setValue(iDefaultValue); } }; }; //------------------------------------------------------------------------- //------------------------------------------------------------------------- template<> class QGoAlgoParameter< std::string > { public: typedef QComboBox RepresentationType; QGoAlgoParameter(std::string iParamName, bool iAdvParam, QStringList iListValues, std::string iDefaultValue = "") { m_ParamName = iParamName; m_Box = new RepresentationType; m_AdvParam = iAdvParam; SetListValues(iListValues, iDefaultValue); } ~QGoAlgoParameter() { /*if (m_Box != NULL) { delete m_Box; }*/ }; std::string m_ParamName; bool m_AdvParam; RepresentationType* m_Box; std::string Getvalue() { return m_Box->currentText().toStdString(); } protected: void SetListValues(QStringList iListValues, std::string iDefaultValue) { m_Box->addItems(iListValues); if (!iDefaultValue.empty()) { m_Box->setCurrentIndex(m_Box->findText(iDefaultValue.c_str())); } }; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoFilterSemiAutoBase.txx0000644000175000017500000001542411667757442024653 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoFilterSemiAutoBase_txx #define __QGoFilterSemiAutoBase_txx // VTK to ITK #include "vtkitkAdaptor.h" // ITK to VTK #include "itkImageToVTKImageFilter.h" // ROI extraction #include "itkRegionOfInterestImageFilter.h" #include "vtkImageData.h" //------------------------------------------------------------------------- // Convert vtkImageData to itkData template< class PixelType, unsigned int VImageDimension > typename itk::Image< PixelType, VImageDimension >::Pointer QGoFilterSemiAutoBase::ConvertVTK2ITK(vtkImageData *iInput) { if ( !iInput ) { std::cerr << "no input to be converted to itk" << std::endl; } //Export VTK image to ITK m_vtk2itkImage->SetInput(iInput); m_vtk2itkImage->Update(); // ImageType typedef itk::Image< PixelType, VImageDimension > ImageType; // Import VTK Image to ITK typedef itk::VTKImageImport< ImageType > ImageImportType; typedef typename ImageImportType::Pointer ImageImportPointer; ImageImportPointer movingImporter = ImageImportType::New(); ConnectPipelines< vtkImageExport, ImageImportPointer >( m_vtk2itkImage, movingImporter); typename ImageType::Pointer itkImage = movingImporter->GetOutput(); itkImage->DisconnectPipeline(); return itkImage; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class PixelType, unsigned int VImageDimension > vtkImageData * QGoFilterSemiAutoBase::ConvertITK2VTK(typename itk::Image< PixelType, VImageDimension >::Pointer iInput) { typedef itk::Image< PixelType, VImageDimension > InternalImageType; typedef itk::ImageToVTKImageFilter< InternalImageType > ConverterType; typedef typename ConverterType::Pointer ConverterPointer; ConverterPointer converter = ConverterType::New(); converter->SetInput(iInput); try { converter->Update(); } catch (itk::ExceptionObject & err) { std::cerr << "converter Exception:" << err << std::endl; } vtkImageData *output = vtkImageData::New(); output->DeepCopy( converter->GetOutput() ); return output; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class PixelType, unsigned int VImageDimension > typename itk::Image< PixelType, VImageDimension >::Pointer QGoFilterSemiAutoBase::ExtractROI(typename itk::Image< PixelType, VImageDimension >::Pointer iInput, double *iCenter, double iRadius) { typedef itk::Image< PixelType, VImageDimension > InternalImageType; typedef typename InternalImageType::PointType InternalPointType; typedef typename InternalImageType::IndexType InternalIndexType; typedef typename InternalImageType::IndexValueType InternalIndexValueType; typedef typename InternalImageType::SizeType InternalSizeType; typedef typename InternalImageType::SizeValueType InternalSizeValueType; typedef typename InternalImageType::RegionType InternalRegionType; typedef typename InternalImageType::SpacingType InternalSpacingType; if ( iInput.IsNull() ) { std::cerr << "m_FeatureImage is Null" << std::endl; } InternalSpacingType spacing = iInput->GetSpacing(); InternalIndexType startOfROI, endOfROI; InternalPointType origin; InternalSizeType size; InternalSizeType sizeOfLargeImage = iInput->GetLargestPossibleRegion().GetSize(); size.Fill(0); unsigned int j; for ( j = 0; j < VImageDimension; j++ ) { size[j] = 1 + 4. * static_cast< InternalSizeValueType >(iRadius / spacing[j]); origin[j] = iCenter[j] - 2 * iRadius; } iInput->TransformPhysicalPointToIndex(origin, startOfROI); for ( j = 0; j < VImageDimension; j++ ) { if ( startOfROI[j] < 0 ) { startOfROI[j] = 0; } endOfROI[j] = startOfROI[j] + static_cast< InternalIndexValueType >(size[j]) - 1; if ( endOfROI[j] > static_cast< InternalIndexValueType >(sizeOfLargeImage[j] - 1) ) { size[j] = sizeOfLargeImage[j] - startOfROI[j]; } } InternalRegionType region; region.SetSize(size); region.SetIndex(startOfROI); typedef itk::RegionOfInterestImageFilter< InternalImageType, InternalImageType > ROIFilterType; typedef typename ROIFilterType::Pointer ROIFilterPointer; ROIFilterPointer roi = ROIFilterType::New(); roi->SetInput(iInput); roi->SetRegionOfInterest(region); try { roi->Update(); } catch (itk::ExceptionObject & err) { std::cerr << "roi Exception:" << err << std::endl; } return roi->GetOutput(); } //------------------------------------------------------------------------- #endif // QGoFilterSemiAutoBaseGoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoTraceEditingWidgetManager.h0000644000175000017500000001262411667757442025570 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTraceEditingWidgetManager_h #define __QGoTraceEditingWidgetManager_h #include "QGoTraceEditingWidget.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "QGoDockWidget.h" #include #include #include #include class GoImageProcessor; /** \class QGoTraceEditingWidgetManager \brief abstract class handles the interactions between the user and the algorithms for one kind of trace */ class QGOGUILIB_EXPORT QGoTraceEditingWidgetManager: public QObject { Q_OBJECT public: explicit QGoTraceEditingWidgetManager(std::string iTraceName, std::vector iVectChannels, int iTimeMin, int iTimeMax, std::vector< vtkPoints* >* iSeeds, GoImageProcessor* iImages, int* iCurrentTimePoint, QWidget* iParent=0); ~QGoTraceEditingWidgetManager(); QAction* GetToggleViewAction(); /** \return the dockwidget for it to be integrated in the mainwindow */ QGoDockWidget* GetDockWidget(); /** \brief display only the current timepoint in the TSlice comboboxes of the qgoalgomanagerwidgets, disable them and enable the channel comboboxes */ virtual void SetTSliceForClassicView(); /** \brief display the 3 timepoints chosen by the user in the TSlice comboboxes of the qgoalgomanagerwidgets, enable them, display only the channel tracked by the user and disable the channel comboboxes */ virtual void SetTSliceForDopplerView( QHash iListTimePoints, int iChannelNumber); public slots: /** \brief show or hide the dockwidget and check the current selected mode in order to emit a signal to get the seeds widget if show or to disable it of hide */ void SetVisible(bool isVisible); signals: void UpdateSeeds(); void ClearAllSeeds(); /** \brief emitted when new meshes need to be saved in database and rendered in the vizu, return the TSlice selected in the TSlice combobox */ void TracesCreatedFromAlgo(std::vector iVectPolydata, int iTCoord); void TracesSplittedFromAlgo(std::vector iVectPolydata); void TracesMergedFromAlgo(vtkPolyData * iPolydata); /** \brief emit true to get the seeds widget enabled and false to disable it */ void SetSeedInteractorBehaviour(bool enable); protected: QGoDockWidget* m_TraceEditingDockWidget; QGoTraceEditingWidget* m_TraceEditingWidget; std::string m_TraceName; std::vector< vtkPoints* >* m_Seeds; //useful ??? GoImageProcessor* m_Images; int* m_CurrentTimePoint; QStringList m_ListTimePoint; int m_MaxThreshold; void SetTheTraceWidget(std::vector iVectChannels, int iTimeMin, int iTimeMax, QWidget* iParent); void SetTheDockWidget(QWidget* iParent); /** \brief return the selected timepoint in the TSlice combobox */ int GetSelectedTimePoint(); /** \brief add the algowidget of the different algo in the algomanagerwidget for the semi automatic mode and set the different SIGNAL/SLOTS connections */ virtual void SetSemiAutomaticAlgorithms(QWidget* iParent = 0) = 0; /** \brief get the vtkpolydata for the new created meshes by the chosen algo */ template void GetPolydatasFromAlgo(T* iAlgo) { emit UpdateSeeds(); std::vector NewTraces = iAlgo->ApplyAlgo( this->m_Images, this->m_TraceEditingWidget->GetCurrentImageName(), this->m_TraceEditingWidget->GetIsInvertedOn() ); emit TracesCreatedFromAlgo(NewTraces, this->GetSelectedTimePoint() ); emit ClearAllSeeds(); } }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.cxx.bak0000644000175000017500000003235611667757442025142 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSegmentationAlgo.h" // Extract ROI #include "vtkExtractVOI.h" // extract polydata 2d #include "vtkMarchingSquares.h" //reorder contour #include "vtkStripper.h" #include "vtkCellArray.h" // extract polydata 3d #include "vtkContourFilter.h" #include "vtkFeatureEdges.h" #include "vtkFillHolesFilter.h" #include "vtkPolyDataConnectivityFilter.h" #include "vtkWindowedSincPolyDataFilter.h" // Decimation 2d #include "vtkPolylineDecimation.h" // Decimation 3d #include "vtkDecimatePro.h" // test code #include QGoSegmentationAlgo::QGoSegmentationAlgo(QWidget *iParent) : m_Decimate(true), m_NumberOfPoints(100), m_AlgoWidget(NULL) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoSegmentationAlgo::~QGoSegmentationAlgo() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoAlgorithmWidget* QGoSegmentationAlgo::GetAlgoWidget() { return this->m_AlgoWidget; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoSegmentationAlgo:: ExtractROI(std::vector iBounds, std::vector iImages) { // vector to be returned std::vector listOfImages; //iterator on the images std::vector::iterator it = iImages.begin(); while( it != iImages.end()) { listOfImages.push_back( ExtractROI(iBounds, *it) ); ++it; } return listOfImages; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: <<<<<<< HEAD ExtractROI(std::vector iBounds, vtkImageData* iImage) ======= ExtractROI(double* iBounds, vtkSmartPointer iImage) >>>>>>> add_genericMethods { // make sure there // assert( iBounds ); vtkSmartPointer extractVOI = vtkSmartPointer::New(); extractVOI->SetInput( iImage ); extractVOI->SetVOI( iBounds[0] ,iBounds[1], iBounds[2] ,iBounds[3], iBounds[4], iBounds[5]); extractVOI->Update(); return extractVOI->GetOutput(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoSegmentationAlgo:: ExtractPolyData(std::vector iInputImage, const double & iThreshold) { // vector to be returned std::vector listOfPolys; //iterator on the images std::vector::iterator it = iInputImage.begin(); while( it != iInputImage.end()) { vtkPolyData* extractedPolyData = ExtractPolyData(*it, iThreshold); if( extractedPolyData ) { listOfPolys.push_back( extractedPolyData ); } ++it; } return listOfPolys; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: ExtractPolyData(vtkImageData *iInputImage, const double & iThreshold) { // make sure there is an image assert( iInputImage ); // test dimension of the input int dimension = iInputImage->GetDataDimension(); switch ( dimension ) { case 2 : return ExtractContour( iInputImage, iThreshold); case 3 : return ExtractMesh( iInputImage, iThreshold); default : std::cout << "dimension unknown (Reconstruct polydata)" << std::endl; } return NULL; } //------------------------------------------------------------------------- /* * \todo Nicolas-do a better reconstruction.. */ //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: ExtractContour( vtkSmartPointer iInputImage, const double & iThreshold) { // create iso-contours vtkSmartPointer contours = vtkSmartPointer::New(); contours->SetInput(iInputImage); contours->GenerateValues (1, iThreshold, iThreshold); contours->Update(); return ReorganizeContour( contours->GetOutput() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: ReorganizeContour(vtkSmartPointer iInputImage) { /* * \note Nicolas-to be enhanced */ // Create reorganize contours vtkStripper *stripper = vtkStripper::New(); stripper->SetInput(iInputImage); //Is it useful?? Which number is the best suited? stripper->SetMaximumLength(999); stripper->Update(); // Reorder points stripper->GetOutput()->GetLines()->InitTraversal(); // npts = nb of points in the line // *pts = pointer to each point vtkIdType *pts = NULL; vtkIdType npts = 0; stripper->GetOutput()->GetLines()->GetNextCell(npts, pts); vtkPoints *points = vtkPoints::New(); vtkCellArray *lines = vtkCellArray::New(); vtkIdType * lineIndices = new vtkIdType[static_cast< int >( npts + 1 )]; for ( int k = 0; k < static_cast< int >( npts ); k++ ) { points->InsertPoint( k, stripper->GetOutput()->GetPoints()->GetPoint(pts[k]) ); lineIndices[k] = k; } lineIndices[static_cast< int >( npts )] = 0; lines->InsertNextCell(npts + 1, lineIndices); delete[] lineIndices; vtkSmartPointer output = vtkSmartPointer::New(); output->SetPoints(points); output->SetLines(lines); lines->Delete(); points->Delete(); stripper->Delete(); return output; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: ExtractMesh(vtkSmartPointer iInputImage, const double & iThreshold) { vtkSmartPointer< vtkContourFilter > contours = vtkSmartPointer< vtkContourFilter >::New(); contours->SetInput(iInputImage); contours->SetComputeGradients(0); contours->SetComputeNormals(0); contours->SetComputeScalars(0); contours->SetNumberOfContours(1); contours->SetValue(0, iThreshold); contours->Update(); vtkSmartPointer< vtkFeatureEdges > feature = vtkSmartPointer< vtkFeatureEdges >::New(); feature->SetInputConnection( contours->GetOutputPort() ); feature->BoundaryEdgesOn(); feature->FeatureEdgesOff(); feature->NonManifoldEdgesOn(); feature->ManifoldEdgesOff(); feature->Update(); vtkSmartPointer< vtkFillHolesFilter > fillFilter = vtkSmartPointer< vtkFillHolesFilter >::New(); vtkSmartPointer< vtkPolyDataConnectivityFilter > connectivityFilter = vtkSmartPointer< vtkPolyDataConnectivityFilter >::New(); connectivityFilter->SetExtractionModeToLargestRegion(); if ( feature->GetOutput()->GetNumberOfCells() > 0 ) { // fill holes if any! fillFilter->SetInputConnection( contours->GetOutputPort() ); fillFilter->Update(); connectivityFilter->SetInputConnection( fillFilter->GetOutputPort() ); } else { connectivityFilter->SetInputConnection( contours->GetOutputPort() ); } // keep the largest region connectivityFilter->Update(); /* * \note Nicolas-Smoother not connected */ /* unsigned int smoothingIterations = 15; double passBand = 0.001; double featureAngle = 120.0; // smoothing vtkSmartPointer< vtkWindowedSincPolyDataFilter > smoother = vtkSmartPointer< vtkWindowedSincPolyDataFilter >::New(); smoother->SetInputConnection( connectivityFilter->GetOutputPort() ); smoother->SetNumberOfIterations( smoothingIterations ); smoother->BoundarySmoothingOff(); smoother->FeatureEdgeSmoothingOff(); smoother->SetFeatureAngle(featureAngle); smoother->SetPassBand(passBand); smoother->NonManifoldSmoothingOn(); smoother->NormalizeCoordinatesOn(); smoother->Update(); */ return connectivityFilter->GetOutput(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: DecimatePolyData( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints) { // make sure there is a polydata assert( iPolyData ); /* * \todo Nicolas-might be better solution to test dimension of a PolyData */ // test dimension of the input double* bounds = iPolyData->GetBounds(); int dimension = 3; if(bounds[0] == bounds[1] || bounds[2] == bounds[3] || bounds[4] == bounds[5]) { --dimension; } switch ( dimension ) { case 2 : return DecimateContour( iPolyData, iNumberOfPoints); case 3 : return DecimateMesh( iPolyData, iNumberOfPoints); default : std::cout << "dimension unknown (Reconstruct polydata)" << std::endl; } return NULL; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: DecimateContour( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints) { // define target reduction unsigned int numberOfPoints = iPolyData->GetNumberOfPoints(); double target = 1 - (double)iNumberOfPoints/(double)numberOfPoints; vtkSmartPointer decimator = vtkSmartPointer::New(); decimator->SetInput(iPolyData); decimator->SetTargetReduction(target); decimator->Update(); return decimator->GetOutput(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: DecimateMesh( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints) { // define target reduction unsigned int numberOfPoints = iPolyData->GetNumberOfPoints(); double target = 1 - (double)iNumberOfPoints/(double)numberOfPoints; vtkSmartPointer decimator = vtkSmartPointer::New(); decimator->SetInput(iPolyData); decimator->SetTargetReduction(target); decimator->Update(); /* * \todo Nicolas-fill holes -smooth..? */ return decimator->GetOutput(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoSegmentationAlgo:: SetDecimate(bool& iDecimate) { m_Decimate = iDecimate; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool QGoSegmentationAlgo:: GetDecimate() { return m_Decimate; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoSegmentationAlgo:: SetNumberOfPoints( unsigned int& iNumberOfPoints) { m_NumberOfPoints = iNumberOfPoints; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- unsigned int QGoSegmentationAlgo:: GetNumberOfPoints() { return m_NumberOfPoints; } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoModesManagerWidget.cxx0000644000175000017500000002367511667757442024660 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoModesManagerWidget.h" #include #include QGoModesManagerWidget::QGoModesManagerWidget(std::vector iVectChannels, QStringList iListTimePoints, QWidget *iParent) :QWidget(iParent), m_ManualModeManager(NULL) { this->Initialize(iVectChannels, iListTimePoints); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoModesManagerWidget::~QGoModesManagerWidget() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoModesManagerWidget::Initialize(std::vector iVectChannels, QStringList iListTimePoints) { this->m_ModeAlreadyCleaned = false; this->m_VBoxLayout = new QVBoxLayout; this->m_ModeComboBox = new QComboBox(this); QHBoxLayout* ModeLayout = new QHBoxLayout; QLabel* ModeLabel = new QLabel(tr("Mode:"), this); ModeLayout->addWidget(ModeLabel); ModeLayout->addWidget(this->m_ModeComboBox); this->m_VBoxLayout->addLayout(ModeLayout); this->m_ModeWidgets = new QStackedWidget; this->m_VBoxLayout->addWidget(this->m_ModeWidgets); this->setLayout(this->m_VBoxLayout); this->m_VBoxLayout->setSizeConstraint(QLayout::SetFixedSize); //add default modes: this->m_SemiAutoAlgoManagerWidget = new QGoAlgorithmsManagerWidget("SemiAutomatic", this, iVectChannels, iListTimePoints); this->AddAlgoManagerWidget(this->m_SemiAutoAlgoManagerWidget, true); this->m_AutoAlgoManagerWidget = new QGoAlgorithmsManagerWidget("Automatic",this, iVectChannels, iListTimePoints); this->AddAlgoManagerWidget(this->m_AutoAlgoManagerWidget, false); m_ModesWhoNeedSeeds.append("SemiAutomatic"); m_ModesWhoNeedSeeds.append("Automatic"); QObject::connect(this->m_ModeComboBox, SIGNAL(activated(int)), this, SLOT(SetTheRightMode(int))); QObject::connect(this->m_AutoAlgoManagerWidget, SIGNAL(ResetClicked() ), this, SIGNAL(ResetClicked() ) ); QObject::connect(this->m_SemiAutoAlgoManagerWidget, SIGNAL(ResetClicked() ), this, SIGNAL(ResetClicked() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoModesManagerWidget::AddWidgetWithModeName( std::string iModeName, QWidget* iWidget, bool ModeNeedSeeds ) { int Index = 0; if (iWidget != 0) { this->m_ModeWidgets->addWidget(iWidget); Index = this->m_ModeWidgets->indexOf(iWidget); } this->m_ModeComboBox->insertItem(Index,iModeName.c_str()); if (ModeNeedSeeds) { this->m_ModesWhoNeedSeeds.append(iModeName.c_str() ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoModesManagerWidget::AddAlgoManagerWidget( QGoAlgorithmsManagerWidget* iAlgoManagerWidget, bool ModeNeedSeeds, int iDefaultIndex) { this->AddWidgetWithModeName(iAlgoManagerWidget->GetModeName(), iAlgoManagerWidget, ModeNeedSeeds); iAlgoManagerWidget->SetCurrentIndex(iDefaultIndex); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoModesManagerWidget::CheckDefaultModes() { if (!this->m_AutoAlgoManagerWidget->HasMethod()) { this->m_ModeComboBox->removeItem( this->m_ModeComboBox->findText("Automatic") ); this->m_ModeWidgets->removeWidget(this->m_AutoAlgoManagerWidget); } if (!this->m_SemiAutoAlgoManagerWidget->HasMethod()) { this->m_ModeComboBox->removeItem( this->m_ModeComboBox->findText("SemiAutomatic") ); this->m_ModeWidgets->removeWidget(this->m_SemiAutoAlgoManagerWidget); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoModesManagerWidget::AddAlgoWidgetForSemiAutomaticMode( QGoAlgorithmWidget* iAlgoWidget) { this->m_SemiAutoAlgoManagerWidget->AddMethod(iAlgoWidget); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoModesManagerWidget::AddAlgoWidgetForAutomaticMode( QGoAlgorithmWidget* iAlgoWidget) { this->m_AutoAlgoManagerWidget->AddMethod(iAlgoWidget); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoModesManagerWidget::AddWidgetForManualMode(QWidget* iWidget, QStringList iListTimePoint, bool ModeNeedSeeds) { std::vector Channels = std::vector(); this->m_ManualModeManager = new QGoAlgorithmsManagerWidget( "Manual",this, Channels, iListTimePoint, true, false); this->m_ManualModeManager->AddWidgetForOnlyOneMethod(iWidget); this->AddAlgoManagerWidget(this->m_ManualModeManager, ModeNeedSeeds); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoModesManagerWidget::GetCurrentImageName() { QGoAlgorithmsManagerWidget* CurrentWidget = dynamic_cast (this->m_ModeWidgets->currentWidget()); return CurrentWidget->GetCurrentImageName(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoModesManagerWidget::GetSelectedTimePoint() { QGoAlgorithmsManagerWidget* CurrentWidget = dynamic_cast (this->m_ModeWidgets->currentWidget()); return CurrentWidget->GetSelectedTimePoint(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoModesManagerWidget::GetIsInvertedOn() { QGoAlgorithmsManagerWidget* CurrentWidget = dynamic_cast (this->m_ModeWidgets->currentWidget()); return CurrentWidget->IsInvertChecked(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoModesManagerWidget::SetTheRightMode(int iIndex) { if(! m_ModeAlreadyCleaned) { this->CheckDefaultModes(); m_ModeAlreadyCleaned = true; } if (iIndex != -1) { this->m_ModeWidgets->setCurrentIndex(iIndex); } if (this->m_ModesWhoNeedSeeds.indexOf( this->m_ModeComboBox->currentText() ) != -1) { emit SetSeedInteractorBehaviour(true); } else { emit SetSeedInteractorBehaviour(false); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoModesManagerWidget::SetTSliceForClassicViewInAllAlgoModes(int iTimePoint) { this->m_AutoAlgoManagerWidget->SetTSliceForClassicView(tr("%1").arg(iTimePoint) ); this->m_SemiAutoAlgoManagerWidget->SetTSliceForClassicView(tr("%1").arg(iTimePoint) ); if (this->m_ManualModeManager) { this->m_ManualModeManager->SetTSliceForClassicView(tr("%1").arg(iTimePoint) ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoModesManagerWidget::SetTSliceForDopplerViewInAllAlgoModes( QHash iListTimePoints, int iChannelNumber) { this->m_AutoAlgoManagerWidget->SetTSliceForDopplerView( iListTimePoints, iChannelNumber); this->m_SemiAutoAlgoManagerWidget->SetTSliceForDopplerView( iListTimePoints, iChannelNumber); if (this->m_ManualModeManager) { this->m_ManualModeManager->SetTSliceForDopplerView( iListTimePoints, iChannelNumber); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoModesManagerWidget::GetCurrentModeName() { return this->m_ModeComboBox->currentText().toStdString(); } GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoShapeAlgo.h0000644000175000017500000000517411667757442022434 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoShapeAlgo_h #define __QGoShapeAlgo_h #include "QGoSemiAutoSegmentationAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" class GoImageProcessor; /** \class QGoShapeAlgo \brief class to be the interface between the shape algo for meshes, contours and set of contours and GoFigure */ class QGoShapeAlgo: public QGoSemiAutoSegmentationAlgo { public: QGoShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); ~QGoShapeAlgo(); virtual std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false ) = 0; protected: QGoAlgoParameter* m_Shape; virtual void SetAlgoWidget(QWidget* iParent = 0); void DeleteParameters(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshEditingWidgetManager.cxx0000644000175000017500000003071211667757442025777 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoMeshEditingWidgetManager.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoAlgorithmsManagerWidget.h" #include "vtkSmartPointer.h" #include "vtkImageExport.h" #include "vtkImageData.h" #include #include #include "QGoMeshWaterShedAlgo.h" #include "GoImageProcessor.h" QGoMeshEditingWidgetManager::QGoMeshEditingWidgetManager( std::vector iVectChannels, int iTimeMin, int iTimeMax, std::vector< vtkPoints* >* iSeeds, GoImageProcessor* iImages, int* iCurrentTimePoint, QWidget* iParent): QGoTraceEditingWidgetManager("Mesh", iVectChannels, iTimeMin, iTimeMax, iSeeds, iImages, iCurrentTimePoint, iParent) { this->SetSemiAutomaticAlgorithms(iParent); this->SetSplitMergeMode(iVectChannels, this->m_ListTimePoint,iParent); this->SetSetOfContoursAlgorithms(iVectChannels, this->m_ListTimePoint, iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoMeshEditingWidgetManager::~QGoMeshEditingWidgetManager() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::SetTSliceForClassicView() { QGoTraceEditingWidgetManager::SetTSliceForClassicView(); if (this->m_SetOfContoursWidget != NULL) { this->m_SetOfContoursWidget->SetTSliceForClassicView( tr("%1").arg(*this->m_CurrentTimePoint) ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::SetTSliceForDopplerView( QHash iListTimePoints, int iChannelNumber) { QGoTraceEditingWidgetManager::SetTSliceForDopplerView( iListTimePoints, iChannelNumber); this->m_SetOfContoursWidget->SetTSliceForDopplerView( iListTimePoints, iChannelNumber); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::SetSemiAutomaticAlgorithms(QWidget* iParent) { //level set: m_LevelSetAlgo = new QGoMeshLevelSetAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* LevelSetWidget = m_LevelSetAlgo->GetAlgoWidget(); this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(LevelSetWidget); QObject::connect(LevelSetWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplyLevelSetAlgo() ) ); //watershed: this->m_WaterShedAlgo = new QGoMeshWaterShedAlgo(this->m_Seeds, this->m_MaxThreshold, iParent); QGoAlgorithmWidget* WaterShedWidget = m_WaterShedAlgo->GetAlgoWidget(); this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(WaterShedWidget); QObject::connect(WaterShedWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplyWaterShedAlgo() ) ); //shape: this->m_ShapeAlgo = new QGoMeshShapeAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* ShapeWidget = this->m_ShapeAlgo->GetAlgoWidget(); this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(ShapeWidget); QObject::connect(ShapeWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplyShapeAlgo() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::SetSetOfContoursAlgorithms( std::vector iVectChannels, QStringList iListTime, QWidget* iParent) { // initialize the widget m_SetOfContoursWidget = new QGoAlgorithmsManagerWidget("Set of Contours", iParent, iVectChannels, iListTime); this->SetTSliceForClassicView(); this->m_TraceEditingWidget->AddMode(m_SetOfContoursWidget, true); //watershed this->m_SetOfContoursWaterShedAlgo = new QGoSetOfContoursWaterShedAlgo(this->m_Seeds, this->m_MaxThreshold, iParent); QGoAlgorithmWidget* SetOfContoursWaterShedWidget = this->m_SetOfContoursWaterShedAlgo->GetAlgoWidget(); this->m_SetOfContoursWidget->AddMethod(SetOfContoursWaterShedWidget); QObject::connect(SetOfContoursWaterShedWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplySetOfContoursWaterShedAlgo() ) ); //levelset this->m_SetOfContoursLevelSetAlgo = new QGoSetOfContoursLevelSetAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* SetOfContoursLevelSetWidget = this->m_SetOfContoursLevelSetAlgo->GetAlgoWidget(); this->m_SetOfContoursWidget->AddMethod(SetOfContoursLevelSetWidget); QObject::connect(SetOfContoursLevelSetWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplySetOfContoursLevelSetAlgo() ) ); //shape this->m_SetOfContoursShapeAlgo = new QGoSetOfContoursShapeAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* SetOfContoursShapeWidget = this->m_SetOfContoursShapeAlgo->GetAlgoWidget(); this->m_SetOfContoursWidget->AddMethod(SetOfContoursShapeWidget); QObject::connect(SetOfContoursShapeWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplySetOfContoursShapeAlgo() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::SetSplitMergeMode( std::vector iVectChannels, QStringList iListTime, QWidget* iParent) { QGoAlgorithmsManagerWidget* SplitAlgoWidget = new QGoAlgorithmsManagerWidget("Split", iParent, iVectChannels); this->m_TraceEditingWidget->AddMode(SplitAlgoWidget, true); m_DanielAlgo = new QGoMeshSplitDanielssonDistanceAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget * DanielWidget = m_DanielAlgo->GetAlgoWidget(); SplitAlgoWidget->AddMethod(DanielWidget ); QObject::connect( DanielWidget, SIGNAL(ApplyAlgo() ) , this, SLOT(RequestPolydatasForDanielsson() ) ); QGoAlgorithmsManagerWidget* MergeAlgoWidget = new QGoAlgorithmsManagerWidget("Merge", iParent, iVectChannels); this->m_TraceEditingWidget->AddMode(MergeAlgoWidget, false); m_ConvexHullAlgo = new QGoMeshMergeConvexHullAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget * ConvexHullWidget = m_ConvexHullAlgo->GetAlgoWidget(); MergeAlgoWidget->AddMethod(ConvexHullWidget ); QObject::connect( ConvexHullWidget, SIGNAL(ApplyAlgo() ) , this, SLOT(RequestPolydatasForConvexHull() ) ); } //------------------------------------------------------------------------- // required to setup the go reference to the algorithm we gonna use //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::RequestPolydatasForDanielsson(){ m_TempReference = dynamic_cast(m_DanielAlgo); emit RequestPolydatas(); } //------------------------------------------------------------------------- // required to setup the go reference to the algorithm we gonna use //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::RequestPolydatasForConvexHull(){ m_TempReference = dynamic_cast(m_ConvexHullAlgo); emit RequestPolydatas(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager:: RequestedPolydatas(std::list< vtkPolyData* > iRequest){ // get mode QString mode = QString::fromStdString(this->m_TraceEditingWidget->GetCurrentModeName()); // create iterator std::list< vtkPolyData*>::iterator iterator = iRequest.begin(); // in split mode if(mode.compare("Split") == 0) { emit UpdateSeeds(); // loop through all polydatas while(iterator != iRequest.end()) { // need vector for API std::vector polys; polys.push_back(*iterator); std::vector NewTraces = m_TempReference->ApplyAlgo( this->m_Images, this->m_TraceEditingWidget->GetCurrentImageName(), polys, this->m_TraceEditingWidget->GetIsInvertedOn()); // need to send trace ID and time point...! emit TracesSplittedFromAlgo(NewTraces); ++iterator; } emit ClearAllSeeds(); } // merge mode // give all pds at once else { std::vector polys; // fill vector with all polydatas while(iterator != iRequest.end()) { polys.push_back(*iterator); ++iterator; } // apply algo std::vector NewTraces = m_TempReference->ApplyAlgo( this->m_Images, this->m_TraceEditingWidget->GetCurrentImageName(), polys, this->m_TraceEditingWidget->GetIsInvertedOn()); emit TracesMergedFromAlgo(NewTraces.front()); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplyLevelSetAlgo() { this->GetPolydatasFromAlgo(this->m_LevelSetAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplyShapeAlgo() { this->GetPolydatasFromAlgo(this->m_ShapeAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplyWaterShedAlgo() { this->GetPolydatasFromAlgo(this->m_WaterShedAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplySetOfContoursWaterShedAlgo() { this->GetSetOfPolydatasFromAlgo( this->m_SetOfContoursWaterShedAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplySetOfContoursLevelSetAlgo() { this->GetSetOfPolydatasFromAlgo( this->m_SetOfContoursLevelSetAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplySetOfContoursShapeAlgo() { this->GetSetOfPolydatasFromAlgo( this->m_SetOfContoursShapeAlgo); } GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoFilterChanAndVese.cxx0000644000175000017500000002407611667757442024433 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoFilterChanAndVese.h" #include "QGoGUILibConfigure.h" // for apply method #include "vtkImageExport.h" #include "vtkImageData.h" // ITK filter #include "itkChanAndVeseSegmentationFilter.h" #include "itkImage.h" #include "itkVTKImageImport.h" // to cut #include "vtkPlane.h" #include "vtkCutter.h" // to translate #include "vtkTransform.h" #include "vtkTransformPolyDataFilter.h" #include "GoImageProcessor.h" //#include "QGoContourSemiAutoLevelsetWidget.h" //-------------------------------------------------------------------------- QGoFilterChanAndVese::QGoFilterChanAndVese(QObject *iParent, int iDimension) : QGoFilterSemiAutoBase(iParent) { m_Image3D = itk::Image< float, 3 >::New(); m_Image2D = itk::Image< float, 2 >::New(); m_Dimension = iDimension; m_Iterations = 15; m_Curvature = 5; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoFilterChanAndVese:: ~QGoFilterChanAndVese() { } //-------------------------------------------------------------------------- /* //-------------------------------------------------------------------------- void QGoFilterChanAndVese::Filter2D(double *iCenter, const int & iOrientation) { const int dimension = 2; // useful to translate the polydata afterwards setCenter(iCenter); vtkImageData *slice = vtkImageData::New(); // Extract one slice if dimenesion == 2 vtkImageData *input = extractOneSlice(getInput(), iCenter, iOrientation); slice->DeepCopy(input); input->Delete(); // Recompute new center double *newOrigin = slice->GetOrigin(); double center[3]; switch ( iOrientation ) { case 0: { center[0] = iCenter[0] + newOrigin[0]; center[1] = iCenter[1] + newOrigin[1]; center[2] = 0.; break; } case 1: { center[0] = iCenter[0] + newOrigin[0]; center[1] = iCenter[2] + newOrigin[1]; center[2] = 0.; break; } case 2: { center[0] = iCenter[1] + newOrigin[0]; center[1] = iCenter[2] + newOrigin[1]; center[2] = 0.; break; } default: { break; } } // run filter typedef itk::Image< unsigned char, dimension > FeatureImageType; typedef itk::Image< float, dimension > OutputImageType; //VTK to ITK //--------------------------------------------------------- FeatureImageType::Pointer itkImage = ConvertVTK2ITK< unsigned char, dimension >(slice); slice->Delete(); // Extract ROI //--------------------------------------------------------- FeatureImageType::Pointer test2 = ExtractROI< unsigned char, dimension >( itkImage, center, getRadius() ); // Apply filter // Apply LevelSet segmentation filter //--------------------------------------------------------- typedef itk::ChanAndVeseSegmentationFilter< FeatureImageType > SegmentationFilterType; FeatureImageType::PointType pt; SegmentationFilterType::Pointer filter = SegmentationFilterType::New(); filter->SetFeatureImage(test2); filter->SetPreprocess(1); pt[0] = center[0]; pt[1] = center[1]; filter->SetCenter(pt); filter->SetRadius( getRadius() ); filter->SetNumberOfIterations(m_Iterations); filter->SetCurvatureWeight(m_Curvature); filter->Update(); OutputImageType::Pointer test3 = filter->GetOutput(); // Convert output //--------------------------------------------------------- vtkImageData *itk2vtk = ConvertITK2VTK< float, dimension >(test3); setOutput(itk2vtk); itk2vtk->Delete(); vtkPolyData *reconstructed = ReconstructContour(getOutput(), 0.); // Translate to real location (i.e. see_pos[]) vtkTransform *t = vtkTransform::New(); t->Translate(getCenter()[0], getCenter()[1], getCenter()[2]); vtkTransformPolyDataFilter *tf = vtkTransformPolyDataFilter::New(); tf->SetTransform(t); tf->SetInput(reconstructed); tf->Update(); vtkPolyData *contour = vtkPolyData::New(); contour->DeepCopy( tf->GetOutput() ); tf->Delete(); t->Delete(); reconstructed->Delete(); emit ContourCreated(contour); }*/ //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector > QGoFilterChanAndVese:: ApplyFilterSetOf2D( double iRadius, std::vector< vtkPoints* >* iPoints, int iIterations, int iCurvature, int iSampling, GoImageProcessor* iImages, int iChannel) { std::vector > oSetOfContours = std::vector >(); return oSetOfContours; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //itk::Image< float, VImageDimension >::Pointer QGoFilterChanAndVese::Apply2DFilter( // itk::Image< unsigned int, VImageDimension >::Pointer iPointer, // int iIterations, int iCurvature) //{ // //const int dimension = 2; // // useful to translate the polydata afterwards // //setCenter(iCenter); // //vtkImageData *slice = vtkImageData::New(); // // Extract one slice if dimenesion == 2 // //vtkImageData *input = extractOneSlice(getInput(), iCenter, iOrientation); // //slice->DeepCopy(input); // //input->Delete(); // // Recompute new center // //double *newOrigin = slice->GetOrigin(); // //double center[3]; // switch ( iOrientation ) // { // case 0: // { // center[0] = iCenter[0] + newOrigin[0]; // center[1] = iCenter[1] + newOrigin[1]; // center[2] = 0.; // break; // } // case 1: // { // center[0] = iCenter[0] + newOrigin[0]; // center[1] = iCenter[2] + newOrigin[1]; // center[2] = 0.; // break; // } // case 2: // { // center[0] = iCenter[1] + newOrigin[0]; // center[1] = iCenter[2] + newOrigin[1]; // center[2] = 0.; // break; // } // default: // { // break; // } // } // // run filter // typedef itk::Image< unsigned char, dimension > FeatureImageType; // typedef itk::Image< float, dimension > OutputImageType; // //VTK to ITK // //--------------------------------------------------------- // FeatureImageType::Pointer // itkImage = ConvertVTK2ITK< unsigned char, dimension >(slice); // slice->Delete(); // // Extract ROI // //--------------------------------------------------------- // FeatureImageType::Pointer // test2 = ExtractROI< unsigned char, dimension >( itkImage, center, getRadius() ); // // Apply filter // // Apply LevelSet segmentation filter // //---------------------------------------------------------- // const int dimension = 2; // typedef itk::Image< unsigned char, dimension > FeatureImageType; // typedef itk::Image< float, dimension > OutputImageType; // typedef itk::ChanAndVeseSegmentationFilter< FeatureImageType > // SegmentationFilterType; // FeatureImageType::PointType pt; // SegmentationFilterType::Pointer filter = SegmentationFilterType::New(); // //filter->SetFeatureImage(test2); // filter->SetFeatureImage(iPointer); // filter->SetPreprocess(1); // //pt[0] = center[0]; // //pt[1] = center[1]; // //filter->SetCenter(pt); // //filter->SetRadius( getRadius() ); // //filter->SetNumberOfIterations(m_Iterations); // //filter->SetCurvatureWeight(m_Curvature); // filter->SetNumberOfIterations(iIterations); // filter->SetCurvatureWeight(iCurvature); // filter->Update(); // //OutputImageType::Pointer test3 = filter->GetOutput(); // return filter->GetOutput(); // // Convert output // //--------------------------------------------------------- // vtkImageData *itk2vtk = ConvertITK2VTK< float, dimension >(test3); // setOutput(itk2vtk); // itk2vtk->Delete(); // vtkPolyData *reconstructed = ReconstructContour(getOutput(), 0.); // // Translate to real location (i.e. see_pos[]) // vtkTransform *t = vtkTransform::New(); // t->Translate(getCenter()[0], // getCenter()[1], // getCenter()[2]); // vtkTransformPolyDataFilter *tf = vtkTransformPolyDataFilter::New(); // tf->SetTransform(t); // tf->SetInput(reconstructed); // tf->Update(); // vtkPolyData *contour = vtkPolyData::New(); // contour->DeepCopy( tf->GetOutput() ); // tf->Delete(); // t->Delete(); // reconstructed->Delete(); // emit ContourCreated(contour); //} GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoFilterWatershed.h0000644000175000017500000001524111667757442023661 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoFilterWatershed_h #define __QGoFilterWatershed_h #include "QGoFilterSemiAutoBase.h" #include "itkWatershedBasedCellSegmentation.h" #include "QGoGUILibConfigure.h" class GoImageProcessor; /** * \class QGoFilterWatershed * \brief Watershed segmentation algorithm implementation. * Can generate contours and meshes. * Will generate 2D objects if m_Dimension<2, 3D objects in the other case. */ class QGOGUILIB_EXPORT QGoFilterWatershed:public QGoFilterSemiAutoBase { Q_OBJECT public: typedef int OutputPixelType; typedef itk::Image< int, 3 > Output3DType; typedef Output3DType::Pointer Output3DPointer; typedef itk::Image< int, 2 > Output2DType; typedef Output2DType::Pointer Output2DPointer; /** \brief Constructor */ explicit QGoFilterWatershed(QObject *iParent = NULL, int iDimension = 2); /** \brief Destructor */ ~QGoFilterWatershed(); template< typename TPixel > void Apply3DFilter( typename itk::Image< TPixel, 3 >::Pointer iITKInput, const int& iThresMin, const int& iThresMax, const double& iCorrTresh, const double& iAlpha, const double& iBeta) { const unsigned int Dimension = 3; typedef itk::Image< TPixel, Dimension > FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef itk::Image< double, Dimension > InputImageType; typedef typename InputImageType::IndexType InputImageIndexType; typedef typename InputImageType::Pointer InputImagePointer; typedef itk::Image< int, Dimension > SegmentImageType; typedef typename SegmentImageType::Pointer SegmentImagePointer; // Apply filter // Apply watershed segmentation filter //--------------------------------------------------------- typedef itk::Image< TPixel, 3 > FeatureImageType; typedef itk::WatershedBasedCellSegmentation SegmentationFilterType; typedef typename SegmentationFilterType::Pointer SegmentationFilterPointer; // ITK filter SegmentationFilterPointer filter = SegmentationFilterType::New(); filter->SetInput(iITKInput); filter->SetNucleusThresholdMin(iThresMin); filter->SetNucleusThresholdMax(iThresMax); filter->SetCorrelationThreshold1(iCorrTresh); filter->SetAlpha(iAlpha); filter->SetBeta(iBeta); filter->Update(); typename Output3DType::Pointer resulting_image = filter->GetOutput(); if( resulting_image.IsNotNull() ) { m_Image3D->Graft( resulting_image ); } else { itkGenericExceptionMacro( <<"WaterShedSegmentationFilter's output is NULL" ); } } template< typename TPixel > void Apply2DFilter( typename itk::Image< TPixel, 2 >::Pointer iITKInput, const int& iThresMin, const int& iThresMax, const double& iCorrTresh, const double& iAlpha, const double& iBeta) { const unsigned int Dimension = 2; typedef itk::Image< TPixel, Dimension > FeatureImageType; typedef typename FeatureImageType::Pointer FeatureImagePointer; typedef itk::Image< double, Dimension > InputImageType; typedef typename InputImageType::IndexType InputImageIndexType; typedef typename InputImageType::Pointer InputImagePointer; typedef itk::Image< int, Dimension > SegmentImageType; typedef typename SegmentImageType::Pointer SegmentImagePointer; // Apply filter // Apply watershed segmentation filter //--------------------------------------------------------- typedef itk::Image< TPixel, 2 > FeatureImageType; typedef itk::WatershedBasedCellSegmentation SegmentationFilterType; typedef typename SegmentationFilterType::Pointer SegmentationFilterPointer; // ITK filter SegmentationFilterPointer filter = SegmentationFilterType::New(); filter->SetInput(iITKInput); filter->SetNucleusThresholdMin(iThresMin); filter->SetNucleusThresholdMax(iThresMax); filter->SetCorrelationThreshold1(iCorrTresh); filter->SetAlpha(iAlpha); filter->SetBeta(iBeta); filter->Update(); typename Output2DType::Pointer resulting_image = filter->GetOutput(); if( resulting_image.IsNotNull() ) { m_Image2D->Graft( resulting_image ); } else { itkGenericExceptionMacro( <<"WaterShedSegmentationFilter's output is NULL" ); } } std::vector > ApplyFilterSetOf2D(double iRadius, int iThresMin, int iThresMax, double iCorrTresh, double iAlpha, double iBeta, int iSampling, std::vector< vtkPoints* >* iPoints, GoImageProcessor* iImages, int iChannel); Output3DType::Pointer GetOutput3D() { return m_Image3D; } Output2DType::Pointer GetOutput2D() { return m_Image2D; } private: void Filter2D(double *iCenter, const int & iOrientation); Output3DType::Pointer m_Image3D; Output2DType::Pointer m_Image2D; int m_TreshMin; int m_TreshMax; double m_CorrTresh; double m_Alpha; double m_Beta; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.h0000644000175000017500000004064611667757442024034 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSegmentationAlgo_h #define __QGoSegmentationAlgo_h #include "QGoAlgorithmWidget.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "QGoGUILibConfigure.h" // convert VTK to ITK #include "itkImage.h" #include "itkVTKImageImport.h" #include "vtkImageExport.h" #include "vtkitkAdaptor.h" // convert itk to vtk #include "itkImageToVTKImageFilter.h" // extract 2d from 2d or 3d from 3d #include "itkRegionOfInterestImageFilter.h" // extract 2d from 3d #include "itkExtractImageFilter.h" // change info #include "itkChangeInformationImageFilter.h" class GoImageProcessor; /** \class QGoSegmentationAlgo \brief abstract class to be the interface between the algorithms for meshes and contours and GoFigure */ class QGOGUILIB_EXPORT QGoSegmentationAlgo:public QObject { Q_OBJECT public: explicit QGoSegmentationAlgo(QWidget *iParent = 0); virtual ~QGoSegmentationAlgo(); /** \brief return the algowidget */ QGoAlgorithmWidget* GetAlgoWidget(); /** \brief return the vtkpolydata created by the algorithm */ /*virtual std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false) = 0;*/ /* * \note Nicolas-shouldnt be public-move to protected */ /* * \brief Extract region of interest, given a bounding box and a list of vtk images * \param[in] iBounds bounding box (xmin, xmax, ymin, ymax, zmin, zmax) * \param[in] iImages vector of vtkimagedata * \return list of roi */ std::vector VTKExtractROI( const std::vector& iBounds, const std::vector< vtkSmartPointer< vtkImageData > >& iImages); /* * \brief Extract region of interest, given a bounding box and a vtk image * \param[in] iBounds bounding box (xmin, xmax, ymin, ymax, zmin, zmax) * \param[in] iImage vtkimagedata * \return roi */ vtkImageData* VTKExtractROI( const std::vector& iBounds, const vtkSmartPointer< vtkImageData > & iImage); /* * \brief Convert a vtkImage to a itkImage. If we call after "ExtractROI", * the dimension should be 3 all the time. * (Even if we extract a2D region from a 3d image) * \tparam PixelType type of pixel (unsigned char, etc.) * \tparam VImageDimension dimension of the image (2 or 3) * \param[in] iInput Pointer to a vtkImageData * \return Pointer to an itkImage */ template< class PixelType, unsigned int VImageDimension > typename itk::Image< PixelType, VImageDimension >::Pointer ConvertVTK2ITK(vtkImageData *iInput) { // make sure there is an input assert ( iInput ); //Export VTK image to ITK vtkSmartPointer exporter = vtkSmartPointer::New(); exporter->SetInput(iInput); exporter->Update(); // ImageType typedef itk::Image< PixelType, VImageDimension > ImageType; // Import VTK Image to ITK typedef itk::VTKImageImport< ImageType > ImageImportType; typedef typename ImageImportType::Pointer ImageImportPointer; ImageImportPointer importer = ImageImportType::New(); ConnectPipelines< vtkImageExport, ImageImportPointer >( exporter, importer); typename ImageType::Pointer itkImage = importer->GetOutput(); itkImage->DisconnectPipeline(); return itkImage; } /* * \brief Convert a itkImage to a vtkImage. If we call after "ExtractROI", * the dimension should be 3 all the time. * (Even if we extract a2D region from a 3d image) * \tparam PixelType type of pixel (unsigned char, etc.) * \tparam VImageDimension dimension of the image (2 or 3) * \param[in] iInput Pointer to an itkImage * \return Pointer to an vtkImageData */ template< class PixelType, unsigned int VImageDimension > vtkImageData* ConvertITK2VTK(typename itk::Image< PixelType, VImageDimension >::Pointer iInput) { typedef itk::Image< PixelType, VImageDimension > InternalImageType; typedef itk::ImageToVTKImageFilter< InternalImageType > ConverterType; typedef typename ConverterType::Pointer ConverterPointer; ConverterPointer converter = ConverterType::New(); converter->SetInput(iInput); try { converter->Update(); } catch (itk::ExceptionObject & err) { std::cerr << "converter Exception:" << err << std::endl; } vtkImageData* output_image = vtkImageData::New(); output_image->DeepCopy( converter->GetOutput() ); return output_image; } //------------------------------------------------------------------------- template< class PixelType, unsigned int VImageDimension > typename itk::Image< PixelType, VImageDimension >::Pointer ITKExtractROI( const std::vector< double > & iBounds, typename itk::Image< PixelType, VImageDimension >::Pointer iInput ) { typedef itk::Image< PixelType, VImageDimension > ImageType; typedef typename ImageType::PointType ImagePointType; typedef typename ImageType::IndexType ImageIndexType; typedef typename ImageType::IndexValueType ImageIndexValueType; typedef typename ImageType::SizeType ImageSizeType; typedef typename ImageType::SizeValueType ImageSizeValueType; typedef typename ImageType::RegionType ImageRegionType; typedef typename ImageType::SpacingType ImageSpacingType; assert( iBounds.size() == 2 * VImageDimension ); if ( iInput.IsNull() ) { std::cerr << "iInput is Null" << std::endl; } ImagePointType t_min, t_max; unsigned int k = 0; for( unsigned int dim = 0; dim < VImageDimension; dim++ ) { t_min[dim] = iBounds[k++]; t_max[dim] = iBounds[k++]; } ImageIndexType startOfROI, endOfROI; iInput->TransformPhysicalPointToIndex( t_min, startOfROI ); iInput->TransformPhysicalPointToIndex( t_max, endOfROI ); ImageSizeType sizeOfLargeImage = iInput->GetLargestPossibleRegion().GetSize(); ImageSizeType size; size.Fill( 0 ); for( unsigned int dim = 0; dim < VImageDimension; dim++ ) { if( startOfROI[dim] < 0 ) { startOfROI[dim] = 0; } if( static_cast< ImageSizeValueType >( startOfROI[dim] ) > sizeOfLargeImage[dim] ) { startOfROI[dim] = sizeOfLargeImage[dim] - 1; } if( endOfROI[dim] < 0 ) { endOfROI[dim] = 0; } if( static_cast< ImageSizeValueType >( endOfROI[dim] ) > sizeOfLargeImage[dim] ) { endOfROI[dim] = sizeOfLargeImage[dim] - 1; } if( endOfROI[dim] - startOfROI[dim] < 0 ) { size[dim] = 0; } else { size[dim] = endOfROI[dim] - startOfROI[dim]; } } ImageRegionType region; region.SetSize(size); region.SetIndex(startOfROI); typedef itk::RegionOfInterestImageFilter< ImageType, ImageType > ROIFilterType; typedef typename ROIFilterType::Pointer ROIFilterPointer; ROIFilterPointer roi = ROIFilterType::New(); roi->SetInput(iInput); roi->SetRegionOfInterest(region); try { roi->Update(); } catch (itk::ExceptionObject & err) { std::cerr << "roi Exception:" << err << std::endl; } return roi->GetOutput(); } template< class PixelType> typename itk::Image< PixelType, 2>::Pointer ITKExtractSlice( const std::vector< double > & iBounds, typename itk::Image< PixelType, 3 >::Pointer iInput ) { typedef itk::Image< PixelType, 3 > InputImageType; typedef itk::Image< PixelType, 2 > OutputImageType; typedef typename InputImageType::PointType ImagePointType; typedef typename InputImageType::IndexType ImageIndexType; typedef typename InputImageType::IndexValueType ImageIndexValueType; typedef typename InputImageType::SizeType ImageSizeType; typedef typename InputImageType::SizeValueType ImageSizeValueType; typedef typename InputImageType::RegionType ImageRegionType; typedef typename InputImageType::SpacingType ImageSpacingType; typedef typename OutputImageType::PointType oImagePointType; typedef typename OutputImageType::OffsetType oImageOffsetType; ImagePointType t_min, t_max; oImagePointType new_origin; // create ROI unsigned int k = 0; for( unsigned int dim = 0; dim < 3; dim++ ) { t_min[dim] = iBounds[k++]; t_max[dim] = iBounds[k++]; } ImageIndexType startOfROI, endOfROI; iInput->TransformPhysicalPointToIndex( t_min, startOfROI ); iInput->TransformPhysicalPointToIndex( t_max, endOfROI ); ImageSizeType sizeOfLargeImage = iInput->GetLargestPossibleRegion().GetSize(); ImageSizeType size; size.Fill( 0 ); #ifdef ITKv4 oImageOffsetType new_offset; #else long int* new_offset = new long int[3]; #endif int l = 0; for( unsigned int dim = 0; dim < 3; dim++ ) { if( startOfROI[dim] < 0 ) { startOfROI[dim] = 0; } if( static_cast< ImageSizeValueType >( startOfROI[dim] ) > sizeOfLargeImage[dim] ) { startOfROI[dim] = sizeOfLargeImage[dim] - 1; } if( endOfROI[dim] < 0 ) { endOfROI[dim] = 0; } if( static_cast< ImageSizeValueType >( endOfROI[dim] ) > sizeOfLargeImage[dim] ) { endOfROI[dim] = sizeOfLargeImage[dim] - 1; } size[dim] = endOfROI[dim] - startOfROI[dim]; if( size[dim] < 0 ) { size[dim] = 0; } // new origin if( size[dim] > 0 ) { new_origin[l] = t_min[dim]; double sizeTest = startOfROI[dim]; new_offset[l] = -sizeTest; ++l; } } ImageRegionType region; region.SetSize(size); region.SetIndex(startOfROI); typedef itk::ExtractImageFilter< InputImageType, OutputImageType > FilterType; typedef typename FilterType::Pointer FilterTypePointer; FilterTypePointer filter = FilterType::New(); filter->SetExtractionRegion( region ); filter->SetInput( iInput ); #ifdef ITKv4 filter->SetDirectionCollapseToIdentity(); #endif try { filter->Update(); } catch (itk::ExceptionObject & err) { std::cerr << "extract slice Exception:" << err << std::endl; } // change information typedef typename itk::ChangeInformationImageFilter CenterFilterType; typedef typename CenterFilterType::Pointer CenterFilterTypePointer; CenterFilterTypePointer center = CenterFilterType::New(); center->SetInput(filter->GetOutput()); center->ChangeOriginOn(); center->SetOutputOrigin(new_origin); center->ChangeRegionOn(); center->SetOutputOffset(new_offset); try { center->Update(); } catch (itk::ExceptionObject & err) { std::cerr << "change information slice Exception:" << err << std::endl; } return center->GetOutput(); } /* * \brief Generate list of polydata given a list of vtkimages and a threshold * \param[in] iInputImage list of images * \param[in] iThreshold threshold * \return list of polydatas */ std::vector ExtractPolyData( std::vector& iInputImage, const double & iThreshold); /* * \brief Generate a polydata given a vtkimage and a threshold * \param[in] iInputImage vtk image * \param[in] iThreshold threshold * \return polydata */ vtkSmartPointer ExtractPolyData( vtkImageData *iInputImage, const double & iThreshold); /* * \brief Decimate a polydata * \param[in] iPolyData polyData to be decimated * \param[in] iNumberOfPoints target number of points * \return Decimated polyData */ vtkSmartPointer DecimatePolyData( vtkSmartPointer& iPolyData, const unsigned int& iNumberOfPoints); /* * \brief Enable decimation during polydata extraction. * \param[in] iDecimate yes (true), no (false) */ void SetDecimate(bool& iDecimate); /* * \brief Is decimation enabled? * \return true (yes), false (no) */ bool GetDecimate(); /* * \brief Set target number of points for polydata extraction * \param[in] iNumberOfPoints number of points */ void SetNumberOfPoints( const unsigned int& iNumberOfPoints); /* * \brief Get target number of points for polydata extraction * \return number of points */ unsigned int GetNumberOfPoints() const; private: /* * \brief Reconstruct a contour from a vtkImageData and a threshold * \param[in] iInputImage vtkImageData * \param[in] iThreshold threshold * \return Pointer to a vtkPolyData */ vtkSmartPointer ExtractContour( vtkSmartPointer iInputImage, const double & iThreshold); /* * \brief Reorganize points within a contour * Required if we want to reedit this contour after. * 1-reorganize * \param[in] iInputImage vtkImageData * \return Pointer to a vtkPolyData */ vtkSmartPointer ReorganizeContour( vtkSmartPointer iInputImage); /* * \brief Reconstruct a mesh from a vtkImageData and a threshold * \param[in] iInputImage vtkImageData * \param[in] iThreshold threshold * \return Pointer to a vtkPolyData */ vtkSmartPointer ExtractMesh( vtkSmartPointer iInputImage, const double & iThreshold); /* * \brief Decimate a contour (line) * \param[in] iPolyData polyData to be decimated * \param[in] iNumberOfPoints target number of points * \return Decimated polyData */ vtkSmartPointer DecimateContour( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints); /* * \brief Decimate a mesh * \param[in] iPolyData polyData to be decimated * \param[in] iNumberOfPoints target number of points * \return Decimated polyData */ vtkSmartPointer DecimateMesh( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints); bool m_Decimate; unsigned int m_NumberOfPoints; protected: QGoAlgorithmWidget* m_AlgoWidget; /** \brief construct the algowidget with the different parameters */ virtual void SetAlgoWidget(QWidget* iParent = 0) = 0; /** \brief delete the different parameters */ virtual void DeleteParameters() = 0; /* * \todo Arnaud has something for itkimage to vtkpolydata in 3d */ //add a method std::vector ConvertITKImagesToPolyData(std::vector iImages) //add a method std::vector GetAttribut(std::vector iNewTraces) //add a method itkImage ConvertVTKToITK(vtkImageIData iImage) }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoTraceEditingWidget.cxx0000644000175000017500000001760511667757442024654 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTraceEditingWidget.h" #include "QGoModesManagerWidget.h" #include "QGoAlgorithmsManagerWidget.h" #include QGoTraceEditingWidget::QGoTraceEditingWidget( std::string iTraceName,std::vector iVectChannels, QStringList iListTimePoints, QWidget *iParent) { this->Initialize(iVectChannels, iListTimePoints, iParent); this->setWindowTitle(tr("%1 Editing").arg(iTraceName.c_str())); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoTraceEditingWidget::~QGoTraceEditingWidget() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidget::Initialize(std::vector iVectChannels, QStringList iListTimePoints, QWidget *iParent) { this->m_ListTimePoints = iListTimePoints; this->m_ModeEditingWidget = new QGoModesManagerWidget( iVectChannels, iListTimePoints, this); this->m_VLayout = new QVBoxLayout; this->SetModesManager(this->m_ModeEditingWidget); this->setLayout(this->m_VLayout); this->m_VLayout->setSizeConstraint(QLayout::SetFixedSize); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidget::AddMode( std::string iModeName, QWidget* iModeWidget, bool ModeNeedSeeds) { QWidget* ModeWidget = new QWidget; if (iModeWidget != 0) { ModeWidget = iModeWidget; } this->m_ModeEditingWidget->AddWidgetWithModeName(iModeName, ModeWidget, ModeNeedSeeds); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidget::AddMode(QGoAlgorithmsManagerWidget* iAlgoModeWidget, bool ModeNeedSeeds) { this->m_ModeEditingWidget->AddWidgetWithModeName(iAlgoModeWidget->GetModeName(), iAlgoModeWidget, ModeNeedSeeds); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidget::SetModesManager(QGoModesManagerWidget* iModeWidget) { this->m_ModeEditingWidget = iModeWidget; this->m_VLayout->addWidget(this->m_ModeEditingWidget); QObject::connect( this->m_ModeEditingWidget, SIGNAL (SetSeedInteractorBehaviour(bool) ), this, SIGNAL (SetSeedInteractorBehaviour(bool) ) ); QObject::connect( this->m_ModeEditingWidget, SIGNAL(ResetClicked() ), this, SIGNAL(ResetClicked() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidget::SetANewModesManager(QGoModesManagerWidget* iModeWidget) { delete this->m_ModeEditingWidget; this->SetModesManager(iModeWidget); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidget::AddAlgoWidgetForSemiAutomaticMode( QGoAlgorithmWidget* iAlgoWidget) { this->m_ModeEditingWidget->AddAlgoWidgetForSemiAutomaticMode(iAlgoWidget); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidget::AddAlgoWidgetForAutomaticMode( QGoAlgorithmWidget* iAlgoWidget) { this->m_ModeEditingWidget->AddAlgoWidgetForAutomaticMode(iAlgoWidget); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidget::AddWidgetForManualMode(QWidget* iWidget, QStringList iListTimePoint, bool ModeNeedSeeds) { this->m_ModeEditingWidget->AddWidgetForManualMode(iWidget, iListTimePoint, ModeNeedSeeds); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoTraceEditingWidget::GetCurrentImageName() { return this->m_ModeEditingWidget->GetCurrentImageName(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoTraceEditingWidget::GetSelectedTimePoint() { return this->m_ModeEditingWidget->GetSelectedTimePoint(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoTraceEditingWidget::GetIsInvertedOn() { return this->m_ModeEditingWidget->GetIsInvertedOn(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidget::CheckTheCurrentMode(bool IsVisible) { if (IsVisible) { this->m_ModeEditingWidget->SetTheRightMode(); } else { emit SetSeedInteractorBehaviour(false); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidget::SetTSliceForClassicView(int iTimePoint) { this->m_ModeEditingWidget->SetTSliceForClassicViewInAllAlgoModes(iTimePoint); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidget::SetTSliceForDopplerView( QHash iListTimePoints, int iChannelNumber) { this->m_ModeEditingWidget->SetTSliceForDopplerViewInAllAlgoModes( iListTimePoints, iChannelNumber); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoTraceEditingWidget::GetCurrentModeName() { return this->m_ModeEditingWidget->GetCurrentModeName(); } GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoAlgorithmWidget.cxx0000644000175000017500000001042611667757442024232 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoAlgorithmWidget.h" #include #include #include "ctkCollapsibleGroupBox.h" #include "ConvertToStringHelper.h" QGoAlgorithmWidget::QGoAlgorithmWidget(std::string iMethodName, QWidget *iParent ) :QWidget(iParent) { this->m_MethodName = iMethodName; this->Initialize(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoAlgorithmWidget::~QGoAlgorithmWidget() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoAlgorithmWidget::Initialize() { this->m_VBoxLayout = new QVBoxLayout; this->m_ParamLayout = new QFormLayout; this->m_AdvParamLayout = new QFormLayout; this->m_VBoxLayout->addLayout(this->m_ParamLayout); this->setLayout(this->m_VBoxLayout); this->m_VBoxLayout->setSizeConstraint(QLayout::SetFixedSize); this->m_AdvParamAlreadySetUp = false; //can not setflat + set checked before inserting the parameters //or no ones will appear... //this->m_AdvParamGroupBox->setFlat(true); //this->m_AdvParamGroupBox->setChecked(false); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoAlgorithmWidget::GetMethodName() { return this->m_MethodName; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoAlgorithmWidget::show() { if (!this->m_AdvParamAlreadySetUp) //in order not to add another collapsible box //each time the widget is shown { if (this->m_AdvParamLayout->rowCount()>0 ) //if there is at least one advanced parameter, //if not, no need to add the collapsible box { ctkCollapsibleGroupBox* AdvParamGroupBox = new ctkCollapsibleGroupBox(tr("Advanced")); AdvParamGroupBox->setLayout(this->m_AdvParamLayout); AdvParamGroupBox->setFlat(true); AdvParamGroupBox->setChecked(false); this->m_VBoxLayout->addWidget(AdvParamGroupBox); } this->m_AdvParamAlreadySetUp = true; //no need to check again when widget shown another time } QWidget::show(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoAlgorithmWidget::EmitApplyAlgo() { emit ApplyAlgo(); }GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshLevelSetAlgo.h0000644000175000017500000001276611667757442023741 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoMeshLevelSetAlgo_h #define __QGoMeshLevelSetAlgo_h #include "QGoLevelSetAlgo.h" #include "QGoFilterChanAndVese.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "vtkTransform.h" #include "vtkTransformPolyDataFilter.h" #include "GoImageProcessor.h" /** \class QGoMeshLevelSetAlgo \brief class to be the interface between the levelset algo for meshes and GoFigure */ class QGoMeshLevelSetAlgo: public QGoLevelSetAlgo { public: QGoMeshLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget *iParent = 0); ~QGoMeshLevelSetAlgo(); std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false); protected: template < class TPixel > // note this will work only in 3D, so we can remove the template // parameter on the image dimension //unsigned int VImageDimension > vtkPolyData * ApplyLevelSetFilter( const std::vector& iCenter, typename itk::Image< TPixel, 3 >::Pointer iImages) { assert( iCenter.size() == 3); const unsigned int ImageDimension = 3; typedef TPixel PixelType; typedef itk::Image< PixelType, ImageDimension > ImageType; typedef typename ImageType::Pointer ImagePointer; // let's compute the bounds of the region of interest double radius = this->m_Radius->GetValue(); std::vector< double > bounds( 2 * ImageDimension, 0. ); unsigned int k = 0; for( unsigned int dim = 0; dim < ImageDimension; dim++ ) { bounds[k++] = iCenter[dim] - 2. * radius; bounds[k++] = iCenter[dim] + 2. * radius; } // then let's extract the Region of Interest ImagePointer ITK_ROI_Image = this->ITKExtractROI< PixelType, ImageDimension >( bounds, iImages ); // Compute the segmentation in 3D // why no call to the filter itself...? QGoFilterChanAndVese Filter; Filter.Apply3DFilter< PixelType >( ITK_ROI_Image, iCenter, 0, // we dont want to extract ROI from input since we already did this->m_Iterations->GetValue(), this->m_Curvature->GetValue()); typename QGoFilterChanAndVese::Output3DPointer ItkOutPut = Filter.GetOutput3D(); // Here it would be better if the mesh extraction would be performed directly // in ITK instead. vtkImageData * FilterOutPutToVTK = this->ConvertITK2VTK< typename QGoFilterChanAndVese::OutputPixelType, ImageDimension>( ItkOutPut ); vtkPolyData* temp_output = this->ExtractPolyData(FilterOutPutToVTK, 0); FilterOutPutToVTK->Delete(); double temp_bounds[6]; temp_output->GetBounds( temp_bounds ); double temp_center[3]; temp_center[0] = ( temp_bounds[0] + temp_bounds[1] ) * 0.5; temp_center[1] = ( temp_bounds[2] + temp_bounds[3] ) * 0.5; temp_center[2] = ( temp_bounds[4] + temp_bounds[5] ) * 0.5; vtkSmartPointer< vtkTransform > translation = vtkSmartPointer< vtkTransform >::New(); /// \todo fix it to get the real center!!! translation->Translate(iCenter[0] - temp_center[0], iCenter[1] - temp_center[1], iCenter[2] - temp_center[2] ); vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform = vtkSmartPointer< vtkTransformPolyDataFilter >::New(); mesh_transform->SetTransform(translation); mesh_transform->SetInput( temp_output ); mesh_transform->Update(); temp_output->Delete(); // MIGHT LEAK! CHECK IT IS DELETED! vtkPolyData* mesh = vtkPolyData::New(); mesh->DeepCopy( mesh_transform->GetOutput() ); return mesh; } }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoFilterSemiAutoBase.h0000644000175000017500000001542511667757442024260 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoFilterSemiAutoBase_h #define __QGoFilterSemiAutoBase_h #include // QT #include #include // VTK to ITK #include "vtkImageExport.h" #include "itkVTKImageImport.h" #include "itkImage.h" #include "vtkSmartPointer.h" // for the signals #include "vtkPolyData.h" class vtkImageData; class vtkPoints; class vtkImageExport; #include "QGoGUILibConfigure.h" /** * \class QGoFilterSemiAutoBase * \brief Connects the common signals regarding the seeds segmentation * Provides methods to convert images from itk to vtk. * Provides methods to convert images from vtk to itk. * Provides methods to extract ROI from your image and to enhance your meshes. */ class QGOGUILIB_EXPORT QGoFilterSemiAutoBase:public QObject { Q_OBJECT public: /** \brief Constructor */ explicit QGoFilterSemiAutoBase(QObject *iParent = NULL); /** \brief Destructor */ virtual ~QGoFilterSemiAutoBase(); /** * \brief Set Name of the filter in the combo box * \param[in] iName Name of the filter */ void setName(QString iName); /** * \brief Get Name of the filter in the combo box * \return Name of the filter */ QString getName(); /** * \brief Set the widget associated to the filter * \param[in] iWidget Widget of the filter */ void setWidget(QWidget *iWidget); /** * \brief Get the widget associated to the filter * \return Widget of the filter */ QWidget * getWidget(); vtkSmartPointer getInput(); void setOutput(vtkImageData *iOutput); vtkImageData * getOutput(); void setCenter(double *iCenter); /** * \brief Get the center of the area to be segmented * \return Center of the area to be segmented */ double * getCenter(); /** * \brief Get the radius of the area to be segmented * \return Radius of the area to be segmented */ double getRadius(); int getSampling(); /** * \brief Get the channel to be segmented * \return Channel to be segmented */ int getChannel(); void setPoints(vtkPoints *iPoints); vtkPoints * getPoints(); void setOriginalImageMC(std::vector< vtkSmartPointer > *iOriginalImage); vtkImageData * extractOneSlice(vtkImageData *iOriginalImage, double *iOrigin, int iDirection); vtkPolyData * ReconstructContour(vtkImageData *iInputImage, const double & iThreshold); vtkPolyData * ReorganizeContour(vtkPolyData *iInputImage = NULL, bool iDecimate = true ); vtkPolyData * ReconstructMesh(vtkImageData *iInputImage, const double & iThreshold); /* * \brief Connect the widget to the algorithm and to gofigure * \param[in] iFilterNumber Filter to be connected */ virtual void ConnectSignals(int iFilterNumber); /* * \brief Convert an image from VTK to ITK * \param[in] iInput VTK image to be converted * \return ITK image */ template< class PixelType, unsigned int VImageDimension > typename itk::Image< PixelType, VImageDimension >::Pointer ConvertVTK2ITK(vtkImageData *iInput); /* * \brief Convert an image from ITK to VTK * \param[in] iInput ITK image to be converted * \return VTK image */ template< class PixelType, unsigned int VImageDimension > vtkImageData * ConvertITK2VTK(typename itk::Image< PixelType, VImageDimension >::Pointer iInput); /* * \brief Extract Region Of Interest (ROI) from an ITK image * \param[in] iCenter Center of the ROI * \param[in] iRadius Radius of the ROI */ template< class PixelType, unsigned int VImageDimension > typename itk::Image< PixelType, VImageDimension >::Pointer ExtractROI(typename itk::Image< PixelType, VImageDimension >::Pointer, double *iCenter, double iRadius); int m_Dimension; public slots: void UpdateVisibility(int iFilter); void setRadius(double iRadius); void setChannel(int iChannel = 0); void setSampling(int iSampling); void UpdateAdvancedMode(bool); signals: void MeshCreated(vtkPolyData *, int timePoint = 0); void ContourCreated(vtkPolyData *); void ImageProcessed(); void UpdateSeeds(); void SegmentationFinished(); void CreateCorrespondingMesh(int); void AddContourForMeshToContours(vtkPolyData *); private: vtkImageExport * m_vtk2itkImage; vtkImageData * m_Output; QString m_Name; QWidget * m_Widget; double m_Center[3]; double m_Radius; int m_Number; int m_Channel; vtkPoints * m_Points; std::vector< vtkSmartPointer > *m_OriginalImageMC; int m_Sampling; }; #include "QGoFilterSemiAutoBase.txx" #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshSplitDanielssonDistanceAlgo.h0000644000175000017500000000526511667757442027000 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoMeshSplitDanielssonDistanceAlgo_h #define __QGoMeshSplitDanielssonDistanceAlgo_h #include "QGoSplitDanielssonDistanceAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" class GoImageProcessor; /** \class QGoMeshSplitDanielssonDistanceAlgo \brief class to be the interface between the QGoMeshSplitDanielssonDistanceAlgo algo for meshes and GoFigure */ class QGoMeshSplitDanielssonDistanceAlgo: public QGoSplitDanielssonDistanceAlgo { public: QGoMeshSplitDanielssonDistanceAlgo(std::vector< vtkPoints* >* iSeeds, QWidget *iParent = 0); ~QGoMeshSplitDanielssonDistanceAlgo(); std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, std::vector iPolyData, bool iIsInvertedOn); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSemiAutoSegmentationAlgo.cxx0000644000175000017500000000750011667757442026046 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSemiAutoSegmentationAlgo.h" //------------------------------------------------------------------------- QGoSemiAutoSegmentationAlgo:: QGoSemiAutoSegmentationAlgo( std::vector< vtkPoints* >* iSeeds, QWidget *iParent) : QGoSegmentationAlgo( iParent ), m_Seeds( iSeeds ) {} //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoSemiAutoSegmentationAlgo::~QGoSemiAutoSegmentationAlgo() { /* * \note Nicolas-Requiered this one? We just copy the address in the constructor. if(this->m_Seeds) { this->m_Seeds->Delete(); } */ } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoSemiAutoSegmentationAlgo::SetAlgoWidget(QWidget* iParent) { if (this->m_AlgoWidget != NULL) { m_Radius = new QGoAlgoParameter("Radius", false, 0.1, 99.99, 2, 3); this->m_AlgoWidget->AddParameter(m_Radius); } else { std::cout<<"the widget has to be created before"; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoSemiAutoSegmentationAlgo:: GetBounds(const std::vector& iCenter, const double& iRadius, const unsigned int& iOrientation) { assert( iCenter.size() == 3 ); assert( iRadius >= 0. ); assert( iOrientation < 4 ); std::vector boundingBox( 6, 0. ); unsigned int k = 0; for(unsigned int i=0; i<3; i++) { if(i == iOrientation) { boundingBox[k++] = iCenter[i]; boundingBox[k++] = iCenter[i]; } else { boundingBox[k++] = iCenter[i] - iRadius; boundingBox[k++] = iCenter[i] + iRadius; } } return boundingBox; } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshLevelSetAlgo.cxx0000644000175000017500000000713311667757442024304 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoMeshLevelSetAlgo.h" #include "QGoFilterChanAndVese.h" QGoMeshLevelSetAlgo:: QGoMeshLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) :QGoLevelSetAlgo(iSeeds, iParent) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoMeshLevelSetAlgo::~QGoMeshLevelSetAlgo() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoMeshLevelSetAlgo::ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn) { std::vector oNewMeshes = std::vector(); if ( this->m_Radius->GetValue() <= 0 ) { std::cerr << "Radius should be > 0 " << std::endl; return oNewMeshes; } double Center[3]; std::vector CenterVect(3); // LOOP FOR EACH SEED for( size_t id = 0; id < this->m_Seeds->size(); id++ ) { for ( int i = 0; i < (*this->m_Seeds)[id]->GetNumberOfPoints(); i++ ) { (*this->m_Seeds)[id]->GetPoint(i, Center); CenterVect[0] = Center[0]; CenterVect[1] = Center[1]; CenterVect[2] = Center[2]; vtkPolyData* temp_output = this->ApplyLevelSetFilter< unsigned char >( CenterVect, iImages->getImageITK< unsigned char, 3>(iChannel)); //input raw image if(temp_output->GetNumberOfCells() > 0) { oNewMeshes.push_back( temp_output ); } /*else { std::cout << "No polydata could be generated - check parameters" << std::endl; temp_output->Delete(); }*/ } } return oNewMeshes; } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoContourManualSegmentation.h0000644000175000017500000000757211667757442025742 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoContourManualSegmentation_h #define __QGoContourManualSegmentation_h #include #include #include "QGoGUILibConfigure.h" class QGoContourManualSegmentationWidget; /** * \class QGoContourManualSegmentation * \ingroup QGoContourManual * \brief Base class for contour manual segmentation */ class QGOGUILIB_EXPORT QGoContourManualSegmentation:public QObject { Q_OBJECT public: /** * \brief Constructor */ explicit QGoContourManualSegmentation(QWidget *parent = 0); /** * \brief Destructor */ ~QGoContourManualSegmentation(); /** * \brief Get the base widget for the contour manual segmentation * \return QWidget pointer to the base widget */ QWidget * getWidget(); /** * \brief Set the reedit mode * \param[in] iReeditMode true: we are in reedit mode, false:classic segmentation */ void SetReeditMode(bool iReeditMode); /** * \brief Get the reedit mode * \return true: we are in reedit mode, false:classic segmentation */ bool GetReeditMode(); public slots: /** * \brief Generate the widget contour properties if it has been modified * \param[in] iModified true:generate new properties, false:don't do anything */ void GenerateContourRepresentationProperties(bool iModified = false); signals: //void ContourRepresentationPropertiesChanged(); /** * \brief Signal sent if we click on the "Validate" button in the widget */ void validateContour(); /** * \brief Signal sent if we click on the "Reinitialize" button in the widget */ void reinitializeContour(); /** * \brief Signal sent if new properties have been generated by * GenerateContourRepresentationProperties() */ void changeContourRepresentationProperty(float iLinewidth, QColor iLinecolor, QColor iNodecolor, QColor iActivenodecolor); protected: QGoContourManualSegmentationWidget *m_ContourSegmentationWidget; double m_LinesWidth; QColor m_LinesColor; QColor m_NodesColor; QColor m_ActiveNodesColor; bool m_ReeditMode; private: Q_DISABLE_COPY(QGoContourManualSegmentation); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshEditingWidgetManager.h0000644000175000017500000001315711667757442025430 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoMeshEditingWidgetManager_h #define __QGoMeshEditingWidgetManager_h #include "QGoTraceEditingWidgetManager.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "QGoMeshLevelSetAlgo.h" #include "QGoMeshShapeAlgo.h" #include "QGoMeshWaterShedAlgo.h" #include "QGoSetOfContoursWaterShedAlgo.h" #include "QGoSetOfContoursLevelSetAlgo.h" #include "QGoSetOfContoursShapeAlgo.h" #include "QGoMeshSplitDanielssonDistanceAlgo.h" #include "QGoMeshMergeConvexHullAlgo.h" #include #include #include class GoImageProcessor; //class QGoMeshWaterShedAlgo; /** \class QGoMeshEditingWidgetManager handles the interactions between the user and the algorithms for the meshes \brief */ class QGOGUILIB_EXPORT QGoMeshEditingWidgetManager: public QGoTraceEditingWidgetManager { Q_OBJECT public: QGoMeshEditingWidgetManager(std::vector iVectChannels, int iTimeMin, int iTimeMax, std::vector< vtkPoints* >* iSeeds, GoImageProcessor* iImages, int* iCurrentTimePoint, QWidget* iParent=0); ~QGoMeshEditingWidgetManager(); /** \brief display only the current timepoint in the TSlice comboboxes of the qgoalgomanagerwidgets, disable them and enable the channel comboboxes */ void SetTSliceForClassicView(); /** \brief display the 3 timepoints chosen by the user in the TSlice comboboxes of the qgoalgomanagerwidgets, enable them, display only the channel tracked by the user and disable the channel comboboxes */ void SetTSliceForDopplerView(QHash iListTimePoints, int iChannelNumber); public slots: void RequestPolydatasForDanielsson(); void RequestPolydatasForConvexHull(); void RequestedPolydatas(std::list< vtkPolyData* >); signals: void SetOfContoursFromAlgo(std::vector > iVectVectPolydata, int iTCoord); void RequestPolydatas(); protected: QGoAlgorithmsManagerWidget* m_SetOfContoursWidget; // segmentation algos QGoMeshLevelSetAlgo* m_LevelSetAlgo; QGoMeshShapeAlgo* m_ShapeAlgo; QGoMeshWaterShedAlgo* m_WaterShedAlgo; // split/merge algos QGoMeshSplitDanielssonDistanceAlgo* m_DanielAlgo; QGoMeshMergeConvexHullAlgo* m_ConvexHullAlgo; QGoSetOfContoursWaterShedAlgo* m_SetOfContoursWaterShedAlgo; QGoSetOfContoursLevelSetAlgo* m_SetOfContoursLevelSetAlgo; QGoSetOfContoursShapeAlgo* m_SetOfContoursShapeAlgo; QGoSplitSegmentationAlgo* m_TempReference; /** \brief add the algowidget of the different algo in the algomanagerwidget for the semi automatic mode and set the different SIGNAL/SLOTS connections */ virtual void SetSemiAutomaticAlgorithms(QWidget* iParent = 0); void SetSetOfContoursAlgorithms( std::vector iVectChannels, QStringList iListTime, QWidget* iParent = 0); void SetSplitMergeMode( std::vector iVectChannels, QStringList iListTime, QWidget* iParent = 0); /** \brief get the sets of vtkpolydata for the new created sets of contours by the chosen algo */ template void GetSetOfPolydatasFromAlgo(T* iAlgo) { emit UpdateSeeds(); std::vector< std::vector > NewSetsOfContours = iAlgo->ApplyAlgoSeveralSeeds(this->m_Images, this->m_TraceEditingWidget->GetCurrentImageName() ); emit SetOfContoursFromAlgo(NewSetsOfContours , this->GetSelectedTimePoint() ); emit ClearAllSeeds(); } signals: protected slots: void ApplyLevelSetAlgo(); void ApplyShapeAlgo(); void ApplyWaterShedAlgo(); void ApplySetOfContoursWaterShedAlgo(); void ApplySetOfContoursLevelSetAlgo(); void ApplySetOfContoursShapeAlgo(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoWaterShedAlgo.h0000644000175000017500000000564011667757442023260 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoWaterShedAlgo_h #define __QGoWaterShedAlgo_h #include "QGoSemiAutoSegmentationAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "GoImageProcessor.h" /** \class QGoWaterShedAlgo \brief class to be the interface between the watershed algo for meshes and GoFigure */ class QGoWaterShedAlgo: public QGoSemiAutoSegmentationAlgo { public: QGoWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, int iMaxThreshold = 0, QWidget* iParent = 0); ~QGoWaterShedAlgo(); virtual std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false) = 0; protected: QGoAlgoParameter* m_ThresMin; QGoAlgoParameter* m_ThresMax; QGoAlgoParameter* m_CorrThres; QGoAlgoParameter* m_Alpha; QGoAlgoParameter* m_Beta; int m_MaxThreshold; virtual void SetAlgoWidget(QWidget* iParent); void DeleteParameters(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshWaterShedAlgo.h0000644000175000017500000001133411667757442024072 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoMeshWaterShedAlgo_h #define __QGoMeshWaterShedAlgo_h #include "QGoWaterShedAlgo.h" #include "QGoFilterWatershed.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "vtkTransform.h" #include "vtkTransformPolyDataFilter.h" #include "GoImageProcessor.h" /** \class QGoMeshWaterShedAlgo \brief class to be the interface between the watershed algo for meshes and GoFigure */ class QGoMeshWaterShedAlgo: public QGoWaterShedAlgo { public: QGoMeshWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, int iMaxThreshold, QWidget* iParent = 0); ~QGoMeshWaterShedAlgo(); std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false); protected: template < class TPixel > // note this will work only in 3D, so we can remove the template // parameter on the image dimension //unsigned int VImageDimension > vtkPolyData * ApplyWaterShedFilter( const std::vector& iCenter, typename itk::Image< TPixel, 3 >::Pointer iImages) { assert( iCenter.size() == 3); const unsigned int ImageDimension = 3; typedef TPixel PixelType; typedef itk::Image< PixelType, ImageDimension > ImageType; typedef typename ImageType::Pointer ImagePointer; // let's compute the bounds of the region of interest double radius = this->m_Radius->GetValue(); std::vector< double > bounds( 2 * ImageDimension, 0. ); unsigned int k = 0; for( unsigned int dim = 0; dim < ImageDimension; dim++ ) { bounds[k++] = iCenter[dim] - 2. * radius; bounds[k++] = iCenter[dim] + 2. * radius; } // then let's extract the Region of Interest ImagePointer ITK_ROI_Image = this->ITKExtractROI< PixelType, ImageDimension >( bounds, iImages ); // Compute the segmentation in 3D QGoFilterWatershed Filter; Filter.Apply3DFilter< PixelType >( ITK_ROI_Image, this->m_ThresMin->GetValue(), this->m_ThresMax->GetValue(), this->m_CorrThres->GetValue(), this->m_Alpha->GetValue(), this->m_Beta->GetValue()); typename QGoFilterWatershed::Output3DPointer ItkOutPut = Filter.GetOutput3D(); // Here it would be better if the mesh extraction would be performed directly // in ITK instead. vtkImageData * FilterOutPutToVTK = this->ConvertITK2VTK< typename QGoFilterWatershed::OutputPixelType, ImageDimension>( ItkOutPut ); // Nicolas- should be able to tune the parameter -0.5- vtkPolyData* temp_output = this->ExtractPolyData(FilterOutPutToVTK, 0.5); FilterOutPutToVTK->Delete(); // MIGHT LEAK! CHECK IT IS DELETED! vtkPolyData* mesh = vtkPolyData::New(); mesh->DeepCopy( temp_output ); return mesh; } }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoContourEditingWidgetManager.h0000644000175000017500000001137611667757442026166 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoContourEditingWidgetManager_h #define __QGoContourEditingWidgetManager_h #include "QGoTraceEditingWidgetManager.h" #include "QGoContourManualSegmentation.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include #include #include "QGoContourLevelSetAlgo.h" class GoImageProcessor; /** \class QGoContourEditingWidgetManager handles the interactions between the user and the algorithms for the contours \brief */ class QGOGUILIB_EXPORT QGoContourEditingWidgetManager: public QGoTraceEditingWidgetManager { Q_OBJECT public: QGoContourEditingWidgetManager(std::vector iVectChannels, int iTimeMin, int iTimeMax, std::vector< vtkPoints* >* iSeeds, GoImageProcessor* iImages, int* iCurrentTimePoint, QWidget* iParent=0); ~QGoContourEditingWidgetManager(); //related to manual mode: /** * \brief Set the reedit mode * \param[in] iReeditMode true: we are in reedit mode, false:classic segmentation */ void SetReeditMode(bool iReeditMode); /** * \brief Get the reedit mode * \return true: we are in reedit mode, false:classic segmentation */ bool GetReeditMode(); void InitializeSettingsForManualMode(); /** \brief display only the current timepoint in the TSlice comboboxes of the qgoalgomanagerwidgets, disable them and enable the channel comboboxes */ //void SetTSliceForClassicView(); /** \brief display the 3 timepoints chosen by the user in the TSlice comboboxes of the qgoalgomanagerwidgets, enable them, display only the channel tracked by the user and disable the channel comboboxes */ //void SetTSliceForDopplerView(QStringList iListTimePoints, int iChannelNumber); public slots: void StartManualSegmentation(bool iValue); virtual void SetVisible(bool isVisible); signals: //from the manual mode: void ContourValidated(int iTCoord); void reinitializeContour(); void changeContourRepresentationProperty(float iLinewidth, QColor iLinecolor, QColor iNodecolor, QColor iActivenodecolor); void ManualSegmentationActivated(bool); protected: QGoContourManualSegmentation* m_ManualMode; QGoContourLevelSetAlgo* m_LevelSetAlgo; /*QGoMeshShapeAlgo* m_ShapeAlgo; QGoMeshWaterShedAlgo* m_WaterShedAlgo; QGoMeshSplitDanielssonDistanceAlgo* m_DanielAlgo;*/ /** \brief add the algowidget of the different algo in the algomanagerwidget for the semi automatic mode and set the different SIGNAL/SLOTS connections */ virtual void SetSemiAutomaticAlgorithms(QWidget* iParent = 0); void SetManualMode( QStringList iListTimePoint, QWidget* iParent); protected slots: /** \brief slot called when the user clicks on "validate" for the manual mode */ void ContourToValidate(); void ApplyLevelSetAlgo(); /*void ApplyShapeAlgo(); void ApplyWaterShedAlgo();*/ }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoContourWaterShedAlgo.h0000644000175000017500000000475311667757442024636 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoContourWaterShedAlgo_h #define __QGoContourWaterShedAlgo_h #include "QGoWaterShedAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" /** \class QGoContourWaterShedAlgo \brief class to be the interface between the watershed algo for contours and GoFigure */ class QGoContourWaterShedAlgo: public QGoWaterShedAlgo { public: QGoContourWaterShedAlgo(QWidget* iParent = 0); ~QGoContourWaterShedAlgo(); std::vector ApplyAlgo( vtkPoints* iSeeds, std::vector >* iImages, int iChannel); protected: int m_Orientation; }; #endifGoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoShapeAlgo.cxx0000644000175000017500000000616511667757442023010 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoShapeAlgo.h" QGoShapeAlgo::QGoShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) :QGoSemiAutoSegmentationAlgo(iSeeds, iParent), m_Shape(NULL) { this->SetAlgoWidget(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoShapeAlgo::~QGoShapeAlgo() { this->DeleteParameters(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoShapeAlgo::DeleteParameters() { if(m_Shape) { delete m_Shape; m_Shape = NULL; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoShapeAlgo::SetAlgoWidget(QWidget* iParent) { this->m_AlgoWidget = new QGoAlgorithmWidget("Shape 3D", iParent); QStringList ShapeList; ShapeList.append("Sphere"); ShapeList.append("Cube"); this->m_Shape = new QGoAlgoParameter("Shape",true, ShapeList, "Sphere"); this->m_AlgoWidget->AddParameter(m_Shape); QGoSemiAutoSegmentationAlgo::SetAlgoWidget(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSplitDanielssonDistanceAlgo.h0000644000175000017500000000537711667757442026167 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSplitDanielssonDistanceAlgo_h #define __QGoSplitDanielssonDistanceAlgo_h #include "QGoSplitSegmentationAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" class GoImageProcessor; /** \class QGoSplitDanielssonDistanceAlgo \brief class to be the interface between the shape algo for meshes, contours and set of contours and GoFigure */ class QGoSplitDanielssonDistanceAlgo: public QGoSplitSegmentationAlgo { public: QGoSplitDanielssonDistanceAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); ~QGoSplitDanielssonDistanceAlgo(); virtual std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, std::vector iPolyData, bool iIsInvertedOn = false ) = 0; protected: virtual void SetAlgoWidget(QWidget* iParent = 0); void DeleteParameters(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSemiAutoSegmentationAlgo.h0000644000175000017500000000665011667757442025500 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSemiAutoSegmentationAlgo_h #define __QGoSemiAutoSegmentationAlgo_h #include "QGoSegmentationAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "QGoGUILibConfigure.h" class GoImageProcessor; /** \class QGoSemiAutoSegmentationAlgo \brief abstract class to be the interface between the semi automatic algorithms for meshes and contours and GoFigure */ class QGOGUILIB_EXPORT QGoSemiAutoSegmentationAlgo:public QGoSegmentationAlgo { Q_OBJECT public: explicit QGoSemiAutoSegmentationAlgo(std::vector< vtkPoints* >* iSeeds, QWidget *iParent = 0); virtual ~QGoSemiAutoSegmentationAlgo(); /** \brief return the vtkpolydata created by the algorithm */ virtual std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false) = 0; protected: std::vector< vtkPoints* >* m_Seeds; QGoAlgoParameter* m_Radius; /** \brief construct the algowidget with the different parameters */ virtual void SetAlgoWidget(QWidget* iParent = 0); /** \brief delete the different parameters */ virtual void DeleteParameters() = 0; /* * \brief Get boundingBox from a center and a radius * \param[in] iCenter center of the box * \param[in] iRadius radius of the box * \param[in] iOrientation 0-xy, 1-xz, 2-yz, 3-xyz * \return vector[6] containing the bounding box (xmin, xmax, ymin, imax, ...) */ std::vector GetBounds( const std::vector& iCenter, const double& iRadius, const unsigned int& iOrientation = 3); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSplitDanielssonDistanceAlgo.cxx0000644000175000017500000000570511667757442026535 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSplitDanielssonDistanceAlgo.h" QGoSplitDanielssonDistanceAlgo::QGoSplitDanielssonDistanceAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) :QGoSplitSegmentationAlgo(iSeeds, iParent) { this->SetAlgoWidget(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoSplitDanielssonDistanceAlgo::~QGoSplitDanielssonDistanceAlgo() { this->DeleteParameters(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoSplitDanielssonDistanceAlgo::DeleteParameters() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoSplitDanielssonDistanceAlgo::SetAlgoWidget(QWidget* iParent) { this->m_AlgoWidget = new QGoAlgorithmWidget("Danielsson", iParent); QGoSplitSegmentationAlgo::SetAlgoWidget(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoContourEditingWidgetManager.cxx0000644000175000017500000002006111667757442026530 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoContourEditingWidgetManager.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoAlgorithmsManagerWidget.h" #include "GoImageProcessor.h" #include "vtkSmartPointer.h" #include "vtkImageExport.h" #include "vtkImageData.h" #include QGoContourEditingWidgetManager::QGoContourEditingWidgetManager( std::vector iVectChannels, int iTimeMin, int iTimeMax, std::vector< vtkPoints* >* iSeeds, GoImageProcessor* iImages, int* iCurrentTimePoint, QWidget* iParent): QGoTraceEditingWidgetManager("Contour", iVectChannels, iTimeMin, iTimeMax, iSeeds, iImages, iCurrentTimePoint, iParent) { this->SetSemiAutomaticAlgorithms(iParent); this->SetManualMode(this->m_ListTimePoint, iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoContourEditingWidgetManager::~QGoContourEditingWidgetManager() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoContourEditingWidgetManager::SetManualMode( QStringList iListTimePoint, QWidget* iParent) { m_ManualMode = new QGoContourManualSegmentation(iParent); this->m_TraceEditingWidget->AddWidgetForManualMode(m_ManualMode->getWidget(), iListTimePoint, false); this->SetTSliceForClassicView(); QObject::connect( this->m_ManualMode, SIGNAL (changeContourRepresentationProperty(float, QColor, QColor, QColor) ), this, SIGNAL(changeContourRepresentationProperty(float, QColor, QColor, QColor) ) ); QObject::connect( this->m_ManualMode, SIGNAL (validateContour() ), this, SLOT(ContourToValidate() ) ); QObject::connect( this->m_ManualMode, SIGNAL (reinitializeContour() ), this, SIGNAL(reinitializeContour() ) ); QObject::connect( this->m_TraceEditingWidget, SIGNAL(SetSeedInteractorBehaviour(bool) ), this, SLOT(StartManualSegmentation(bool) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoContourEditingWidgetManager::StartManualSegmentation( bool iValue ) { // if current is if(this->m_TraceEditingWidget->GetCurrentModeName().compare("Manual") == 0) { emit ManualSegmentationActivated( true ); } else { emit ManualSegmentationActivated( false ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoContourEditingWidgetManager::ContourToValidate() { int CurrentTimePoint = this->GetSelectedTimePoint(); //for test purpose emit ContourValidated( CurrentTimePoint ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoContourEditingWidgetManager::SetSemiAutomaticAlgorithms(QWidget* iParent) { //level set: m_LevelSetAlgo = new QGoContourLevelSetAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* LevelSetWidget = m_LevelSetAlgo->GetAlgoWidget(); this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(LevelSetWidget); QObject::connect(LevelSetWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplyLevelSetAlgo() ) ); /*//shape: this->m_ShapeAlgo = new QGoMeshShapeAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* ShapeWidget = this->m_ShapeAlgo->GetAlgoWidget(); this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(ShapeWidget); QObject::connect(ShapeWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplyShapeAlgo() ) ); //watershed: this->m_WaterShedAlgo = new QGoMeshWaterShedAlgo(this->m_Seeds, this->m_MaxThreshold, iParent); QGoAlgorithmWidget* WaterShedWidget = m_WaterShedAlgo->GetAlgoWidget(); this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(WaterShedWidget); QObject::connect(WaterShedWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplyWaterShedAlgo() ) );*/ } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoContourEditingWidgetManager::ApplyLevelSetAlgo() { this->GetPolydatasFromAlgo(this->m_LevelSetAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*void QGoContourEditingWidgetManager::ApplyShapeAlgo() { this->GetPolydatasFromAlgo(this->m_ShapeAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoContourEditingWidgetManager::ApplyWaterShedAlgo() { this->GetPolydatasFromAlgo(this->m_WaterShedAlgo); }*/ //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoContourEditingWidgetManager::SetReeditMode(bool iReeditMode) { this->m_ManualMode->SetReeditMode(iReeditMode); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoContourEditingWidgetManager::GetReeditMode() { return this->m_ManualMode->GetReeditMode(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoContourEditingWidgetManager::InitializeSettingsForManualMode() { this->m_ManualMode->GenerateContourRepresentationProperties(true); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoContourEditingWidgetManager::SetVisible(bool isVisible) { QGoTraceEditingWidgetManager::SetVisible(isVisible); if (this->m_TraceEditingWidget->GetCurrentModeName() == "Manual") { emit ManualSegmentationActivated(isVisible); } } GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoTraceEditingWidget.h0000644000175000017500000001013011667757442024263 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTraceEditingWidget_h #define __QGoTraceEditingWidget_h #include #include #include #include #include #include #include "QGoModesManagerWidget.h" #include "QGoAlgorithmsManagerWidget.h" class QGoTraceEditingWidget: public QWidget { Q_OBJECT public: explicit QGoTraceEditingWidget(std::string iTraceName , std::vector iVectChannels, QStringList iListTimePoints, QWidget *iParent = 0 ); ~QGoTraceEditingWidget(); /** \brief add iModeWidget as a widget to be displayed when iModeName is selected in the combobox of m_ModeEditingWidget \param[in] iModeName name of the mode corresponding to iModeWidget \param[in] iModeWidget Widget corresponding to iModeName */ void AddMode( std::string iModeName, QWidget* iModeWidget, bool ModeNeedSeeds); void AddMode(QGoAlgorithmsManagerWidget* iAlgoModeWidget, bool ModeNeedSeeds); /** \brief replace the existing m_ModeEditingWidget with iModeWidget: all the previous mode will be erased \param[in] iModeWidget modes manager */ void SetANewModesManager(QGoModesManagerWidget* iModeWidget); void AddAlgoWidgetForSemiAutomaticMode(QGoAlgorithmWidget* iAlgoWidget); void AddAlgoWidgetForAutomaticMode(QGoAlgorithmWidget* iAlgoWidget); void AddWidgetForManualMode(QWidget* iWidget, QStringList iListTimePoint, bool ModeNeedSeeds); std::string GetCurrentImageName(); int GetSelectedTimePoint(); bool GetIsInvertedOn(); /** \brief check which mode is selected and if the seeds are needed or not and emit the corresponding signals based on the visibility of the widget */ void CheckTheCurrentMode(bool IsVisible); void SetTSliceForClassicView(int iTimePoint); void SetTSliceForDopplerView( QHash iListTimePoints, int iChannelNumber); /** \brief return the name of the current mode in the combobox */ std::string GetCurrentModeName(); signals: void SetSeedInteractorBehaviour(bool enable); void ResetClicked(); protected: void Initialize(std::vector iVectChannels, QStringList iListTimePoints, QWidget *iParent = 0); QGoModesManagerWidget* m_ModeEditingWidget; QVBoxLayout* m_VLayout; QStringList m_ListTimePoints; void SetModesManager(QGoModesManagerWidget* iModeWidget); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoAlgorithmsManagerWidget.cxx0000644000175000017500000002567511667757442025724 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoAlgorithmsManagerWidget.h" #include #include #include #include #include #include QGoAlgorithmsManagerWidget:: QGoAlgorithmsManagerWidget( std::string iModeName, QWidget *iParent, std::vector iVectChannels, QStringList iListTime, bool iOnlyOneMethod, bool NeedApplyResetButton ) : QWidget(iParent), m_MethodComboBox(NULL), m_ChannelComboBox(NULL), m_TimeComboBox(NULL) { this->m_ModeName = iModeName; this->Initialize(iVectChannels, iListTime, iOnlyOneMethod, NeedApplyResetButton); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoAlgorithmsManagerWidget::~QGoAlgorithmsManagerWidget() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoAlgorithmsManagerWidget::Initialize(std::vector iVectChannels, QStringList iListTime, bool iOnlyOneMethod, bool NeedApplyResetButton) { this->m_VBoxLayout = new QVBoxLayout; QHBoxLayout* HBox = new QHBoxLayout; QFormLayout* FormLayout = new QFormLayout; if (!iListTime.empty() ) { this->m_ListTimePoints = iListTime; this->m_TimeComboBox = new QComboBox(this); this->m_TimeComboBox->addItems(iListTime); QLabel* Label= new QLabel("TSlice",this); HBox->addWidget(Label); HBox->addWidget(this->m_TimeComboBox); } this->m_InvertBox = new QCheckBox("Invert", this); HBox->addWidget(this->m_InvertBox); this->m_VBoxLayout->addLayout(HBox); if (!iVectChannels.empty() ) { this->m_ChannelComboBox = new QComboBox(this); std::vector::iterator iter = iVectChannels.begin(); while (iter != iVectChannels.end()) { this->m_ChannelComboBox->addItem(*iter); ++iter; } FormLayout->addRow(tr("Channel:"), this->m_ChannelComboBox); } this->m_MethodWidgets = new QStackedWidget(this); if (!iOnlyOneMethod) { this->m_MethodComboBox = new QComboBox(this); FormLayout->addRow(tr("Method:"), this->m_MethodComboBox); QObject::connect(this->m_MethodComboBox, SIGNAL(activated(int)), this->m_MethodWidgets, SLOT(setCurrentIndex(int))); } this->m_VBoxLayout->addLayout(FormLayout); this->m_VBoxLayout->addWidget(this->m_MethodWidgets); if (NeedApplyResetButton) { QHBoxLayout* ButtonLayout = new QHBoxLayout; QPushButton* ApplyButton = new QPushButton(tr("Apply"),this); ApplyButton->setShortcut(tr("A", "Apply Algorithm")); ApplyButton->setShortcut(tr("Ctrl+A", "Apply Algorithm")); ApplyButton->setToolTip("Apply Algorithm"); QPushButton* ResetButton = new QPushButton(tr("Delete"), this); ResetButton->setShortcut(tr("D", "Delete the seeds")); ResetButton->setShortcut(tr("Ctrl+D", "Delete the seeds")); ResetButton->setToolTip("Delete the seeds"); ButtonLayout->addWidget(ApplyButton); ButtonLayout->addWidget(ResetButton); this->m_VBoxLayout->addLayout(ButtonLayout); QObject::connect(ApplyButton, SIGNAL(clicked()), this, SLOT(EmitApplyAlgo())); QObject::connect(ResetButton, SIGNAL(clicked()), this, SIGNAL(ResetClicked())); } this->setLayout(this->m_VBoxLayout); this->m_VBoxLayout->setSizeConstraint(QLayout::SetFixedSize); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoAlgorithmsManagerWidget::AddMethod(QGoAlgorithmWidget* iAlgoWidget) { this->m_MethodWidgets->addWidget(iAlgoWidget); int Index = this->m_MethodWidgets->indexOf(iAlgoWidget); this->m_MethodComboBox->insertItem(Index, iAlgoWidget->GetMethodName().c_str()); iAlgoWidget->show(); this->m_MethodComboBox->setCurrentIndex(Index); this->m_MethodWidgets->setCurrentWidget(iAlgoWidget); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoAlgorithmsManagerWidget::SetCurrentIndex(int iIndex) { if (this->m_MethodComboBox != NULL) { this->m_MethodComboBox->setCurrentIndex(iIndex); } this->m_MethodWidgets->setCurrentIndex(iIndex); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoAlgorithmsManagerWidget::GetModeName() { return this->m_ModeName; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoAlgorithmsManagerWidget::SetCurrentChannel(QString iChannel) { this->m_ChannelComboBox->setCurrentIndex( this->m_ChannelComboBox->findText(iChannel) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoAlgorithmsManagerWidget::SetTSliceForClassicView(QString iTimePoint) { if (this->m_TimeComboBox) { this->m_TimeComboBox->clear(); this->m_TimeComboBox->addItems(this->m_ListTimePoints); this->m_TimeComboBox->setCurrentIndex( this->m_TimeComboBox->findText(iTimePoint) ); this->m_TimeComboBox->setEnabled(false); } if (this->m_ChannelComboBox) { this->m_ChannelComboBox->setEnabled(true); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoAlgorithmsManagerWidget::SetTSliceForDopplerView( QHash iListTimePoints, int iIndexChannel) { if (this->m_TimeComboBox) { this->m_TimeComboBox->clear(); if (!iListTimePoints.empty() ) { QHash::iterator iter = iListTimePoints.begin(); while(iter != iListTimePoints.end() ) { QPixmap pix(12, 12); QPainter painter(&pix); painter.setPen(Qt::gray); QColor color = iter.value(); painter.setBrush( QBrush(color) ); painter.drawRect(0, 0, 12, 12); QIcon Icon; Icon.addPixmap(pix); this->m_TimeComboBox->addItem(Icon, iter.key()); ++iter; } } if (iListTimePoints.size() > 0) { this->m_TimeComboBox->setCurrentIndex(1); } this->m_TimeComboBox->setEnabled(true); } if (this->m_ChannelComboBox) { this->m_ChannelComboBox->setCurrentIndex(iIndexChannel); this->m_ChannelComboBox->setEnabled(false); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoAlgorithmsManagerWidget::HasMethod() { return this->m_MethodComboBox->count(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoAlgorithmsManagerWidget::EmitApplyAlgo() { QGoAlgorithmWidget* iCurrentWidget = dynamic_cast(m_MethodWidgets->currentWidget()); iCurrentWidget->EmitApplyAlgo(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoAlgorithmsManagerWidget::GetCurrentImageName() { std::string imageName; if(this->m_ChannelComboBox->isEnabled()) { imageName = this->m_ChannelComboBox->currentText().toStdString(); } else { imageName = this->m_TimeComboBox->currentText().toStdString(); } return imageName; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoAlgorithmsManagerWidget::GetSelectedTimePoint() { return this->m_TimeComboBox->currentText().toInt(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoAlgorithmsManagerWidget::AddWidgetForOnlyOneMethod( QWidget* iWidget) { this->m_MethodWidgets->addWidget(iWidget); //int Index = this->m_MethodWidgets->indexOf(iWidget); this->m_MethodWidgets->setCurrentWidget(iWidget); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoAlgorithmsManagerWidget::IsInvertChecked() { if (this->m_InvertBox->checkState() == Qt::Checked) { return true; } else { return false; } } /*void QGoAlgorithmsManagerWidget::AddMethod(std::string iNameMethod, QWidget* iParametersWidget, QWidget* iAdvParamWidget) { QWidget* MethodWidget = new QWidget(this); QVBoxLayout* MethodLayout = new QVBoxLayout; MethodLayout->addWidget(iParametersWidget); QGoAdvancedParametersWidget* AdvParamWidget = new QGoAdvancedParametersWidget(this); AdvParamWidget->AddAdvancedParamWidget(iAdvParamWidget); MethodLayout->addWidget(AdvParamWidget); MethodWidget->setLayout(MethodLayout); this->m_MethodWidgets->addWidget(MethodWidget); int Index = this->m_MethodWidgets->indexOf(MethodWidget); this->m_MethodComboBox->insertItem(Index,iNameMethod.c_str()); }*/ GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoContourLevelSetAlgo.h0000644000175000017500000001700011667757442024460 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoContourLevelSetAlgo_h #define __QGoContourLevelSetAlgo_h #include "QGoLevelSetAlgo.h" #include "QGoFilterChanAndVese.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "vtkTransform.h" #include "vtkTransformPolyDataFilter.h" class GoImageProcessor; /** \class QGoContourLevelSetAlgo \brief class to be the interface between the levelset algo for contours and GoFigure */ class QGoContourLevelSetAlgo: public QGoLevelSetAlgo { public: QGoContourLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget *iParent = 0); ~QGoContourLevelSetAlgo(); std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false); protected: template < class TPixel> vtkPolyData * ApplyLevelSetFilter( const std::vector& iCenter, typename itk::Image< TPixel, 3 >::Pointer iImages, const unsigned int& iOrientation) { assert( iCenter.size() == 3); const unsigned int ImageDimension = 3; typedef TPixel PixelType; typedef itk::Image< PixelType, ImageDimension > ImageType; typedef typename ImageType::Pointer ImagePointer; typedef itk::Image< PixelType, 2 > ImageType2D; typedef typename ImageType2D::Pointer ImageType2DPointer; // let's compute the bounds of the region of interest double radius = this->m_Radius->GetValue(); std::vector< double > bounds( 2 * ImageDimension, 0. ); unsigned int k = 0; for( unsigned int dim = 0; dim < ImageDimension; dim++ ) { bounds[k++] = iCenter[dim] - 2. * radius; bounds[k++] = iCenter[dim] + 2. * radius; } bounds[2*iOrientation] = iCenter[iOrientation]; bounds[2*iOrientation +1] = iCenter[iOrientation]; for(int i=0;i<6;++i) { std::cout << "bounds: " << bounds[i] << std::endl; } // then let's extract the Slice of Interest ImageType2DPointer ITK_Slice_Image = this->ITKExtractSlice( bounds, iImages ); // Compute the segmentation in 3D // why no call to the filter itself...? QGoFilterChanAndVese Filter; Filter.Apply2DFilter< PixelType >( ITK_Slice_Image, iCenter, 0, // we dont want to extract ROI from input since we already did this->m_Iterations->GetValue(), this->m_Curvature->GetValue()); typename QGoFilterChanAndVese::Output2DPointer ItkOutPut = Filter.GetOutput2D(); // Here it would be better if the mesh extraction would be performed directly // in ITK instead. vtkImageData * FilterOutPutToVTK = this->ConvertITK2VTK< typename QGoFilterChanAndVese::OutputPixelType, 2 // image dimension >( ItkOutPut ); vtkPolyData* temp_output = this->ExtractPolyData(FilterOutPutToVTK, 0.5); // translation transform ----------------------- //------------------------------------------------------------------------ double temp_bounds[6]; FilterOutPutToVTK->GetBounds( temp_bounds ); double temp_center[3]; temp_center[0] = ( temp_bounds[0] + temp_bounds[1] ) * 0.5; temp_center[1] = ( temp_bounds[2] + temp_bounds[3] ) * 0.5; temp_center[2] = ( temp_bounds[4] + temp_bounds[5] ) * 0.5; vtkSmartPointer< vtkTransform > translation2 = vtkSmartPointer< vtkTransform >::New(); translation2->Translate(-temp_center[0], -temp_center[1], -temp_center[2]); vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform2 = vtkSmartPointer< vtkTransformPolyDataFilter >::New(); mesh_transform2->SetTransform(translation2); mesh_transform2->SetInput( temp_output ); mesh_transform2->Update(); // rotation transform ----------------------- //------------------------------------------------------------------------ vtkSmartPointer< vtkTransform > translation = vtkSmartPointer< vtkTransform >::New(); // rotate polydata if necessary if(iOrientation == 0) { translation->RotateY(-90); // check if + or - 90 } else if(iOrientation == 1) { translation->RotateX(-90); // check if + or - 90 } else if(iOrientation == 2) { // no rotation, we are in the good plan } vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform = vtkSmartPointer< vtkTransformPolyDataFilter >::New(); mesh_transform->SetTransform(translation); mesh_transform->SetInput( mesh_transform2->GetOutput() ); mesh_transform->Update(); // translate back ----------------------- //------------------------------------------------------------------------ double temp_center2[3]; temp_center2[0] = ( bounds[0] + bounds[1] ) * 0.5; temp_center2[1] = ( bounds[2] + bounds[3] ) * 0.5; temp_center2[2] = ( bounds[4] + bounds[5] ) * 0.5; vtkSmartPointer< vtkTransform > translation23 = vtkSmartPointer< vtkTransform >::New(); translation23->Translate(temp_center2[0], temp_center2[1], temp_center2[2]); vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform23 = vtkSmartPointer< vtkTransformPolyDataFilter >::New(); mesh_transform23->SetTransform(translation23); mesh_transform23->SetInput( mesh_transform->GetOutput() ); mesh_transform23->Update(); //----------------------------------------------------------------------- // MIGHT LEAK! CHECK IT IS DELETED! vtkPolyData* mesh = vtkPolyData::New(); mesh->DeepCopy( mesh_transform23->GetOutput() ); temp_output->Delete(); return mesh; } }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoContourManualSegmentationWidget.h0000644000175000017500000000614111667757442027075 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoContourManualSegmentationWidget_h #define __QGoContourManualSegmentationWidget_h #include #include "ui_ContourManualSegmentationWidget.h" class vtkProperty; class QGoManualSegmentationSettingsDialog; #include "QGoManualSegmentationSettingsDialog.h" #include "QGoIOConfigure.h" /** * \class QGoContourManualSegmentationWidget * \ingroup QGoContourManual * \brief Define the manual segmentation widget connections */ class QGOGUILIB_EXPORT QGoContourManualSegmentationWidget: public QWidget, private Ui::ContourManualSegmentationWidget { Q_OBJECT public: explicit QGoContourManualSegmentationWidget(QWidget *parent = 0); ~QGoContourManualSegmentationWidget(); /* * \brief Pop up dialog to choose the contour properties */ QGoManualSegmentationSettingsDialog *m_SettingsDialog; signals: /* * \brief Signal sent if "Reinitialize" button clicked */ void ReinitializePressed(); /* * \brief Signal sent if "Validate" button clicked */ void ValidatePressed(); /* * \brief Signal sent if we "Setting" button clicked */ void SettingsPressed(); /* * \brief Signal sent if leave the m_SettingsDialog by clicking "OK" */ void UpdateContourRepresentationProperties(); void ManualSegmentationActivated(bool); private: Q_DISABLE_COPY(QGoContourManualSegmentationWidget); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSplitSegmentationAlgo.cxx0000644000175000017500000000647111667757442025421 0ustar mathieumathieu /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSplitSegmentationAlgo.h" //------------------------------------------------------------------------- QGoSplitSegmentationAlgo:: QGoSplitSegmentationAlgo( std::vector< vtkPoints* >* iSeeds, QWidget *iParent) : QGoSegmentationAlgo( iParent ), m_Seeds( iSeeds ) {} //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoSplitSegmentationAlgo::~QGoSplitSegmentationAlgo() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoSplitSegmentationAlgo::SetAlgoWidget(QWidget* iParent) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoSplitSegmentationAlgo:: GetBounds(const std::vector& iCenter, const double& iRadius, const unsigned int& iOrientation) { assert( iCenter.size() == 3 ); assert( iRadius >= 0. ); assert( iOrientation < 4 ); std::vector boundingBox( 6, 0. ); unsigned int k = 0; for(unsigned int i=0; i<3; i++) { if(i == iOrientation) { boundingBox[k++] = iCenter[i]; boundingBox[k++] = iCenter[i]; } else { boundingBox[k++] = iCenter[i] - iRadius; boundingBox[k++] = iCenter[i] + iRadius; } } return boundingBox; } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoLevelSetAlgo.cxx0000644000175000017500000000621411667757442023466 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoLevelSetAlgo.h" QGoLevelSetAlgo::QGoLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) :QGoSemiAutoSegmentationAlgo(iSeeds, iParent) { this->SetAlgoWidget(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoLevelSetAlgo::~QGoLevelSetAlgo() { this->DeleteParameters(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLevelSetAlgo::DeleteParameters() { delete m_Curvature; delete m_Iterations; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLevelSetAlgo::SetAlgoWidget(QWidget* iParent) { this->m_AlgoWidget = new QGoAlgorithmWidget("LevelSet", iParent); m_Curvature = new QGoAlgoParameter("Curvature", true, 0, 1000, 20); this->m_AlgoWidget->AddParameter(m_Curvature); m_Iterations = new QGoAlgoParameter ("Iterations", true, 0, 1000, 100); this->m_AlgoWidget->AddParameter(m_Iterations); QGoSemiAutoSegmentationAlgo::SetAlgoWidget(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMergeConvexHullAlgo.h0000644000175000017500000000531711667757442024442 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoMergeConvexHullAlgo_h #define __QGoMergeConvexHullAlgo_h #include "QGoSplitSegmentationAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" class GoImageProcessor; /** \class QGoMergeConvexHullAlgo \brief class to be the interface between the shape algo for meshes, contours and set of contours and GoFigure */ class QGoMergeConvexHullAlgo: public QGoSplitSegmentationAlgo { public: QGoMergeConvexHullAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); ~QGoMergeConvexHullAlgo(); virtual std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, std::vector iPolyData, bool iIsInvertedOn = false ) = 0; protected: virtual void SetAlgoWidget(QWidget* iParent = 0); void DeleteParameters(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshMergeConvexHullAlgo.cxx0000644000175000017500000001126211667757442025626 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoMeshMergeConvexHullAlgo.h" #include "GoImageProcessor.h" #include "itkImage.h" #include "itkvtkMeshMergeConvexHullFilter.h" QGoMeshMergeConvexHullAlgo::QGoMeshMergeConvexHullAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) :QGoMergeConvexHullAlgo(iSeeds, iParent) { this->setObjectName("Merge"); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoMeshMergeConvexHullAlgo::~QGoMeshMergeConvexHullAlgo() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoMeshMergeConvexHullAlgo::ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, std::vector iPolyData, bool iIsInvertedOn) { const unsigned int Dimension = 3; typedef unsigned char PixelType; typedef itk::Image< PixelType, Dimension > ImageType; typedef std::list< vtkPolyData* > PolyDataListType; PolyDataListType listOfPolydatas; // init bounding box std::vector< double > bounds(Dimension*2); for(unsigned int i = 0; i::max(); bounds[i*2+1] = std::numeric_limits::min(); } // get bounding box over all selected polydatas std::vector::iterator iterator = iPolyData.begin(); while(iterator != iPolyData.end()) { double* boundsPointer = (*iterator)->GetBounds(); for(unsigned int i = 0; i(boundsPointer[i*2]); if(boundsPointer[i*2 + 1] > bounds[i*2 +1]) bounds[i*2+1] = static_cast(boundsPointer[i*2+1]); } listOfPolydatas.push_back(*iterator); ++iterator; } ImageType::Pointer ITK_Full_Image = iImages->getImageITK( iImages->getChannelName(0)); itk::Vector spacing = ITK_Full_Image->GetSpacing(); // work on smaller region // increase size of bounding box by 20*spacing... bug itk? for(unsigned int i = 0; iITKExtractROI< PixelType, Dimension >( bounds, ITK_Full_Image); typedef itk::vtkMeshMergeConvexHullFilter< ImageType, PolyDataListType > MergerType; MergerType::Pointer filter = MergerType::New(); filter->SetInputs( listOfPolydatas ); filter->SetNumberOfImages( 1 ); filter->SetFeatureImage( 0, ITK_ROI_Image ); filter->Update(); std::vector oVector; oVector.push_back(filter->GetOutput()); return oVector; } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoFilterSemiAutoBase.cxx0000644000175000017500000004355311667757442024636 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoFilterSemiAutoBase.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkImageData.h" //#include "QGoSeedBaseWidget.h" //Extract one slice #include "vtkMatrix4x4.h" #include "vtkImageReslice.h" // construct contour #include "vtkContourFilter.h" #include "vtkMarchingSquares.h" #include "vtkCellArray.h" #include "vtkPolylineDecimation.h" #include "vtkStripper.h" #include "vtkFeatureEdges.h" // construct mesh #include "vtkMarchingCubes.h" // keep the largest region #include "vtkPolyDataConnectivityFilter.h" // fill the holes! #include "vtkFillHolesFilter.h" // and smooth it...! #include "vtkWindowedSincPolyDataFilter.h" #include "vtkPolyDataWriter.h" // to cut #include "vtkPlane.h" #include "vtkCutter.h" #include "vtkImageExport.h" //-------------------------------------------------------------------------- QGoFilterSemiAutoBase::QGoFilterSemiAutoBase(QObject *iParent) : QObject(iParent), m_Widget(NULL), m_Radius(3.), m_Number(0), m_Channel(0), m_Points(NULL), m_OriginalImageMC(NULL), m_Sampling(3) { m_Output = vtkImageData::New(); m_vtk2itkImage = vtkImageExport::New(); m_Center[0] = 0; m_Center[1] = 0; m_Center[2] = 0; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoFilterSemiAutoBase:: ~QGoFilterSemiAutoBase() { m_Output->Delete(); m_vtk2itkImage->Delete(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoFilterSemiAutoBase::setName(QString iName) { m_Name = iName; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoFilterSemiAutoBase::getName() { return m_Name; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoFilterSemiAutoBase::setWidget(QWidget *iWidget) { //m_Widget = iWidget; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QWidget * QGoFilterSemiAutoBase::getWidget() { return m_Widget; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // Original data without ROI vtkSmartPointer< vtkImageData > QGoFilterSemiAutoBase::getInput() { return ( *m_OriginalImageMC )[m_Channel]; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // Original data without ROI void QGoFilterSemiAutoBase::setOutput(vtkImageData *iOutputImage) { m_Output->DeepCopy(iOutputImage); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkImageData * QGoFilterSemiAutoBase::getOutput() { return m_Output; } //-------------------------------------------------------------------------- // Center of the ROI to apply the segmentation algorithm //-------------------------------------------------------------------------- void QGoFilterSemiAutoBase::setCenter(double *iCenter) { m_Center[0] = iCenter[0]; m_Center[1] = iCenter[1]; m_Center[2] = iCenter[2]; } //-------------------------------------------------------------------------- // Center of the ROI to apply the segmentation algorithm //-------------------------------------------------------------------------- double * QGoFilterSemiAutoBase::getCenter() { return m_Center; } //-------------------------------------------------------------------------- // Radius to define ROI //-------------------------------------------------------------------------- void QGoFilterSemiAutoBase::setRadius(double iRadius) { m_Radius = iRadius; } //-------------------------------------------------------------------------- // Radius to define ROI //-------------------------------------------------------------------------- double QGoFilterSemiAutoBase::getRadius() { return m_Radius; } //-------------------------------------------------------------------------- // Radius to define ROI //-------------------------------------------------------------------------- void QGoFilterSemiAutoBase::setSampling(int iSampling) { m_Sampling = iSampling; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int QGoFilterSemiAutoBase::getSampling() { return m_Sampling; } //-------------------------------------------------------------------------- // Radius to define ROI //-------------------------------------------------------------------------- void QGoFilterSemiAutoBase::setChannel(int iChannel) { m_Channel = iChannel; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int QGoFilterSemiAutoBase::getChannel() { return m_Channel; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPoints * QGoFilterSemiAutoBase::getPoints() { return m_Points; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoFilterSemiAutoBase::setPoints(vtkPoints *iPoints) { m_Points = iPoints; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoFilterSemiAutoBase::setOriginalImageMC(std::vector< vtkSmartPointer< vtkImageData > > *iOriginalImage) { m_OriginalImageMC = iOriginalImage; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoFilterSemiAutoBase::UpdateVisibility(int iCurrentFilter) { /*QWidget *w = m_Widget->parentWidget()->parentWidget(); if ( m_Number == iCurrentFilter ) { m_Widget->show(); QObject::connect( w, SIGNAL( Apply() ), this, SLOT( Apply() ) ); } else { m_Widget->hide(); QObject::disconnect( w, SIGNAL( Apply() ), this, SLOT( Apply() ) ); }*/ } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoFilterSemiAutoBase::UpdateAdvancedMode(bool checked) { //QWidget * w = m_Widget->parentWidget()->parentWidget(); //QGoSeedBaseWidget *baseWidget = dynamic_cast< QGoSeedBaseWidget * >( w ); //if ( checked && ( m_Number != baseWidget->GetCurrentFilter() ) ) // { // m_Widget->hide(); // } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoFilterSemiAutoBase::ConnectSignals(int iFilterNumber) { /*m_Number = iFilterNumber; QWidget *w = m_Widget->parentWidget()->parentWidget(); // Buttons connections QObject::connect( w, SIGNAL( Apply() ), this, SLOT( Apply() ) ); QObject::connect( w, SIGNAL( Filter(int) ), this, SLOT( UpdateVisibility(int) ) ); QObject::connect( w, SIGNAL( Radius(double) ), this, SLOT( setRadius(double) ) ); QObject::connect( w, SIGNAL( Channel(int) ), this, SLOT( setChannel(int) ) ); QObject::connect( w, SIGNAL( Sampling(int) ), this, SLOT( setSampling(int) ) ); QObject::connect( w, SIGNAL( Clicked(bool) ), this, SLOT( UpdateAdvancedMode(bool) ) ); // End of segmentation signals QObject::connect( this, SIGNAL( MeshCreated(vtkPolyData *, int) ), w, SIGNAL( MeshCreated(vtkPolyData *, int) ) ); QObject::connect( this, SIGNAL( ContourCreated(vtkPolyData *) ), w, SIGNAL( ContourCreated(vtkPolyData *) ) ); QObject::connect( this, SIGNAL( ImageProcessed() ), w, SIGNAL( ImageProcessed() ) ); QObject::connect( this, SIGNAL( CreateCorrespondingMesh(int) ), w, SIGNAL( CreateCorrespondingMesh(int) ) ); QObject::connect( this, SIGNAL( AddContourForMeshToContours(vtkPolyData *) ), w, SIGNAL( AddContourForMeshToContours(vtkPolyData *) ) ); QObject::connect( this, SIGNAL( UpdateSeeds() ), w, SIGNAL( UpdateSeeds() ) ); QObject::connect( this, SIGNAL( SegmentationFinished() ), w, SIGNAL( SegmentationFinished() ) );*/ } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkImageData * QGoFilterSemiAutoBase::extractOneSlice(vtkImageData *iOriginalImage, double *iOrigin, int iDirection) { static double elements[3][16] = { { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1 }, { 0, 0, -1, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1 } }; // Set the slice orientation vtkMatrix4x4 *resliceAxes = vtkMatrix4x4::New(); resliceAxes->DeepCopy(elements[iDirection]); // Set the point through which to slice resliceAxes->SetElement(0, 3, iOrigin[0]); resliceAxes->SetElement(1, 3, iOrigin[1]); resliceAxes->SetElement(2, 3, iOrigin[2]); vtkImageReslice *reslicer = vtkImageReslice::New(); reslicer->SetOutputDimensionality(2); reslicer->SetInformationInput(iOriginalImage); reslicer->SetInterpolationModeToLinear(); reslicer->SetInput(iOriginalImage); reslicer->SetResliceAxes(resliceAxes); reslicer->Update(); vtkImageData *output = vtkImageData::New(); output->DeepCopy( reslicer->GetOutput() ); reslicer->Delete(); resliceAxes->Delete(); return output; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyData * QGoFilterSemiAutoBase::ReconstructContour(vtkImageData *iInputImage, const double & iThreshold) { // create iso-contours vtkMarchingSquares *contours = vtkMarchingSquares::New(); contours->SetInput(iInputImage); contours->GenerateValues (1, iThreshold, iThreshold); contours->Update(); vtkPolyData *outputToOrganize = vtkPolyData::New(); outputToOrganize->DeepCopy( contours->GetOutput() ); vtkPolyData *output = ReorganizeContour(outputToOrganize); contours->Delete(); outputToOrganize->Delete(); return output; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyData * QGoFilterSemiAutoBase::ReorganizeContour(vtkPolyData *iInputImage, bool iDecimate) { // Create reorganize contours vtkStripper *stripper = vtkStripper::New(); stripper->SetInput(iInputImage); //Is it useful?? Which number is the best suited? stripper->SetMaximumLength(999); stripper->Update(); // Reorder points stripper->GetOutput()->GetLines()->InitTraversal(); // npts = nb of points in the line // *pts = pointer to each point vtkIdType *pts = NULL; vtkIdType npts = 0; stripper->GetOutput()->GetLines()->GetNextCell(npts, pts); vtkPoints *points = vtkPoints::New(); vtkCellArray *lines = vtkCellArray::New(); vtkIdType * lineIndices = new vtkIdType[static_cast< int >( npts + 1 )]; for ( int k = 0; k < static_cast< int >( npts ); k++ ) { points->InsertPoint( k, stripper->GetOutput()->GetPoints()->GetPoint(pts[k]) ); lineIndices[k] = k; } lineIndices[static_cast< int >( npts )] = 0; lines->InsertNextCell(npts + 1, lineIndices); delete[] lineIndices; vtkPolyData *testPolyD = vtkPolyData::New(); testPolyD->SetPoints(points); testPolyD->SetLines(lines); if ( iDecimate ) { //Decimation (has to be after points reorganization) vtkPolylineDecimation *decimator = vtkPolylineDecimation::New(); decimator->SetInput(testPolyD); double ratio = 1. - 20. / static_cast< double >( npts ); decimator->SetTargetReduction(ratio); decimator->Update(); vtkPolyData *output = vtkPolyData::New(); output->DeepCopy( decimator->GetOutput() ); lines->Delete(); points->Delete(); stripper->Delete(); decimator->Delete(); testPolyD->Delete(); return output; } else { lines->Delete(); points->Delete(); stripper->Delete(); return testPolyD; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkPolyData * QGoFilterSemiAutoBase::ReconstructMesh(vtkImageData *iInputImage, const double & iThreshold) { // create iso-contours // Problem[Kishore]: Creates holes in some meshes although image has no hole // vtkMarchingCubes *contours = vtkMarchingCubes::New(); // // contours->SetInput(iInputImage); // contours->GenerateValues (1, iThreshold, iThreshold); // contours->SetComputeGradients(0); // contours->SetComputeNormals(1); // contours->SetComputeScalars(0); // contours->SetNumberOfContours(1); // contours->Update(); vtkSmartPointer< vtkContourFilter > contours = vtkSmartPointer< vtkContourFilter >::New(); contours->SetInput(iInputImage); contours->SetComputeGradients(0); contours->SetComputeNormals(0); contours->SetComputeScalars(0); contours->SetNumberOfContours(1); contours->SetValue(0, iThreshold); contours->Update(); vtkSmartPointer< vtkFeatureEdges > feature = vtkSmartPointer< vtkFeatureEdges >::New(); feature->SetInputConnection( contours->GetOutputPort() ); feature->BoundaryEdgesOn(); feature->FeatureEdgesOff(); feature->NonManifoldEdgesOn(); feature->ManifoldEdgesOff(); feature->Update(); vtkSmartPointer< vtkFillHolesFilter > fillFilter = vtkSmartPointer< vtkFillHolesFilter >::New(); vtkSmartPointer< vtkPolyDataConnectivityFilter > connectivityFilter = vtkSmartPointer< vtkPolyDataConnectivityFilter >::New(); connectivityFilter->SetExtractionModeToLargestRegion(); if ( feature->GetOutput()->GetNumberOfCells() > 0 ) { // fill holes if any! fillFilter->SetInputConnection( contours->GetOutputPort() ); fillFilter->Update(); connectivityFilter->SetInputConnection( fillFilter->GetOutputPort() ); } else { connectivityFilter->SetInputConnection( contours->GetOutputPort() ); } // keep the largest region connectivityFilter->Update(); unsigned int smoothingIterations = 15; double passBand = 0.001; double featureAngle = 120.0; // smoothing vtkSmartPointer< vtkWindowedSincPolyDataFilter > smoother = vtkSmartPointer< vtkWindowedSincPolyDataFilter >::New(); smoother->SetInputConnection( connectivityFilter->GetOutputPort() ); smoother->SetNumberOfIterations( smoothingIterations ); smoother->BoundarySmoothingOff(); smoother->FeatureEdgeSmoothingOff(); smoother->SetFeatureAngle(featureAngle); smoother->SetPassBand(passBand); smoother->NonManifoldSmoothingOn(); smoother->NormalizeCoordinatesOn(); smoother->Update(); vtkPolyData *output = vtkPolyData::New(); output->DeepCopy( connectivityFilter->GetOutput() ); return output; } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMergeConvexHullAlgo.cxx0000644000175000017500000000561511667757442025016 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoMergeConvexHullAlgo.h" QGoMergeConvexHullAlgo::QGoMergeConvexHullAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) :QGoSplitSegmentationAlgo(iSeeds, iParent) { this->SetAlgoWidget(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoMergeConvexHullAlgo::~QGoMergeConvexHullAlgo() { this->DeleteParameters(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMergeConvexHullAlgo::DeleteParameters() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMergeConvexHullAlgo::SetAlgoWidget(QWidget* iParent) { this->m_AlgoWidget = new QGoAlgorithmWidget("ConvexHull", iParent); QGoSplitSegmentationAlgo::SetAlgoWidget(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSetOfContoursLevelSetAlgo.cxx0000644000175000017500000000674011667757442026170 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSetOfContoursLevelSetAlgo.h" #include "QGoFilterChanAndVese.h" #include "GoImageProcessor.h" QGoSetOfContoursLevelSetAlgo::QGoSetOfContoursLevelSetAlgo( std::vector< vtkPoints* >* iSeeds, QWidget* iParent) :QGoLevelSetAlgo(iSeeds, iParent) { m_Sampling = new QGoAlgoParameter("Sampling", false, 0, 999, 3); this->m_AlgoWidget->AddParameter(m_Sampling); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoSetOfContoursLevelSetAlgo::~QGoSetOfContoursLevelSetAlgo() { //this->DeleteParameters(); delete m_Sampling; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoSetOfContoursLevelSetAlgo::ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn) { std::vector NewContours = std::vector(); return NewContours; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector > QGoSetOfContoursLevelSetAlgo:: ApplyAlgoSeveralSeeds( GoImageProcessor* iImages, std::string iChannel) { std::vector > NewContours; QGoFilterChanAndVese LevelSetFilter; //double *center = new double[3]; /* NewContours = LevelSetFilter.ApplyFilterSetOf2D(this->m_Radius->GetValue(), this->m_Seeds, this->m_Iterations->GetValue(), this->m_Curvature->GetValue(),this->m_Sampling->GetValue(), iImages, iChannel );*/ return NewContours; } GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSetOfContoursWaterShedAlgo.h0000644000175000017500000002153411667757442025756 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSetOfContoursWaterShedAlgo_h #define __QGoSetOfContoursWaterShedAlgo_h // external files #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "vtkTransform.h" #include "vtkTransformPolyDataFilter.h" // project files #include "QGoWaterShedAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "QGoFilterWatershed.h" // temp for debug purpose #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "itkImageFileWriter.h" #include "vtkPointData.h" class GoImageProcessor; /** \class QGoSetOfContoursWaterShedAlgo \brief class to be the interface between the watershed algo for set of contours and GoFigure */ class QGoSetOfContoursWaterShedAlgo: public QGoWaterShedAlgo { public: QGoSetOfContoursWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, int iMaxThreshold, QWidget* iParent = 0); ~QGoSetOfContoursWaterShedAlgo(); // should not be virutal pure since we dont implement it.... std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false); std::vector > ApplyAlgoSeveralSeeds( GoImageProcessor* iImages, std::string iChannel); protected: QGoAlgoParameter* m_Sampling; template < class TPixel > // note this will work only in 3D, so we can remove the template // parameter on the image dimension //unsigned int VImageDimension > std::vector ApplyWaterShedFilter( const std::vector& iCenter, typename itk::Image< TPixel, 3 >::Pointer iImages, const unsigned int& iOrientation) { assert( iCenter.size() == 3); const unsigned int ImageDimension = 3; typedef TPixel PixelType; typedef itk::Image< PixelType, ImageDimension > ImageType; typedef typename ImageType::Pointer ImagePointer; typedef itk::Image< PixelType, 2 > ImageType2D; typedef typename ImageType2D::Pointer ImageType2DPointer; typedef typename ImageType::SpacingType ImageSpacingType; std::vector output; ImageSpacingType spacing = iImages->GetSpacing(); for(int i= 0; im_Sampling->GetValue(); ++i) { // let's compute the bounds of the region of interest double radius = this->m_Radius->GetValue(); std::vector< double > bounds( 2 * ImageDimension, 0. ); unsigned int k = 0; for( unsigned int dim = 0; dim < ImageDimension; dim++ ) { bounds[k++] = iCenter[dim] - 2. * radius; bounds[k++] = iCenter[dim] + 2. * radius; } int pair = i+ i%2 -1; if(pair < 0) { pair = 0; } bounds[2*iOrientation] = iCenter[iOrientation] + (pair*(pow(-1., static_cast(i) ) )*spacing[iOrientation]); bounds[2*iOrientation +1] = iCenter[iOrientation] + (pair*(pow(-1., static_cast(i) ) )*spacing[iOrientation]); // then let's extract the Slice of Interest ImageType2DPointer ITK_Slice_Image = this->ITKExtractSlice( bounds, iImages ); // Compute the segmentation in 3D QGoFilterWatershed Filter; Filter.Apply2DFilter< PixelType >( ITK_Slice_Image, this->m_ThresMin->GetValue(), this->m_ThresMax->GetValue(), this->m_CorrThres->GetValue(), this->m_Alpha->GetValue(), this->m_Beta->GetValue()); typename QGoFilterWatershed::Output2DPointer ItkOutPut = Filter.GetOutput2D(); // Here it would be better if the mesh extraction would be performed directly // in ITK instead. vtkImageData * FilterOutPutToVTK = this->ConvertITK2VTK< typename QGoFilterWatershed::OutputPixelType, 2>( ItkOutPut ); // Nicolas- should be able to tune the parameter -0.5- vtkPolyData* temp_output = this->ExtractPolyData(FilterOutPutToVTK, 0.5); // translation transform ----------------------- //------------------------------------------------------------------------ double temp_bounds[6]; FilterOutPutToVTK->GetBounds( temp_bounds ); double temp_center[3]; temp_center[0] = ( temp_bounds[0] + temp_bounds[1] ) * 0.5; temp_center[1] = ( temp_bounds[2] + temp_bounds[3] ) * 0.5; temp_center[2] = ( temp_bounds[4] + temp_bounds[5] ) * 0.5; vtkSmartPointer< vtkTransform > translation2 = vtkSmartPointer< vtkTransform >::New(); translation2->Translate(-temp_center[0], -temp_center[1], -temp_center[2]); vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform2 = vtkSmartPointer< vtkTransformPolyDataFilter >::New(); mesh_transform2->SetTransform(translation2); mesh_transform2->SetInput( temp_output ); mesh_transform2->Update(); // rotation transform ----------------------- //------------------------------------------------------------------------ vtkSmartPointer< vtkTransform > translation = vtkSmartPointer< vtkTransform >::New(); // rotate polydata if necessary if(iOrientation == 0) { translation->RotateY(-90); // check if + or - 90 } else if(iOrientation == 1) { translation->RotateX(-90); // check if + or - 90 } else if(iOrientation == 2) { // no rotation, we are in the good plan } vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform = vtkSmartPointer< vtkTransformPolyDataFilter >::New(); mesh_transform->SetTransform(translation); mesh_transform->SetInput( mesh_transform2->GetOutput() ); mesh_transform->Update(); // translate back ----------------------- //------------------------------------------------------------------------ double temp_center2[3]; temp_center2[0] = ( bounds[0] + bounds[1] ) * 0.5; temp_center2[1] = ( bounds[2] + bounds[3] ) * 0.5; temp_center2[2] = ( bounds[4] + bounds[5] ) * 0.5; vtkSmartPointer< vtkTransform > translation23 = vtkSmartPointer< vtkTransform >::New(); translation23->Translate(temp_center2[0], temp_center2[1], temp_center2[2]); vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform23 = vtkSmartPointer< vtkTransformPolyDataFilter >::New(); mesh_transform23->SetTransform(translation23); mesh_transform23->SetInput( mesh_transform->GetOutput() ); mesh_transform23->Update(); //----------------------------------------------------------------------- temp_output->Delete(); vtkPolyData* testt = vtkPolyData::New(); testt->DeepCopy(mesh_transform23->GetOutput()); output.push_back(testt); } return output; } }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoContourLevelSetAlgo.cxx0000644000175000017500000000757611667757442025054 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoContourLevelSetAlgo.h" #include "QGoFilterChanAndVese.h" #include "GoImageProcessor.h" QGoContourLevelSetAlgo:: QGoContourLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) :QGoLevelSetAlgo(iSeeds, iParent) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoContourLevelSetAlgo::~QGoContourLevelSetAlgo() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoContourLevelSetAlgo::ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn) { std::vector oNewContours = std::vector(); if ( this->m_Radius->GetValue() <= 0 ) { std::cerr << "Radius should be > 0 " << std::endl; return oNewContours; } double Center[3]; std::vector CenterVect(3); // LOOP FOR EACH SEED for( size_t id = 0; id < this->m_Seeds->size(); id++ ) { unsigned int dimension2Collapse(0); if(id == 0) { dimension2Collapse = 2; // we are in XY view, collapse Z } else if(id == 1) { dimension2Collapse = 1; // we are in XZ view, collapse Y } else if(id == 2) { dimension2Collapse = 0; // we are in YZ view, collapse X } for ( int i = 0; i < (*this->m_Seeds)[id]->GetNumberOfPoints(); i++ ) { (*this->m_Seeds)[id]->GetPoint(i, Center); CenterVect[0] = Center[0]; CenterVect[1] = Center[1]; CenterVect[2] = Center[2]; vtkPolyData* temp_output = this->ApplyLevelSetFilter< unsigned char >( CenterVect, iImages->getImageITK< unsigned char, 3>(iChannel),//input raw image dimension2Collapse);// axe to be collapsed(0=x, 1=y, 2=z) oNewContours.push_back( temp_output ); } } return oNewContours; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSetOfContoursLevelSetAlgo.h0000644000175000017500000000532011667757442025606 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSetOfContoursLevelSetAlgo_h #define __QGoSetOfContoursLevelSetAlgo_h #include "QGoLevelSetAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" class GoImageProcessor; /** \class QGoSetOfContoursLevelSetAlgo \brief class to be the interface between the levelset algo for set of contours and GoFigure */ class QGoSetOfContoursLevelSetAlgo: public QGoLevelSetAlgo { public: QGoSetOfContoursLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); ~QGoSetOfContoursLevelSetAlgo(); std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false); std::vector > ApplyAlgoSeveralSeeds( GoImageProcessor* iImages, std::string iChannel); protected: QGoAlgoParameter* m_Sampling; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshMergeConvexHullAlgo.h0000644000175000017500000000515511667757442025257 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoMeshMergeConvexHullAlgo_h #define __QGoMeshMergeConvexHullAlgo_h #include "QGoMergeConvexHullAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" class GoImageProcessor; /** \class QGoMeshMergeConvexHullAlgo \brief class to be the interface between the QGoMeshMergeConvexHullAlgo algo for meshes and GoFigure */ class QGoMeshMergeConvexHullAlgo: public QGoMergeConvexHullAlgo { public: QGoMeshMergeConvexHullAlgo(std::vector< vtkPoints* >* iSeeds, QWidget *iParent = 0); ~QGoMeshMergeConvexHullAlgo(); std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, std::vector iPolyData, bool iIsInvertedOn); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoTraceEditingWidgetManager.cxx0000644000175000017500000003065111667757442026143 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTraceEditingWidgetManager.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoAlgorithmsManagerWidget.h" #include "vtkSmartPointer.h" #include "vtkImageExport.h" #include "vtkImageData.h" #include #include "GoImageProcessor.h" QGoTraceEditingWidgetManager::QGoTraceEditingWidgetManager( std::string iTraceName, std::vector iVectChannels, int iTimeMin, int iTimeMax, std::vector< vtkPoints* >* iSeeds, GoImageProcessor* iImages, int* iCurrentTimePoint, QWidget* iParent) { this->m_TraceName = iTraceName; this->m_Seeds = iSeeds; this->m_Images = iImages; this->m_CurrentTimePoint = iCurrentTimePoint; this->m_MaxThreshold = iImages->getMaxImage(); this->SetTheTraceWidget(iVectChannels, iTimeMin, iTimeMax, iParent); this->SetTheDockWidget(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoTraceEditingWidgetManager::~QGoTraceEditingWidgetManager() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidgetManager::SetTheTraceWidget( std::vector iVectChannels, int iTimeMin, int iTimeMax, QWidget* iParent) { QStringList ListTimePoints; for (int i = iTimeMin; i < iTimeMax+1; ++i) { ListTimePoints.push_back(tr("%1").arg(i)); } this->m_ListTimePoint = ListTimePoints; this->m_TraceEditingWidget = new QGoTraceEditingWidget( this->m_TraceName.c_str(), iVectChannels, ListTimePoints, iParent); QObject::connect( this->m_TraceEditingWidget, SIGNAL(SetSeedInteractorBehaviour(bool) ), this, SIGNAL(SetSeedInteractorBehaviour(bool) ) ); QObject::connect( this->m_TraceEditingWidget, SIGNAL(ResetClicked() ), this, SIGNAL(ClearAllSeeds() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidgetManager::SetTheDockWidget(QWidget* iParent) { this->m_TraceEditingDockWidget = new QGoDockWidget(iParent); std::string WindowTitle = this->m_TraceName; WindowTitle += " Editing"; this->m_TraceEditingDockWidget->setWindowTitle(WindowTitle.c_str()); this->m_TraceEditingDockWidget->setWidget(this->m_TraceEditingWidget); QIcon TraceSegmentationIcon; std::string PathIcon = ":/fig/"; PathIcon += this->m_TraceName; PathIcon += "Editing.png"; TraceSegmentationIcon.addPixmap(QPixmap( QString::fromUtf8(PathIcon.c_str() ) ), QIcon::Normal, QIcon::Off); this->m_TraceEditingDockWidget->toggleViewAction()->setIcon(TraceSegmentationIcon); this->m_TraceEditingDockWidget->toggleViewAction()->setToolTip( tr("%1 Editing").arg(this->m_TraceName.c_str() ) ); this->m_TraceEditingDockWidget->toggleViewAction()->setStatusTip( tr("Create %1s manually, semi-automatically or automatically").arg(this->m_TraceName.c_str() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QAction* QGoTraceEditingWidgetManager::GetToggleViewAction() { return this->m_TraceEditingDockWidget->toggleViewAction(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoDockWidget* QGoTraceEditingWidgetManager::GetDockWidget() { return this->m_TraceEditingDockWidget; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidgetManager::SetVisible(bool isVisible) { this->m_TraceEditingDockWidget->setVisible(isVisible); this->m_TraceEditingWidget->CheckTheCurrentMode(isVisible); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidgetManager::SetTSliceForClassicView() { this->m_TraceEditingWidget->SetTSliceForClassicView( *this->m_CurrentTimePoint); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTraceEditingWidgetManager::SetTSliceForDopplerView( QHash iListTimePoints, int iChannelNumber) { this->m_TraceEditingWidget->SetTSliceForDopplerView( iListTimePoints, iChannelNumber); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoTraceEditingWidgetManager::GetSelectedTimePoint() { return this->m_TraceEditingWidget->GetSelectedTimePoint(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*void QGoMeshEditingWidgetManager::SetSemiAutomaticAlgorithms(QWidget* iParent) { //level set: m_LevelSetAlgo = new QGoMeshLevelSetAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* LevelSetWidget = m_LevelSetAlgo->GetAlgoWidget(); this->m_MeshEditingWidget->AddAlgoWidgetForSemiAutomaticMode(LevelSetWidget); QObject::connect(LevelSetWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplyLevelSetAlgo() ) ); //shape: this->m_ShapeAlgo = new QGoMeshShapeAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* ShapeWidget = this->m_ShapeAlgo->GetAlgoWidget(); this->m_MeshEditingWidget->AddAlgoWidgetForSemiAutomaticMode(ShapeWidget); QObject::connect(ShapeWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplyShapeAlgo() ) ); //watershed: this->m_WaterShedAlgo = new QGoMeshWaterShedAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* WaterShedWidget = m_WaterShedAlgo->GetAlgoWidget(); this->m_MeshEditingWidget->AddAlgoWidgetForSemiAutomaticMode(WaterShedWidget); QObject::connect(WaterShedWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplyWaterShedAlgo() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::SetSetOfContoursAlgorithms( std::vector iVectChannels, QStringList iListTime, QWidget* iParent) { m_SetOfContoursWidget = new QGoAlgorithmsManagerWidget("Set of Contours", iParent, iVectChannels, iListTime); this->m_SetOfContoursWaterShedAlgo = new QGoSetOfContoursWaterShedAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* SetOfContoursWaterShedWidget = this->m_SetOfContoursWaterShedAlgo->GetAlgoWidget(); this->m_SetOfContoursWidget->AddMethod(SetOfContoursWaterShedWidget); this->m_SetOfContoursLevelSetAlgo = new QGoSetOfContoursLevelSetAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* SetOfContoursLevelSetWidget = this->m_SetOfContoursLevelSetAlgo->GetAlgoWidget(); this->m_SetOfContoursWidget->AddMethod(SetOfContoursLevelSetWidget); this->m_SetOfContoursShapeAlgo = new QGoSetOfContoursShapeAlgo(this->m_Seeds, iParent); QGoAlgorithmWidget* SetOfContoursShapeWidget = this->m_SetOfContoursShapeAlgo->GetAlgoWidget(); this->m_SetOfContoursWidget->AddMethod(SetOfContoursShapeWidget); this->m_MeshEditingWidget->AddMode(m_SetOfContoursWidget, true); QObject::connect(SetOfContoursWaterShedWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplySetOfContoursWaterShedAlgo() ) ); QObject::connect(SetOfContoursLevelSetWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplySetOfContoursLevelSetAlgo() ) ); QObject::connect(SetOfContoursShapeWidget, SIGNAL(ApplyAlgo() ), this, SLOT(ApplySetOfContoursShapeAlgo() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::SetSplitMergeMode(QWidget* iParent) { QGoAlgorithmsManagerWidget* SplitAlgoWidget = new QGoAlgorithmsManagerWidget("Split", iParent); this->m_MeshEditingWidget->AddMode(SplitAlgoWidget, true); m_DanielAlgo = new QGoMeshSplitDanielssonDistanceAlgo(iParent); QGoAlgorithmWidget * DanielWidget = m_DanielAlgo->GetAlgoWidget(); SplitAlgoWidget->AddMethod(DanielWidget ); QObject::connect( DanielWidget, SIGNAL(ApplyAlgo() ) , this, SLOT(ApplyDanielAlgo() ) ); QGoAlgorithmsManagerWidget* MergeAlgoWidget = new QGoAlgorithmsManagerWidget("Merge", iParent); this->m_MeshEditingWidget->AddMode(MergeAlgoWidget, true); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplyDanielAlgo() { this->GetPolydatasFromAlgo(this->m_DanielAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplyLevelSetAlgo() { this->GetPolydatasFromAlgo(this->m_LevelSetAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplyShapeAlgo() { this->GetPolydatasFromAlgo(this->m_ShapeAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplyWaterShedAlgo() { this->GetPolydatasFromAlgo(this->m_WaterShedAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplySetOfContoursWaterShedAlgo() { this->GetSetOfPolydatasFromAlgo( this->m_SetOfContoursWaterShedAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplySetOfContoursLevelSetAlgo() { this->GetSetOfPolydatasFromAlgo( this->m_SetOfContoursLevelSetAlgo); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoMeshEditingWidgetManager::ApplySetOfContoursShapeAlgo() { this->GetSetOfPolydatasFromAlgo( this->m_SetOfContoursShapeAlgo); }*/ GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoWaterShedAlgo.cxx0000644000175000017500000000732211667757442023632 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoWaterShedAlgo.h" // need param: max threshold QGoWaterShedAlgo::QGoWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, int iMaxThreshold, QWidget* iParent) :QGoSemiAutoSegmentationAlgo(iSeeds,iParent) { m_MaxThreshold = iMaxThreshold; this->SetAlgoWidget(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoWaterShedAlgo::~QGoWaterShedAlgo() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoWaterShedAlgo::DeleteParameters() { delete m_ThresMin; delete m_ThresMax; delete m_CorrThres; delete m_Alpha; delete m_Beta; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoWaterShedAlgo::SetAlgoWidget(QWidget* iParent) { this->m_AlgoWidget = new QGoAlgorithmWidget("WaterShed", iParent); m_ThresMin = new QGoAlgoParameter("Background <",true, 0, m_MaxThreshold, 10); this->m_AlgoWidget->AddParameter(m_ThresMin); m_ThresMax = new QGoAlgoParameter("Nuclei >", true, 0, m_MaxThreshold, 30); this->m_AlgoWidget->AddParameter(m_ThresMax); m_CorrThres = new QGoAlgoParameter("Gaussian Simile", true, 0, 1, 2, 0.5, 0.01); this->m_AlgoWidget->AddParameter(m_CorrThres); m_Alpha = new QGoAlgoParameter("Scaling", true, 0, 10, 2, 1.5, 0.1); this->m_AlgoWidget->AddParameter(m_Alpha); m_Beta = new QGoAlgoParameter("Slope", true, 0, 10, 2, 3, 0.1); this->m_AlgoWidget->AddParameter(m_Beta); QGoSemiAutoSegmentationAlgo::SetAlgoWidget(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSplitSegmentationAlgo.h0000644000175000017500000000670011667757442025041 0ustar mathieumathieu /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSplitSegmentationAlgo_h #define __QGoSplitSegmentationAlgo_h #include "QGoSegmentationAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "QGoGUILibConfigure.h" class GoImageProcessor; /** \class QGoSplitSegmentationAlgo \brief abstract class to be the interface between the semi automatic algorithms for meshes and contours and GoFigure */ class QGOGUILIB_EXPORT QGoSplitSegmentationAlgo:public QGoSegmentationAlgo { Q_OBJECT public: explicit QGoSplitSegmentationAlgo(std::vector< vtkPoints* >* iSeeds, QWidget *iParent = 0); virtual ~QGoSplitSegmentationAlgo(); /** \brief return the vtkpolydata created by the algorithm */ virtual std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, std::vector iPolyData, bool iIsInvertedOn = false) = 0; protected: std::vector< vtkPoints* >* m_Seeds; QGoAlgoParameter* m_Radius; /** \brief construct the algowidget with the different parameters */ virtual void SetAlgoWidget(QWidget* iParent = 0); /** \brief delete the different parameters */ virtual void DeleteParameters() = 0; /* * \brief Get boundingBox from a center and a radius * \param[in] iCenter center of the box * \param[in] iRadius radius of the box * \param[in] iOrientation 0-xy, 1-xz, 2-yz, 3-xyz * \return vector[6] containing the bounding box (xmin, xmax, ymin, imax, ...) */ std::vector GetBounds( const std::vector& iCenter, const double& iRadius, const unsigned int& iOrientation = 3); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoFilterChanAndVese.h0000644000175000017500000001521211667757442024050 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoFilterChanAndVese_h #define __QGoFilterChanAndVese_h #include "QGoFilterSemiAutoBase.h" #include #include "QGoGUILibConfigure.h" #include "itkImage.h" #include "itkChanAndVeseSegmentationFilter.h" #include "itkVTKImageImport.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" class GoImageProcessor; /** * \class QGoFilterChanAndVese * \brief Levelset segmentation algorithm implementation. * Can generate contours and meshes. * Will generate 2D objects if m_Dimension<2, 3D objects in the other case. */ class QGOGUILIB_EXPORT QGoFilterChanAndVese : public QGoFilterSemiAutoBase { Q_OBJECT public: typedef float OutputPixelType; typedef itk::Image< float, 3 > Output3DType; typedef Output3DType::Pointer Output3DPointer; typedef itk::Image< float, 2 > Output2DType; typedef Output2DType::Pointer Output2DPointer; /** \brief Constructor */ explicit QGoFilterChanAndVese(QObject *iParent = NULL, int iDimension = 2); /** \brief Destructor */ ~QGoFilterChanAndVese(); std::vector ApplyFilterLevelSet3D(double iRadius, vtkPoints* iPoints, int iIterations, int iCurvature, GoImageProcessor* iImages, int iChannel); template< typename TPixel > void Apply3DFilter( typename itk::Image< TPixel, 3 >::Pointer iITKInput, const std::vector< double >& iCenter, const double& iRadius, const int& iIterations, const int& iCurvature) { typedef itk::Image< TPixel, 3 > FeatureImageType; typedef itk::ChanAndVeseSegmentationFilter< FeatureImageType > SegmentationFilterType; typedef typename SegmentationFilterType::Pointer SegmentationFilterPointer; typedef typename SegmentationFilterType::InternalPointType ITKPointType; typedef typename SegmentationFilterType::InternalCoordRepType ITKCoordType; // convert center into ITKPointType ITKPointType itk_center; for( unsigned int dim = 0; dim < 3; dim++ ) { itk_center[dim] = static_cast< ITKCoordType >( iCenter[dim] ); } // convert radius into ITKCoordType ITKCoordType itk_radius = static_cast< ITKCoordType >( iRadius ); // ITK filter SegmentationFilterPointer filter = SegmentationFilterType::New(); filter->SetCenter( itk_center ); filter->SetRadius( itk_radius ); filter->SetFeatureImage(iITKInput); filter->SetPreprocess(0);//1); filter->SetNumberOfIterations(iIterations); filter->SetCurvatureWeight(iCurvature); filter->Update(); typename Output3DType::Pointer resulting_image = filter->GetOutput(); if( resulting_image.IsNotNull() ) { m_Image3D->Graft( resulting_image ); } else { itkGenericExceptionMacro( <<"ChanAndVeseSegmentationFilter's output is NULL" ); } } template< typename TPixel > void Apply2DFilter( typename itk::Image< TPixel, 2 >::Pointer iITKInput, const std::vector< double >& iCenter, const double& iRadius, const int& iIterations, const int& iCurvature) { typedef itk::Image< TPixel, 2 > FeatureImageType; typedef itk::ChanAndVeseSegmentationFilter< FeatureImageType > SegmentationFilterType; typedef typename SegmentationFilterType::Pointer SegmentationFilterPointer; typedef typename SegmentationFilterType::InternalPointType ITKPointType; typedef typename SegmentationFilterType::InternalCoordRepType ITKCoordType; // convert center into ITKPointType ITKPointType itk_center; for( unsigned int dim = 0; dim < 2; dim++ ) { itk_center[dim] = static_cast< ITKCoordType >( iCenter[dim] ); } // convert radius into ITKCoordType ITKCoordType itk_radius = static_cast< ITKCoordType >( iRadius ); // ITK filter SegmentationFilterPointer filter = SegmentationFilterType::New(); filter->SetCenter( itk_center ); filter->SetRadius( itk_radius ); filter->SetFeatureImage(iITKInput); filter->SetPreprocess(0);//1); filter->SetNumberOfIterations(iIterations); filter->SetCurvatureWeight(iCurvature); filter->Update(); typename Output2DType::Pointer resulting_image = filter->GetOutput(); if( resulting_image.IsNotNull() ) { m_Image2D->Graft( resulting_image ); } else { itkGenericExceptionMacro( <<"ChanAndVeseSegmentationFilter's output is NULL" ); } } std::vector > ApplyFilterSetOf2D( double iRadius, std::vector< vtkPoints* >* iPoints, int iIterations, int iCurvature, int iSampling, GoImageProcessor* iImages, int iChannel); Output3DType::Pointer GetOutput3D() { return m_Image3D; } Output2DType::Pointer GetOutput2D() { return m_Image2D; } private: //void Filter2D(double *iCenter, const int & iOrientation); Output3DType::Pointer m_Image3D; Output2DType::Pointer m_Image2D; int m_Iterations; int m_Curvature; int m_Dimension; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.h.bak0000644000175000017500000002320411667757442024557 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSegmentationAlgo_h #define __QGoSegmentationAlgo_h #include "QGoAlgorithmWidget.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" #include "QGoGUILibConfigure.h" // convert VTK to ITK #include "itkImage.h" #include "itkVTKImageImport.h" #include "vtkImageExport.h" #include "vtkitkAdaptor.h" // convert itk to vtk #include "itkImageToVTKImageFilter.h" /** \class QGoSegmentationAlgo \brief abstract class to be the interface between the algorithms for meshes and contours and GoFigure */ class QGOGUILIB_EXPORT QGoSegmentationAlgo:public QObject { Q_OBJECT public: QGoSegmentationAlgo(QWidget *iParent = 0); ~QGoSegmentationAlgo(); /** \brief return the algowidget */ QGoAlgorithmWidget* GetAlgoWidget(); /** \brief return the vtkpolydata created by the algorithm */ virtual std::vector ApplyAlgo( std::vector >* iImages, int iChannel) = 0; /* * \note Nicolas-shouldnt be public-move to protected */ /* * \brief Extract region of interest, given a bounding box and a list of vtk images * \param[in] iBounds bounding box (xmin, xmax, ymin, ymax, zmin, zmax) * \param[in] iImages vector of vtkimagedata * \return list of roi */ std::vector ExtractROI(std::vector iBounds, std::vector iImages); /* * \brief Extract region of interest, given a bounding box and a vtk image * \param[in] iBounds bounding box (xmin, xmax, ymin, ymax, zmin, zmax) * \param[in] iImage vtkimagedata * \return roi */ <<<<<<< HEAD vtkImageData* ExtractROI(std::vector iBounds, vtkImageData* iImage); ======= vtkSmartPointer ExtractROI(double* iBounds, vtkSmartPointer iImage); >>>>>>> add_genericMethods /* * \brief Convert a vtkImage to a itkImage. If we call after "ExtractROI", * the dimension should be 3 all the time. * (Even if we extract a2D region from a 3d image) * \tparam PixelType type of pixel (unsigned char, etc.) * \tparam VImageDimension dimension of the image (2 or 3) * \param[in] iInput Pointer to a vtkImageData * \return Pointer to an itkImage */ template< class PixelType, unsigned int VImageDimension > typename itk::Image< PixelType, VImageDimension >::Pointer ConvertVTK2ITK(vtkImageData *iInput) { // make sure there is an input assert ( iInput ); //Export VTK image to ITK vtkSmartPointer exporter = vtkSmartPointer::New(); exporter->SetInput(iInput); exporter->Update(); // ImageType typedef itk::Image< PixelType, VImageDimension > ImageType; // Import VTK Image to ITK typedef itk::VTKImageImport< ImageType > ImageImportType; typedef typename ImageImportType::Pointer ImageImportPointer; ImageImportPointer importer = ImageImportType::New(); ConnectPipelines< vtkImageExport, ImageImportPointer >( exporter, importer); typename ImageType::Pointer itkImage = importer->GetOutput(); itkImage->DisconnectPipeline(); return itkImage; } /* * \brief Convert a itkImage to a vtkImage. If we call after "ExtractROI", * the dimension should be 3 all the time. * (Even if we extract a2D region from a 3d image) * \tparam PixelType type of pixel (unsigned char, etc.) * \tparam VImageDimension dimension of the image (2 or 3) * \param[in] iInput Pointer to an itkImage * \return Pointer to an vtkImageData */ template< class PixelType, unsigned int VImageDimension > vtkSmartPointer ConvertITK2VTK(typename itk::Image< PixelType, VImageDimension >::Pointer iInput) { typedef itk::Image< PixelType, VImageDimension > InternalImageType; typedef itk::ImageToVTKImageFilter< InternalImageType > ConverterType; typedef typename ConverterType::Pointer ConverterPointer; ConverterPointer converter = ConverterType::New(); converter->SetInput(iInput); try { converter->Update(); } catch (itk::ExceptionObject & err) { std::cerr << "converter Exception:" << err << std::endl; } return converter->GetOutput(); } /* * \brief Generate list of polydata given a list of vtkimages and a threshold * \param[in] iInputImage list of images * \param[in] iThreshold threshold * \return list of polydatas */ std::vector ExtractPolyData(std::vector iInputImage, const double & iThreshold); /* * \brief Generate a polydata given a vtkimage and a threshold * \param[in] iInputImage vtk image * \param[in] iThreshold threshold * \return polydata */ vtkSmartPointer ExtractPolyData(vtkImageData *iInputImage, const double & iThreshold); /* * \brief Decimate a polydata * \param[in] iPolyData polyData to be decimated * \param[in] iNumberOfPoints target number of points * \return Decimated polyData */ vtkSmartPointer DecimatePolyData( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints); /* * \brief Enable decimation during polydata extraction. * \param[in] iDecimate yes (true), no (false) */ void SetDecimate(bool& iDecimate); /* * \brief Is decimation enabled? * \return true (yes), false (no) */ bool GetDecimate(); /* * \brief Set target number of points for polydata extraction * \param[in] iNumberOfPoints number of points */ void SetNumberOfPoints( unsigned int& iNumberOfPoints); /* * \brief Get target number of points for polydata extraction * \return number of points */ unsigned int GetNumberOfPoints(); private: /* * \brief Reconstruct a contour from a vtkImageData and a threshold * \param[in] iInputImage vtkImageData * \param[in] iThreshold threshold * \return Pointer to a vtkPolyData */ vtkSmartPointer ExtractContour( vtkSmartPointer iInputImage, const double & iThreshold); /* * \brief Reorganize points within a contour * Required if we want to reedit this contour after. * 1-reorganize * \param[in] iInputImage vtkImageData * \return Pointer to a vtkPolyData */ vtkSmartPointer ReorganizeContour( vtkSmartPointer iInputImage); /* * \brief Reconstruct a mesh from a vtkImageData and a threshold * \param[in] iInputImage vtkImageData * \param[in] iThreshold threshold * \return Pointer to a vtkPolyData */ vtkSmartPointer ExtractMesh( vtkSmartPointer iInputImage, const double & iThreshold); /* * \brief Decimate a contour (line) * \param[in] iPolyData polyData to be decimated * \param[in] iNumberOfPoints target number of points * \return Decimated polyData */ vtkSmartPointer DecimateContour( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints); /* * \brief Decimate a mesh * \param[in] iPolyData polyData to be decimated * \param[in] iNumberOfPoints target number of points * \return Decimated polyData */ vtkSmartPointer DecimateMesh( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints); bool m_Decimate; unsigned int m_NumberOfPoints; protected: QGoAlgorithmWidget* m_AlgoWidget; /** \brief construct the algowidget with the different parameters */ virtual void SetAlgoWidget(QWidget* iParent = 0) = 0; /** \brief delete the different parameters */ virtual void DeleteParameters() = 0; /* * \todo Arnaud has something for itkimage to vtkpolydata in 3d */ //add a method std::vector ConvertITKImagesToPolyData(std::vector iImages) //add a method std::vector GetAttribut(std::vector iNewTraces) //add a method itkImage ConvertVTKToITK(vtkImageIData iImage) }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSetOfContoursWaterShedAlgo.cxx0000644000175000017500000001064711667757442026334 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSetOfContoursWaterShedAlgo.h" #include "GoImageProcessor.h" QGoSetOfContoursWaterShedAlgo:: QGoSetOfContoursWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, int iMaxThreshold, QWidget* iParent) :QGoWaterShedAlgo(iSeeds, iMaxThreshold, iParent) { m_Sampling = new QGoAlgoParameter("Sampling", false, 0, 999, 3); this->m_AlgoWidget->AddParameter(m_Sampling); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoSetOfContoursWaterShedAlgo:: ~QGoSetOfContoursWaterShedAlgo() { //this->DeleteParameters(); delete m_Sampling; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoSetOfContoursWaterShedAlgo:: ApplyAlgo(GoImageProcessor* iImages,std::string iChannel, bool iIsInvertedOn) { std::vector NewContours = std::vector(); return NewContours; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector > QGoSetOfContoursWaterShedAlgo:: ApplyAlgoSeveralSeeds( GoImageProcessor* iImages, std::string iChannel) { std::vector > NewContours; if ( this->m_Radius->GetValue() <= 0 ) { std::cerr << "Radius should be > 0 " << std::endl; return NewContours; } double Center[3]; std::vector CenterVect(3); // LOOP FOR EACH SEED for( size_t id = 0; id < this->m_Seeds->size(); id++ ) { unsigned int dimension2Collapse(0); if(id == 0) { dimension2Collapse = 2; // we are in XY view, collapse Z } else if(id == 1) { dimension2Collapse = 1; // we are in XZ view, collapse Y } else if(id == 2) { dimension2Collapse = 0; // we are in YZ view, collapse X } for ( int i = 0; i < (*this->m_Seeds)[id]->GetNumberOfPoints(); i++ ) { std::cout << "dimension2Collapse: " << dimension2Collapse << std::endl; (*this->m_Seeds)[id]->GetPoint(i, Center); CenterVect[0] = Center[0]; CenterVect[1] = Center[1]; CenterVect[2] = Center[2]; std::vector temp_output = this->ApplyWaterShedFilter< unsigned char >( CenterVect, iImages->getImageITK< unsigned char, 3>(iChannel),//input raw image dimension2Collapse);// axe to be collapsed(0=x, 1=y, 2=z) NewContours.push_back( temp_output ); } } return NewContours; } GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoFilterShape.h0000644000175000017500000000646511667757442023003 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoFilterShape_h #define __QGoFilterShape_h #include "QGoFilterSemiAutoBase.h" #include "QGoGUILibConfigure.h" class GoImageProcessor; class vtkPolyData; /** * \class QGoFilterShape * \brief Shape segmentation algorithm implementation. * Can generate circles, spheres, squares and cubes. * Will generate 2D objects if m_Dimension<2, 3D objects in the other case. */ class QGOGUILIB_EXPORT QGoFilterShape:public QGoFilterSemiAutoBase { Q_OBJECT public: /** \brief Constructor */ explicit QGoFilterShape(QObject *iParent = NULL, int iDimension = 2); /** \brief Destructor */ ~QGoFilterShape(); virtual vtkPolyData * Apply(); virtual void ConnectSignals(int iFilterNumber); //integration algo /** \brief return the polydatas corresponding to the new created Shapes */ std::vector ApplyFilter3D( double iRadius, std::vector< vtkPoints* >* iPoints, std::string iShape, GoImageProcessor* iImages, int iChannel); std::vector > ApplyFilterSetOf2D(double iRadius, std::string iShape, int iSampling, std::vector< vtkPoints* >* iPoints, GoImageProcessor* iImages, int iChannel); public slots: void setShape(int); protected: int m_Shape; vtkPolyData * GenerateSphere(double *iCenter, double iRadius, vtkSmartPointer< vtkImageData > iImage); vtkPolyData * GenerateCube(double *iCenter, double iRadius, vtkSmartPointer< vtkImageData > iImage); vtkPolyData * GenerateCylinder(double *iCenter); private: Q_DISABLE_COPY(QGoFilterShape); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoManualSegmentationSettingsDialog.cxx0000644000175000017500000002140511667757442027573 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoManualSegmentationSettingsDialog.h" #include #include #include "vtkOrientedGlyphContourRepresentation.h" #include "vtkContourWidget.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkProperty.h" #include "vtkPolyData.h" #include "vtkCellArray.h" #include "vtkMath.h" QGoManualSegmentationSettingsDialog::QGoManualSegmentationSettingsDialog(QWidget *iParent, const double & iWidth, const QColor & iLineColor, const QColor & iNodeColor, const QColor & iActivatedNodeColor) : QDialog( iParent), m_LineWidth(iWidth), m_LineColor(iLineColor), m_NodeColor(iNodeColor), m_ActivatedNodeColor(iActivatedNodeColor) { this->setupUi(this); ReadSettings(); m_Renderer = vtkSmartPointer< vtkRenderer >::New(); vtkRenderWindow *renwin = this->qvtkWidget->GetRenderWindow(); renwin->AddRenderer(m_Renderer); this->LineWidthSpinBox->setValue(m_LineWidth); m_ContourRepresentation = vtkSmartPointer< vtkOrientedGlyphContourRepresentation >::New(); m_ContourRepresentation->GetLinesProperty()->SetLineWidth( static_cast< float >( m_LineWidth ) ); m_ContourRepresentation->GetLinesProperty()->SetColor( m_LineColor.redF(), m_LineColor.greenF(), m_LineColor.blueF() ); m_ContourRepresentation->GetProperty()->SetColor( m_NodeColor.redF(), m_NodeColor.greenF(), m_NodeColor.blueF() ); m_ContourRepresentation->GetActiveProperty()->SetColor( m_ActivatedNodeColor.redF(), m_ActivatedNodeColor.greenF(), m_ActivatedNodeColor.blueF() ); m_ContourWidget = vtkSmartPointer< vtkContourWidget >::New(); m_ContourWidget->SetInteractor( this->qvtkWidget->GetInteractor() ); m_ContourWidget->SetRepresentation(m_ContourRepresentation); m_ContourWidget->On(); m_InitPD = vtkSmartPointer< vtkPolyData >::New(); vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New(); vtkSmartPointer< vtkCellArray > lines = vtkSmartPointer< vtkCellArray >::New(); vtkIdType *lineIndices = new vtkIdType[7]; for ( int i = 0; i < 6; i++ ) { const double angle = 2.0 * vtkMath::Pi() * i / 6.0; points->InsertPoint(static_cast< vtkIdType >( i ), 0.1 * cos(angle), 0.1 * sin(angle), 0.0); lineIndices[i] = static_cast< vtkIdType >( i ); } lineIndices[6] = 0; lines->InsertNextCell(7, lineIndices); delete[] lineIndices; m_InitPD->SetPoints(points); m_InitPD->SetLines(lines); m_ContourWidget->Initialize(m_InitPD); m_ContourWidget->Render(); m_Renderer->ResetCamera(); renwin->Render(); QObject::connect( this->LineWidthSpinBox, SIGNAL( valueChanged(double) ), this, SLOT( SetLineWidth(double) ) ); QObject::connect( this->LineColorBtn, SIGNAL( pressed() ), this, SLOT( SelectLineColor() ) ); QObject::connect( this->NodeColorBtn, SIGNAL( pressed() ), this, SLOT( SelectNodeColor() ) ); QObject::connect( this->ActivatedNodeColorBtn, SIGNAL( pressed() ), this, SLOT( SelectActivatedNodeColor() ) ); } QGoManualSegmentationSettingsDialog:: ~QGoManualSegmentationSettingsDialog() { WriteSettings(); delete this->qvtkWidget; } double QGoManualSegmentationSettingsDialog::GetLineWidth() const { return m_LineWidth; } QColor QGoManualSegmentationSettingsDialog::GetLineColor() const { return m_LineColor; } QColor QGoManualSegmentationSettingsDialog::GetNodeColor() const { return m_NodeColor; } QColor QGoManualSegmentationSettingsDialog::GetActivatedNodeColor() const { return m_ActivatedNodeColor; } void QGoManualSegmentationSettingsDialog::SetLineWidth(const double & iValue) { if ( m_LineWidth != iValue ) { m_LineWidth = iValue; m_ContourRepresentation->GetLinesProperty()->SetLineWidth( static_cast< float >( m_LineWidth ) ); m_ContourWidget->Render(); m_Renderer->Render(); } } void QGoManualSegmentationSettingsDialog::SelectLineColor() { m_LineColor = QColorDialog::getColor( m_LineColor, this, tr("Select Line Color") ); if ( m_LineColor.isValid() ) { m_ContourRepresentation->GetLinesProperty()->SetColor( m_LineColor.redF(), m_LineColor.greenF(), m_LineColor.blueF() ); m_ContourWidget->Render(); m_Renderer->Render(); } } void QGoManualSegmentationSettingsDialog::SelectNodeColor() { m_NodeColor = QColorDialog::getColor( m_NodeColor, this, tr("Select Node Color") ); if ( m_NodeColor.isValid() ) { m_ContourRepresentation->GetProperty()->SetColor( m_NodeColor.redF(), m_NodeColor.greenF(), m_NodeColor.blueF() ); m_ContourWidget->Render(); m_Renderer->Render(); } } void QGoManualSegmentationSettingsDialog::SelectActivatedNodeColor() { m_ActivatedNodeColor = QColorDialog::getColor( m_ActivatedNodeColor, this, tr("Select Activated Node Color") ); if ( m_ActivatedNodeColor.isValid() ) { m_ContourRepresentation->GetActiveProperty()->SetColor( m_ActivatedNodeColor.redF(), m_ActivatedNodeColor.greenF(), m_ActivatedNodeColor.blueF() ); m_ContourWidget->Render(); m_Renderer->Render(); } } void QGoManualSegmentationSettingsDialog::ReadSettings() { QSettings settings; settings.beginGroup("ManualSegmentationSettings"); m_NodeColor = settings.value("NodeColor").value< QColor >(); m_ActivatedNodeColor = settings.value("ActivatedNodeColor").value< QColor >(); m_LineColor = settings.value("LineColor").value< QColor >(); m_LineWidth = settings.value("LineWidth").toDouble(); if ( ( !m_NodeColor.isValid() ) && ( !m_ActivatedNodeColor.isValid() ) && ( !m_LineColor.isValid() ) && !( m_LineWidth > 0. ) ) { m_LineWidth = 1.; m_NodeColor = Qt::cyan; m_LineColor = Qt::magenta; m_ActivatedNodeColor = Qt::yellow; } QSize tsize = settings.value("Size").toSize(); if ( tsize.isValid() ) { this->resize(tsize); this->move( settings.value("Position").toPoint() ); } else { this->resize(350, 390); } settings.endGroup(); } void QGoManualSegmentationSettingsDialog::WriteSettings() { QSettings settings; settings.beginGroup("ManualSegmentationSettings"); settings.setValue( "Size", this->size() ); settings.setValue( "Position", this->pos() ); settings.setValue("NodeColor", m_NodeColor); settings.setValue("ActivatedNodeColor", m_ActivatedNodeColor); settings.setValue("LineColor", m_LineColor); settings.setValue("LineWidth", m_LineWidth); settings.endGroup(); }GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoManualSegmentationSettingsDialog.h0000644000175000017500000001062311667757442027220 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoManualSegmentationSettingsDialog_h #define __QGoManualSegmentationSettingsDialog_h #include "ui_ManualSegmentationSettingsDlg.h" #include #include "vtkSmartPointer.h" #include "QGoGUILibConfigure.h" class vtkOrientedGlyphContourRepresentation; class vtkContourWidget; class vtkRenderer; class vtkPolyData; /** * \class QGoManualSegmentationSettingsDialog * \ingroup QGoContourManual * \brief Settings dialog for the contour widget. Useful to define the color * of the line, the color of the nodes,the color of the active nodes and the * thickness of the line */ class QGOGUILIB_EXPORT QGoManualSegmentationSettingsDialog: public QDialog, private Ui::ManualSegmentationSettingsDlg { Q_OBJECT public: explicit QGoManualSegmentationSettingsDialog(QWidget *parent = 0, const double & iWidth = 1., const QColor & iLineColor = Qt::magenta, const QColor & iNodeColor = Qt::cyan, const QColor & iActivatedNodeColor = Qt::yellow); virtual ~QGoManualSegmentationSettingsDialog(); /** * \brief Get the width of the line * \return double containing the selected width */ double GetLineWidth() const; /** * \brief Get the color of the line * \return QColor containing the selected color */ QColor GetLineColor() const; /** * \brief Get the color of the Node * \return QColor containing the selected color */ QColor GetNodeColor() const; /** * \brief Get the color of the Active Node * \return QColor containing the selected color */ QColor GetActivatedNodeColor() const; public slots: /** * \brief Set the width of the line * \param[in] iWidth double containing the selected width */ void SetLineWidth(const double & iWidth); /** * \brief Open a dialog to choose the color of the lines */ void SelectLineColor(); /** * \brief Open a dialog to choose the color of the node */ void SelectNodeColor(); /** * \brief Open a dialog to choose the color of the activated node */ void SelectActivatedNodeColor(); protected: virtual void ReadSettings(); virtual void WriteSettings(); vtkSmartPointer< vtkOrientedGlyphContourRepresentation > m_ContourRepresentation; vtkSmartPointer< vtkContourWidget > m_ContourWidget; vtkSmartPointer< vtkRenderer > m_Renderer; vtkSmartPointer< vtkPolyData > m_InitPD; double m_LineWidth; QColor m_LineColor; QColor m_NodeColor; QColor m_ActivatedNodeColor; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshShapeAlgo.h0000644000175000017500000000471711667757442023253 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoMeshShapeAlgo_h #define __QGoMeshShapeAlgo_h #include "QGoShapeAlgo.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" class GoImageProcessor; /** \class QGoMeshShapeAlgo \brief class to be the interface between the shape algo for meshes and GoFigure */ class QGoMeshShapeAlgo: public QGoShapeAlgo { public: QGoMeshShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); ~QGoMeshShapeAlgo(); std::vector ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn = false); protected: }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshShapeAlgo.cxx0000644000175000017500000000551011667757442023616 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoMeshShapeAlgo.h" #include "QGoFilterShape.h" #include "GoImageProcessor.h" QGoMeshShapeAlgo::QGoMeshShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) :QGoShapeAlgo(iSeeds, iParent) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoMeshShapeAlgo::~QGoMeshShapeAlgo() { this->DeleteParameters(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoMeshShapeAlgo::ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn) { QGoFilterShape ShapeFilter; std::vector NewMeshes = ShapeFilter.ApplyFilter3D(m_Radius->GetValue(), this->m_Seeds, this->m_Shape->Getvalue(), iImages, 0); return NewMeshes; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoMeshSplitDanielssonDistanceAlgo.cxx0000644000175000017500000001234511667757442027350 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoMeshSplitDanielssonDistanceAlgo.h" #include "itkvtkMeshSplitterDanielssonDistanceImageFilter.h" #include "GoImageProcessor.h" //temp #include "vtkPolyDataWriter.h" QGoMeshSplitDanielssonDistanceAlgo::QGoMeshSplitDanielssonDistanceAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) :QGoSplitDanielssonDistanceAlgo(iSeeds, iParent) { this->setObjectName("Split"); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoMeshSplitDanielssonDistanceAlgo::~QGoMeshSplitDanielssonDistanceAlgo() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoMeshSplitDanielssonDistanceAlgo::ApplyAlgo( GoImageProcessor* iImages, std::string iChannel, std::vector iPolyData, bool iIsInvertedOn) { const unsigned int Dimension = 3; typedef unsigned char PixelType; typedef itk::Image< PixelType, Dimension > ImageType; typedef itk::vtkMeshSplitterDanielssonDistanceImageFilter< ImageType > SplitterType; std::vector oVector; std::vector< double > bounds(6); double* boundsPointer = iPolyData[0]->GetBounds(); for(unsigned int i = 0; i(boundsPointer[i*2]); bounds[i*2+1] = static_cast(boundsPointer[i*2+1]); } typedef SplitterType::PointSetType PointSetType; PointSetType::Pointer seeds = PointSetType::New(); ImageType::PointType itk_pt; double vtk_pt[3]; int position = 0; for( size_t id = 0; id < this->m_Seeds->size(); id++ ) { for ( int i = 0; i < (*this->m_Seeds)[id]->GetNumberOfPoints(); i++ ) { (*this->m_Seeds)[id]->GetPoint(i, vtk_pt); // if seed is inside the bounding box, use it! if( vtk_pt[0] > bounds[0] && vtk_pt[0] < bounds[1] && vtk_pt[1] > bounds[2] && vtk_pt[1] < bounds[3] && vtk_pt[2] > bounds[4] && vtk_pt[2] < bounds[5]) { itk_pt[0] = vtk_pt[0]; itk_pt[1] = vtk_pt[1]; itk_pt[2] = vtk_pt[2]; std::cout << itk_pt[0] << "-" << itk_pt[1] << "-" << itk_pt[2] << std::endl; seeds->SetPoint( position, itk_pt ); ++position; } } } if( position >= 2) { ImageType::Pointer ITK_Full_Image = iImages->getImageITK( iImages->getChannelName(0)); itk::Vector spacing = ITK_Full_Image->GetSpacing(); // work on smaller region // increase size of bounding box by 20*spacing... bug itk? for(unsigned int i = 0; iITKExtractROI< PixelType, Dimension >( bounds, ITK_Full_Image); SplitterType::Pointer filter = SplitterType::New(); // size_t nb_ch = iImages->getNumberOfChannels(); filter->SetNumberOfImages( 1 ); filter->SetMesh( iPolyData[0] ); filter->SetFeatureImage( 0, ITK_ROI_Image); filter->SetSeeds( seeds ); filter->Update(); oVector = filter->GetOutputs(); } return oVector; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.cxx0000644000175000017500000003430411667757442024401 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSegmentationAlgo.h" // Extract ROI #include "vtkExtractVOI.h" // extract polydata 2d #include "vtkMarchingSquares.h" //reorder contour #include "vtkStripper.h" #include "vtkCellArray.h" // extract polydata 3d #include "vtkContourFilter.h" #include "vtkFeatureEdges.h" #include "vtkFillHolesFilter.h" #include "vtkPolyDataConnectivityFilter.h" #include "vtkWindowedSincPolyDataFilter.h" #include "vtkMath.h" // Decimation 2d #include "vtkPolylineDecimation.h" // Decimation 3d #include "vtkDecimatePro.h" // test code #include QGoSegmentationAlgo::QGoSegmentationAlgo(QWidget *iParent) : QObject( iParent ), m_Decimate(true), m_NumberOfPoints(100), m_AlgoWidget(NULL) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoSegmentationAlgo::~QGoSegmentationAlgo() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoAlgorithmWidget* QGoSegmentationAlgo::GetAlgoWidget() { return this->m_AlgoWidget; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoSegmentationAlgo::VTKExtractROI( const std::vector& iBounds, const std::vector< vtkSmartPointer< vtkImageData > > & iImages) { assert( iBounds.size() == 6 ); // vector to be returned std::vector listOfImages; //iterator on the images std::vector< vtkSmartPointer< vtkImageData > >::const_iterator it = iImages.begin(); while( it != iImages.end()) { listOfImages.push_back( VTKExtractROI(iBounds, *it) ); ++it; } return listOfImages; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- vtkImageData* QGoSegmentationAlgo:: VTKExtractROI(const std::vector& iBounds, const vtkSmartPointer< vtkImageData > & iImage) { // make sure there assert( iBounds.size() == 6 ); double org[3]; iImage->GetOrigin( org ); double spacing[3]; iImage->GetSpacing( spacing ); std::vector< int > bounds_idx(6); int k = 0; for( int i = 0; i < 3; i++ ) { bounds_idx[k] = vtkMath::Round( ( iBounds[k] - org[i] ) / spacing[i] ); ++k; bounds_idx[k] = vtkMath::Round( ( iBounds[k] - org[i] ) / spacing[i] ); ++k; } vtkSmartPointer extractVOI = vtkSmartPointer::New(); extractVOI->SetInput( iImage ); extractVOI->SetVOI( bounds_idx[0], bounds_idx[1], bounds_idx[2], bounds_idx[3], bounds_idx[4], bounds_idx[5]); extractVOI->Update(); vtkImageData* temp_image = vtkImageData::New(); temp_image->DeepCopy( extractVOI->GetOutput() ); return temp_image; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector QGoSegmentationAlgo:: ExtractPolyData( std::vector& iInputImage, const double & iThreshold) { // vector to be returned std::vector listOfPolys; //iterator on the images std::vector::iterator it = iInputImage.begin(); while( it != iInputImage.end()) { vtkPolyData* extractedPolyData = ExtractPolyData(*it, iThreshold); if( extractedPolyData ) { listOfPolys.push_back( extractedPolyData ); } ++it; } return listOfPolys; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: ExtractPolyData(vtkImageData *iInputImage, const double & iThreshold) { // make sure there is an image assert( iInputImage ); // test dimension of the input int extent[6]; iInputImage->GetExtent( extent ); int dimension = 3; for( int i = 0; i < 3; i++ ) { if( extent[2*i] == extent[2*i+1] ) { --dimension; } } switch ( dimension ) { case 2 : return ExtractContour( iInputImage, iThreshold); case 3 : return ExtractMesh( iInputImage, iThreshold); default : std::cout << "dimension unknown (Reconstruct polydata)" << std::endl; } return NULL; } //------------------------------------------------------------------------- /* * \todo Nicolas-do a better reconstruction.. */ //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: ExtractContour( vtkSmartPointer iInputImage, const double & iThreshold) { // create iso-contours vtkSmartPointer contours = vtkSmartPointer::New(); contours->SetInput(iInputImage); contours->GenerateValues (1, iThreshold, iThreshold); contours->Update(); return ReorganizeContour( contours->GetOutput() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: ReorganizeContour(vtkSmartPointer iInputImage) { /* * \note Nicolas-to be enhanced */ // Create reorganize contours vtkStripper *stripper = vtkStripper::New(); stripper->SetInput(iInputImage); //Is it useful?? Which number is the best suited? stripper->SetMaximumLength(999); stripper->Update(); // Reorder points stripper->GetOutput()->GetLines()->InitTraversal(); // npts = nb of points in the line // *pts = pointer to each point vtkIdType *pts = NULL; vtkIdType npts = 0; stripper->GetOutput()->GetLines()->GetNextCell(npts, pts); vtkPoints *points = vtkPoints::New(); vtkCellArray *lines = vtkCellArray::New(); vtkIdType * lineIndices = new vtkIdType[static_cast< int >( npts + 1 )]; for ( int k = 0; k < static_cast< int >( npts ); k++ ) { points->InsertPoint( k, stripper->GetOutput()->GetPoints()->GetPoint(pts[k]) ); lineIndices[k] = k; } lineIndices[static_cast< int >( npts )] = 0; lines->InsertNextCell(npts + 1, lineIndices); delete[] lineIndices; vtkSmartPointer output = vtkSmartPointer::New(); output->SetPoints(points); output->SetLines(lines); lines->Delete(); points->Delete(); stripper->Delete(); vtkPolyData* output2 = vtkPolyData::New(); output2->DeepCopy(output); return output2; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: ExtractMesh(vtkSmartPointer iInputImage, const double & iThreshold) { vtkSmartPointer< vtkContourFilter > contours = vtkSmartPointer< vtkContourFilter >::New(); contours->SetInput(iInputImage); contours->SetComputeGradients(0); contours->SetComputeNormals(0); contours->SetComputeScalars(0); contours->SetNumberOfContours(1); contours->SetValue(0, iThreshold); contours->Update(); std::cout << "Number Of Points: " << iInputImage->GetNumberOfPoints() << std::endl; vtkSmartPointer< vtkFeatureEdges > feature = vtkSmartPointer< vtkFeatureEdges >::New(); feature->SetInputConnection( contours->GetOutputPort() ); feature->BoundaryEdgesOn(); feature->FeatureEdgesOff(); feature->NonManifoldEdgesOn(); feature->ManifoldEdgesOff(); feature->Update(); vtkSmartPointer< vtkFillHolesFilter > fillFilter = vtkSmartPointer< vtkFillHolesFilter >::New(); vtkSmartPointer< vtkPolyDataConnectivityFilter > connectivityFilter = vtkSmartPointer< vtkPolyDataConnectivityFilter >::New(); connectivityFilter->SetExtractionModeToLargestRegion(); if ( feature->GetOutput()->GetNumberOfCells() > 0 ) { // fill holes if any! fillFilter->SetInputConnection( contours->GetOutputPort() ); fillFilter->Update(); connectivityFilter->SetInputConnection( fillFilter->GetOutputPort() ); } else { connectivityFilter->SetInputConnection( contours->GetOutputPort() ); } // keep the largest region connectivityFilter->Update(); /* * \note Nicolas-Smoother not connected */ /* unsigned int smoothingIterations = 15; double passBand = 0.001; double featureAngle = 120.0; // smoothing vtkSmartPointer< vtkWindowedSincPolyDataFilter > smoother = vtkSmartPointer< vtkWindowedSincPolyDataFilter >::New(); smoother->SetInputConnection( connectivityFilter->GetOutputPort() ); smoother->SetNumberOfIterations( smoothingIterations ); smoother->BoundarySmoothingOff(); smoother->FeatureEdgeSmoothingOff(); smoother->SetFeatureAngle(featureAngle); smoother->SetPassBand(passBand); smoother->NonManifoldSmoothingOn(); smoother->NormalizeCoordinatesOn(); smoother->Update(); */ vtkPolyData* output = vtkPolyData::New(); output->DeepCopy( connectivityFilter->GetOutput() ); return output; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: DecimatePolyData( vtkSmartPointer& iPolyData, const unsigned int& iNumberOfPoints) { // make sure there is a polydata assert( iPolyData ); /* * \todo Nicolas-might be better solution to test dimension of a PolyData */ // test dimension of the input double* bounds = iPolyData->GetBounds(); int dimension = 3; for( int i = 0; i < 3; i++ ) { if( bounds[2*i] == bounds[2*i+1] ) { --dimension; } } switch ( dimension ) { case 2 : return DecimateContour( iPolyData, iNumberOfPoints); case 3 : return DecimateMesh( iPolyData, iNumberOfPoints); default : itkGenericExceptionMacro( << "dimension unknown (Reconstruct polydata)" ); } return NULL; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: DecimateContour( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints) { // define target reduction unsigned int numberOfPoints = iPolyData->GetNumberOfPoints(); double target = 1 - (double)iNumberOfPoints/(double)numberOfPoints; vtkSmartPointer decimator = vtkSmartPointer::New(); decimator->SetInput(iPolyData); decimator->SetTargetReduction(target); decimator->Update(); return decimator->GetOutput(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkSmartPointer QGoSegmentationAlgo:: DecimateMesh( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints) { // define target reduction unsigned int numberOfPoints = iPolyData->GetNumberOfPoints(); double target = 1 - (double)iNumberOfPoints/(double)numberOfPoints; vtkSmartPointer decimator = vtkSmartPointer::New(); decimator->SetInput(iPolyData); decimator->SetTargetReduction(target); decimator->Update(); /* * \todo Nicolas-fill holes -smooth..? */ return decimator->GetOutput(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoSegmentationAlgo:: SetDecimate(bool& iDecimate) { m_Decimate = iDecimate; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool QGoSegmentationAlgo:: GetDecimate() { return m_Decimate; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoSegmentationAlgo:: SetNumberOfPoints( const unsigned int& iNumberOfPoints) { m_NumberOfPoints = iNumberOfPoints; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- unsigned int QGoSegmentationAlgo:: GetNumberOfPoints() const { return m_NumberOfPoints; } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoContourManualSegmentation.cxx0000644000175000017500000001163511667757442026310 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoContourManualSegmentation.h" #include "QGoContourManualSegmentationWidget.h" #include "QGoManualSegmentationSettingsDialog.h" //-------------------------------------------------------------------------- QGoContourManualSegmentation::QGoContourManualSegmentation(QWidget *iParent) : QObject(iParent), m_LinesWidth(2.), m_LinesColor(Qt::magenta), m_NodesColor(Qt::yellow), m_ActiveNodesColor(Qt::cyan), m_ReeditMode(false) { m_ContourSegmentationWidget = new QGoContourManualSegmentationWidget(iParent); QObject::connect( m_ContourSegmentationWidget, SIGNAL( UpdateContourRepresentationProperties() ), this, SLOT( GenerateContourRepresentationProperties() ) ); QObject::connect( m_ContourSegmentationWidget, SIGNAL( ValidatePressed() ), this, SIGNAL( validateContour() ) ); QObject::connect( m_ContourSegmentationWidget, SIGNAL( ReinitializePressed() ), this, SIGNAL( reinitializeContour() ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoContourManualSegmentation:: ~QGoContourManualSegmentation() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QWidget * QGoContourManualSegmentation::getWidget() { return m_ContourSegmentationWidget; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoContourManualSegmentation::GenerateContourRepresentationProperties(bool iModified) { bool haschanged = iModified; double temp = m_ContourSegmentationWidget->m_SettingsDialog->GetLineWidth(); if ( m_LinesWidth != temp ) { m_LinesWidth = temp; haschanged = true; } QColor temp_color = m_ContourSegmentationWidget->m_SettingsDialog->GetLineColor(); if ( m_LinesColor != temp_color ) { m_LinesColor = temp_color; haschanged = true; } temp_color = m_ContourSegmentationWidget->m_SettingsDialog->GetNodeColor(); if ( m_NodesColor != temp_color ) { m_NodesColor = temp_color; haschanged = true; } temp_color = m_ContourSegmentationWidget->m_SettingsDialog->GetActivatedNodeColor(); if ( m_ActiveNodesColor != temp_color ) { m_ActiveNodesColor = temp_color; haschanged = true; } if ( haschanged ) { emit changeContourRepresentationProperty( static_cast< float >( m_LinesWidth ), m_LinesColor, m_NodesColor, m_ActiveNodesColor); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoContourManualSegmentation::SetReeditMode(bool iReeditMode) { m_ReeditMode = iReeditMode; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool QGoContourManualSegmentation::GetReeditMode() { return m_ReeditMode; } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoAlgorithmWidget.h0000644000175000017500000000657711667757442023673 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoAlgorithmWidget_h #define __QGoAlgorithmWidget_h #include #include #include #include #include #include #include "ctkCollapsibleGroupBox.h" #include "QGoAlgoParameter.h" /** * \class QGoAlgorithmWidget * \ingroup GUI * \brief */ class QGoAlgorithmWidget: public QWidget { Q_OBJECT public: explicit QGoAlgorithmWidget(std::string iMethodName, QWidget *iParent = 0); ~QGoAlgorithmWidget(); /** \brief \return the name of the algorithms */ std::string GetMethodName(); /** \brief add the Advanced parameters box if there are parameters inside and reduce it before showing the widget */ void show(); template void AddParameter(QGoAlgoParameter* iParameter) { if (iParameter->m_AdvParam) { this->m_AdvParamLayout->addRow(tr("%1:").arg(iParameter->m_ParamName.c_str() ), iParameter->m_Box); } else { this->m_ParamLayout->addRow(tr("%1:").arg(iParameter->m_ParamName.c_str() ), iParameter->m_Box); } } /** \brief method called by the QGoAlgoManagerWidget when the apply button is clicked, emit the signal applyAlgo() */ void EmitApplyAlgo(); signals: void ApplyAlgo(); protected: QVBoxLayout* m_VBoxLayout; std::string m_MethodName; QFormLayout* m_ParamLayout; QFormLayout* m_AdvParamLayout; bool m_AdvParamAlreadySetUp; void Initialize(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoAlgorithmsManagerWidget.h0000644000175000017500000001221211667757442025330 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoAlgorithmsManagerWidget_h #define __QGoAlgorithmsManagerWidget_h #include #include #include #include #include #include #include #include #include #include "QGoAlgorithmWidget.h" /** * \class QGoAlgorithmsManagerWidget * \ingroup GUI * \brief manages all the algorithms widget for a same mode, has a combobox with the name of the methods which display a different QGoAlgorithmWidget depending on the method selected in the combobox */ class QGoAlgorithmsManagerWidget: public QWidget { Q_OBJECT public: explicit QGoAlgorithmsManagerWidget(std::string iModeName, QWidget *iParent = 0, std::vector iVectChannels = std::vector(), QStringList iListTime = QStringList(), bool iOnlyOneMethod = false, bool NeedApplyResetButton = true); ~QGoAlgorithmsManagerWidget(); /** \brief add a widget in the stacked layout with the name of the method associated in the combobox to display it, including the parameters and the advanced parameters displayed in an expandable box \param[in] iAlgoWidget widget with all the parameters for the algorithm */ void AddMethod(QGoAlgorithmWidget* iAlgoWidget); /** \brief add the widget in the stacked_widgets and hide the methodcombobox as there will be only one method in this algomanagerwidget */ void AddWidgetForOnlyOneMethod(QWidget* iWidget); /** \brief set the current index in the combobox to iIndex and get the corresponding widget to display \param[in] iIndex index to be displayed as the current one */ void SetCurrentIndex(int iIndex); void SetCurrentChannel(QString iChannel); void SetTSliceForClassicView(QString iTimePoint); void SetTSliceForDopplerView( QHash iListTimePoints, int iIndexChannel); /** \brief return the name of the mode \return the name of the mode */ std::string GetModeName(); /** \brief return true if it has at least one QGoAlgorithmWidget in the stackedWidgets \return false if there is no algorithm */ bool HasMethod(); /** \brief return the number of the selected channel */ std::string GetCurrentImageName(); int GetSelectedTimePoint(); bool IsInvertChecked(); signals: void ResetClicked(); void InvertChecked(Qt::CheckState); protected: QVBoxLayout* m_VBoxLayout; QComboBox* m_MethodComboBox; QStackedWidget* m_MethodWidgets; std::string m_ModeName; QComboBox* m_ChannelComboBox; QComboBox* m_TimeComboBox; QStringList m_ListTimePoints; QLabel* m_MethodLabel; QCheckBox* m_InvertBox; /** \brief add the different widgets, buttons and fill the comboboxes for channel and timepoint \param[in] iListChannels list of the names of the channels \param[in] iListTime list of the timepoints */ void Initialize(std::vector iVectChannels = std::vector(), QStringList iListTime = QStringList(), bool iOnlyOneMethod = false, bool NeedApplyResetButton = true); protected slots: /** \brief after button clicked signal is emitted, get the current widget of the stackedwidgets and call the method in QGoAlgoWidget to make it emit a signal */ void EmitApplyAlgo(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoContourManualSegmentationWidget.cxx0000644000175000017500000000651711667757442027457 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoContourManualSegmentationWidget.h" #include #include "QGoManualSegmentationSettingsDialog.h" //---------------------------------------------------------------------------// QGoContourManualSegmentationWidget::QGoContourManualSegmentationWidget(QWidget *iParent) : QWidget(iParent) { this->setupUi(this); m_SettingsDialog = new QGoManualSegmentationSettingsDialog(this); QObject::connect( this->ReinitializeBtn, SIGNAL( pressed() ), this, SIGNAL( ReinitializePressed() ) ); QObject::connect( this->ValidateBtn, SIGNAL( pressed() ), this, SIGNAL( ValidatePressed() ) ); QObject::connect( this->SettingsBtn, SIGNAL( pressed() ), m_SettingsDialog, SLOT ( exec() ) ); QObject::connect( m_SettingsDialog, SIGNAL( accepted() ), this, SIGNAL( UpdateContourRepresentationProperties() ) ); // shortcuts this->ValidateBtn->setShortcut(tr("Ctrl + A", "Apply")); this->ValidateBtn->setShortcut(tr("A", "Apply")); this->ReinitializeBtn->setShortcut(tr("Ctrl + D", "Delete")); this->ReinitializeBtn->setShortcut(tr("D", "Delete")); this->SettingsBtn->setShortcut(tr("Ctrl + S", "Settings")); this->SettingsBtn->setShortcut(tr("S", "Settings")); } //---------------------------------------------------------------------------// //---------------------------------------------------------------------------// QGoContourManualSegmentationWidget:: ~QGoContourManualSegmentationWidget() { } //---------------------------------------------------------------------------// GoFigure2-v0.9.0/Code/GUI/lib/TraceEditing/QGoModesManagerWidget.h0000644000175000017500000001267711667757442024305 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoModesManagerWidget_h #define __QGoModesManagerWidget_h #include #include #include #include #include #include "QGoAlgorithmsManagerWidget.h" /** * \class QGoModesManagerWidget * \ingroup GUI * \brief widget that manages the different modes for the TraceEditingWidget, has a combobox with the mode names and a corresponging stackedWidgets which display the right widget according to the mode selected in the combobox, has semiautomatic and automatic default modes */ class QGoModesManagerWidget: public QWidget { Q_OBJECT public: explicit QGoModesManagerWidget(std::vector iVectChannels, QStringList iListTimePoints, QWidget *iParent = 0); ~QGoModesManagerWidget(); /** \brief add a widget in the StackedWidget with the mode name that will be added in the combobox. \param[in] iModeName name of the mode \param[in] iWidget widget that will be displayed when iModeName is selected \param[in] ModeNeedSeeds if true, a signal will be emitted everytime the mode name appear in the combobox */ void AddWidgetWithModeName (std::string iModeName, QWidget* iWidget, bool ModeNeedSeeds); /** \brief add a QGoAlgorithmsManagerWidget and set the default index of this algo widget to iDefaultIndex \param[in] iAlgoManagerWidget \param[in] iDefaultIndex default index for the algo widget */ void AddAlgoManagerWidget(QGoAlgorithmsManagerWidget* iAlgoManagerWidget, bool ModeNeedSeeds, int iDefaultIndex = 0); /** \brief add the iAlgoWidget directly in the QgoAlgomanager corresponding to the Semi Automatic mode \param[in] iAlgoWidget widget to be added for the parameters of the algo */ void AddAlgoWidgetForSemiAutomaticMode(QGoAlgorithmWidget* iAlgoWidget); /** \brief add the iAlgoWidget directly in the QgoAlgomanager corresponding to the Automatic mode \param[in] iAlgoWidget widget to be added for the parameters of the algo */ void AddAlgoWidgetForAutomaticMode(QGoAlgorithmWidget* iAlgoWidget); /** \brief create the "manual" mode and makes it correspond to the provided widget \param[in] iWidget widget to be added for the manual mode */ void AddWidgetForManualMode(QWidget* iWidget, QStringList iListTimePoint, bool ModeNeedSeeds); /** \brief return the number of the selected channel */ std::string GetCurrentImageName(); int GetSelectedTimePoint(); bool GetIsInvertedOn(); void SetTSliceForClassicViewInAllAlgoModes(int iTimePoint); void SetTSliceForDopplerViewInAllAlgoModes( QHash iListTimePoints, int iChannelNumber); /** \brief return the mode name currently selected in the combobox */ std::string GetCurrentModeName(); public slots: /** \brief set the right mode according to the combobox if iIndex is different than -1 and emit a signal to enable/disable the seeds interactor mode based on the name of the selected mode */ void SetTheRightMode(int iIndex = -1); signals: void SetSeedInteractorBehaviour(bool enable); void ResetClicked(); protected: QVBoxLayout* m_VBoxLayout; QComboBox* m_ModeComboBox; QStackedWidget* m_ModeWidgets; QGoAlgorithmsManagerWidget* m_SemiAutoAlgoManagerWidget; QGoAlgorithmsManagerWidget* m_AutoAlgoManagerWidget; QGoAlgorithmsManagerWidget* m_ManualModeManager; bool m_ModeAlreadyCleaned; QStringList m_ModesWhoNeedSeeds; void Initialize(std::vector iVectChannels, QStringList iListTimePoints); /** \brief check that there is something in the default modes, if not, remove the mode name from the combobox */ void CheckDefaultModes(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoTabElementBase.cxx0000644000175000017500000002213711667757442021413 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTabElementBase.h" #include #include #include #include #include #include #include //-------------------------------------------------------------------------- QGoTabElementBase::QGoTabElementBase(QWidget *iParent) : QMainWindow(iParent), m_StatusBar(NULL) //m_TracesActions(NULL), //m_TraceSettingsToolBar(NULL), { //this->m_TracesActions = new QGoToolBarStatus; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoTabElementBase::~QGoTabElementBase() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< QAction * > QGoTabElementBase::ViewActions() { return m_ViewActions; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< QAction * > QGoTabElementBase::ViewNoToolBarActions() { return this->m_ViewNoToolBarActions; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< QAction * > QGoTabElementBase::SegmentationActions() { return m_SegmentationActions; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< QAction * > QGoTabElementBase::ToolsActions() { return m_ToolsActions; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< QAction * > QGoTabElementBase::BookmarkActions() { return m_BookmarkActions; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //std::vector< QAction * > QGoTabElementBase::ModeActions() //{ // return m_ModeActions; //} //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //std::vector< QAction * > QGoTabElementBase::TracesActions() //QGoToolBarStatus* QGoTabElementBase::TracesActions() //{ // return m_TracesActions; //} ////-------------------------------------------------------------------------- ////-------------------------------------------------------------------------- //QGoTraceSettingsWidget* QGoTabElementBase::TraceSettingsWidget() //{ // return m_TraceSettingsWidgetForToolBar; //} ////-------------------------------------------------------------------------- ////-------------------------------------------------------------------------- //void QGoTabElementBase::SetTraceSettingsToolBar( // QToolBar* iToolBar) //{ // this->m_TraceSettingsToolBar = iToolBar; //} //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::list< QGoTabElementBase::QGoDockWidgetStatusPair > & QGoTabElementBase::DockWidget() { return m_DockWidgetList; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::list< QAction * > QGoTabElementBase::GetPluginActions() { return m_PluginActionList; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabElementBase::SetPluginActions(std::list< QAction * > iList) { m_PluginActionList = iList; } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabElementBase::CreateModeToolBar( QMenu* iMenu, QToolBar* iToolBar) { QActionGroup* ModeGroup = new QActionGroup(this); ModeGroup->setObjectName("ModeGroup"); this->m_ModeToolBar = new QGoToolBarStatus(iToolBar, iMenu, Qt::TopToolBarArea, true, true, this); //---------------------------------// // default mode // //---------------------------------// // Create/initialize the default action QAction *DefaultAction = new QAction(tr("Default"), this); DefaultAction->setShortcut(tr("1", "Default Mode")); DefaultAction->setObjectName("DefaultMode"); DefaultAction->setCheckable(true); DefaultAction->setChecked(true); QIcon DefaultIcon; DefaultIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/mouse-cursor.png") ), QIcon::Normal, QIcon::Off); DefaultAction->setIcon(DefaultIcon); ModeGroup->addAction(DefaultAction); // it also updates the interactor behaviour QObject::connect( DefaultAction, SIGNAL( toggled(bool) ), this, SLOT( DefaultInteractorBehavior(bool) ) ); this->m_ModeToolBar->m_VectorAction.push_back(DefaultAction); //---------------------------------// // Zoom mode // //---------------------------------// QAction *ZoomAction = new QAction(tr("Zoom"), this); ZoomAction->setShortcut(tr("Z", "Zoom Mode")); ZoomAction->setCheckable(true); ZoomAction->setChecked(false); QIcon ZoomIcon; ZoomIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/zoom.png") ), QIcon::Normal, QIcon::Off); ZoomAction->setIcon(ZoomIcon); ModeGroup->addAction(ZoomAction); this->m_ModeToolBar->m_VectorAction.push_back(ZoomAction); // it also updates the interactor behaviour QObject::connect( ZoomAction, SIGNAL( toggled(bool) ), this, SLOT( ZoomInteractorBehavior(bool) ) ); //---------------------------------// // Translate mode // //---------------------------------// QAction *TranslateAction = new QAction(tr("Translate"), this); TranslateAction->setShortcut(tr("T", "Translate Mode")); TranslateAction->setCheckable(true); TranslateAction->setChecked(false); QIcon TranslateIcon; TranslateIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/Hand.png") ), QIcon::Normal, QIcon::Off); TranslateAction->setIcon(TranslateIcon); ModeGroup->addAction(TranslateAction); this->m_ModeToolBar->m_VectorAction.push_back(TranslateAction); // it also updates the interactor behaviour QObject::connect( TranslateAction, SIGNAL( toggled(bool) ), this, SLOT( TranslateInteractorBehavior(bool) ) ); this->m_ToolBarList.push_back(this->m_ModeToolBar); } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabElementBase::CreateViewToolBar(QMenu* iMenu, QToolBar* iToolBar) { } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabElementBase::SetStatusBarPointer(QStatusBar *iStatusbar) { this->m_StatusBar = iStatusbar; } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< QGoToolBarStatus* > QGoTabElementBase::GetToolBarsStatus() { return this->m_ToolBarList; } GoFigure2-v0.9.0/Code/GUI/lib/TraceInfoStructure.h0000644000175000017500000000745711667757442021421 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __TraceInfoStructure_h #define __TraceInfoStructure_h #include "QGoTableWidget.h" #include "GoDBCollectionOfTraces.h" // #include "ContourMeshStructureHelper.h" #include struct TraceInfoStructure { std::string TraceName; std::string TraceNameID; std::string CollectionName; std::string CollectionNameID; std::string CollectionOf; std::string CollectionOfID; QGoTableWidget *Table; GoDBCollectionOfTraces *CollectionOfTraces; // ContourMeshStructureMultiIndexContainer *ListTracesInfoForVisu; TraceInfoStructure():Table(NULL), CollectionOfTraces(NULL)//, // ListTracesInfoForVisu(NULL) {} TraceInfoStructure(const std::string & iTraceName, QWidget *parent): Table(NULL), CollectionOfTraces(NULL)//, ListTracesInfoForVisu(NULL) { SetInfoStructure(iTraceName, parent); } ~TraceInfoStructure() { // Table has a parent that is supposed to delete it if ( Table ) { delete Table; } /* if ( ListTracesInfoForVisu ) { delete ListTracesInfoForVisu; }*/ if ( CollectionOfTraces ) { delete CollectionOfTraces; } } void SetInfoStructure(const std::string & iTraceName, QWidget *iParent) { TraceName = iTraceName; TraceNameID = iTraceName; TraceNameID += "ID"; if ( TraceName == "contour" ) { CollectionName = "mesh"; CollectionOf = "None"; } if ( TraceName == "mesh" ) { CollectionName = "track"; CollectionOf = "contour"; } if ( TraceName == "track" ) { CollectionName = "lineage"; CollectionOf = "mesh"; } if ( TraceName == "lineage" ) { CollectionName = "None"; CollectionOf = "mesh"; } CollectionNameID = CollectionName; CollectionNameID += "ID"; CollectionOfID = CollectionOf; CollectionOfID += "ID"; //CollectionOfTraces = new GoDBCollectionOfTraces(CollectionName, // TraceName); CollectionOfTraces = new GoDBCollectionOfTraces(); Table = new QGoTableWidget(iParent); } }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoNameDescriptionInputDialog.cxx0000644000175000017500000001031011667757442024012 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoNameDescriptionInputDialog.h" #include #include #include "QTextEditChild.h" QGoNameDescriptionInputDialog::QGoNameDescriptionInputDialog(QWidget *iParent, QString iEntityName) : QDialog(iParent) { this->setupUi(this); this->m_EntityName = iEntityName; this->setWindowTitle( tr("Create a %1").arg(this->m_EntityName) ); this->EntityLabel->setText( tr("new %1 you want to save:").arg(iEntityName) ); this->NameLineEdit->setMaxLength(45); this->m_DescriptionTextEdit = new QTextEditChild(this, 1000); this->formLayout->addRow("Description:", this->m_DescriptionTextEdit); QObject::connect( this->NameDescriptionButtonBox, SIGNAL( accepted() ), this, SLOT( ValidationRequested() ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoNameDescriptionInputDialog::~QGoNameDescriptionInputDialog() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string QGoNameDescriptionInputDialog::GetInputTextForName() { return this->NameLineEdit->text().toStdString(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string QGoNameDescriptionInputDialog::GetInputTextForDescription() { return this->m_DescriptionTextEdit->toPlainText().toStdString(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoNameDescriptionInputDialog::ValidationRequested() { if ( this->GetInputTextForName().empty() ) { QMessageBox msgBox; msgBox.setText( tr("Please enter the name for the %1 to add").arg(this->m_EntityName) ); msgBox.exec(); } else { emit NewNameDescription( this->GetInputTextForName(), this->GetInputTextForDescription() ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoNameDescriptionInputDialog::NameAlreadyExists() { QMessageBox msgBox; msgBox.setText( tr("This name already exists, please choose another one") ); msgBox.exec(); }GoFigure2-v0.9.0/Code/GUI/lib/QGoImageView.h0000644000175000017500000002051211667757442020075 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoImageView_h #define __QGoImageView_h #include #include "vtkSmartPointer.h" class vtkLookupTable; class vtkImageData; class vtkViewImage2D; class vtkViewImage2DCollection; class vtkImageActor; class vtkActor; class vtkPolyData; class vtkProperty; class vtkProp3D; class QVTKInteractor; // For the seed widget #include "vtkPoints.h" #include "vtkSeedRepresentation.h" class vtkSeedWidget; class vtkConstrainedPointHandleRepresentation; class vtkImageActorPointPlacer; // For the distance widget... class vtkDistanceWidget; // For the angle widget... class vtkAngleWidget; // For the contour widget class vtkContourWidget; class vtkOrientedGlyphContourRepresentation; class vtkDistanceRepresentation2D; #include "QGoGUILibConfigure.h" /** \class QGoImageView \brief Abstract class for the visualization of 3D Image represented by one vtkImageData*. */ class QGOGUILIB_EXPORT QGoImageView:public QWidget { Q_OBJECT public: /** \brief Default Constructor. */ explicit QGoImageView(QWidget *parent = 0); /** \brief Destructor. */ virtual ~QGoImageView(); /** \brief Set the image to displaid. */ virtual void SetImage(vtkImageData *iImage) = 0; /** \brief Get the displaid image.*/ vtkImageData * GetImage(); /** \brief Get Image Coordinates from World Coordinates. */ int *GetImageCoordinatesFromWorldCoordinates(double pos[3]); void Update(); void SetIntersectionLineWidth( const float& iWidth ); /** \brief Returns the interactor for one given view. */ virtual QVTKInteractor * GetInteractor(const int &) = 0; virtual void setupUi(QWidget *parent) = 0; virtual void retranslateUi(QWidget *parent) = 0; /** \brief Returns used background color by viewers. \param[out] r red \param[out] g green \param[out] b blue */ void GetBackgroundColor(double & r, double & g, double & b); /** \overload */ double * GetBackgroundColor(); /** * \brief * \param[in] iId * \return */ vtkViewImage2D * GetImageViewer(const int & iId); int GetNumberOfImageViewers(); virtual void RemoveActor(const int & iId, vtkActor *iActor); virtual void AddActor(const int & iId, vtkActor *iActor); // virtual std::vector< vtkQuadricLODActor* > /** * \brief Add contour with given property into the visualization. * \param[in] iDataset contour * \param[in] iProperty * \return vector of vtkActor rendered in each 2D viewer. */ virtual std::vector< vtkActor * > AddContour(vtkPolyData *iDataset, vtkProperty *iProperty = NULL); /** * \brief Use the default interactor style */ void DefaultMode(); /** * \brief Use the zoom interactor style */ void ZoomMode(); /** * \brief Use the pan interactor style */ void PanMode(); /** * \brief Use the contour picking mode */ void EnableContourPickingMode(); /** * \brief Reset collection Window level */ void ResetWindowLevel(); /** * \brief Set the lookup table in the collection */ void SetLookupTable(vtkLookupTable *iLut); /** * \brief Show/hide the scalar bar in the collection */ void ShowScalarBar(const bool &); /** * \brief Get the image actor */ vtkImageActor * GetImageActor(const int & iId); /** * \brief Invert visibility of the Spline Plane */ void ShowSplinePlane(); /** * \brief Interpolate the data for visualization */ void SetInterpolate(const int & val); virtual void ChangeCursorShape(QCursor iCursorShape) = 0; /** * \brief Initializae the distance widget */ void InitializeDistanceWidget(); void EnableDistanceWidget(bool iEnable); /** * \brief Initializae the angle widget */ void InitializeAngleWidget(); void EnableAngleWidget(bool iActive); /** * \brief Initializae the angle widget */ void InitializeContourWidget(); void EnableContourWidget(bool iActivate); void InitializeContourWidgetNodes(int iDir, vtkPolyData *iNodes); vtkPolyData * GetContourRepresentationAsPolydata(int iDir); vtkPolyData * GetContourRepresentationNodePolydata(int iDir); /** * \brief Initializae the seed widget */ void InitializeSeedWidget(); void EnableSeedWidget(bool iEnable); /* * \brief Get seeds ordered by view in a vector * \param iPoints vector of points containing the seeds */ void GetSeeds( std::vector& iPoints ); public slots: /** \brief Set background color for all views. \param[in] r red \param[in] g green \param[in] b blue */ void SetBackgroundColor(const double & r, const double & g, const double & b); /** \overload */ void SetBackgroundColor(double rgb[3]); /** \overload */ void SetBackgroundColor(const QColor & iColor); /** * \brief Show annotations in the collection */ void ShowAnnotations(); /** * \brief Clear all the seeds positions after using it. */ void ClearAllSeeds(); void UpdateContourRepresentationProperties(float linewidth, QColor linecolor, QColor nodecolor, QColor activenodecolor); void ReinitializeContourWidget(); /** * \brief Update only the visualization */ void UpdateRenderWindows(); protected: vtkViewImage2DCollection *m_Pool; vtkImageData * m_Image; // Seed Widget specific members std::vector< vtkSmartPointer< vtkSeedWidget > > m_SeedWidget; std::vector< vtkSmartPointer< vtkConstrainedPointHandleRepresentation > > m_Handle; std::vector< vtkSmartPointer< vtkSeedRepresentation > > m_SeedRep; // Distance Widget specific members std::vector< vtkSmartPointer< vtkDistanceWidget > > m_DistanceWidget; // std::vector< vtkSmartPointer< vtkDistanceRepresentation2D > > // m_DistanceRepresentation; // Angle widget specific members std::vector< vtkSmartPointer< vtkAngleWidget > > m_AngleWidget; // Contour Widget specific members std::vector< vtkSmartPointer< vtkContourWidget > > m_ContourWidget; std::vector< vtkSmartPointer< vtkOrientedGlyphContourRepresentation > > m_ContourRepresentation; float m_LinesWidth; QColor m_LinesColor; QColor m_NodesColor; QColor m_ActiveNodesColor; float m_IntersectionLineWidth; unsigned int m_SnapshotId; bool m_ShowAnnotations; bool m_ShowSplinePlane; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoToolBarStatus.cxx0000644000175000017500000001710711667757442021347 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoToolBarStatus.h" #include QGoToolBarStatus::QGoToolBarStatus(QWidget* iParent) : QObject(iParent), m_ToolBar(NULL), m_Menu(NULL), m_Area(Qt::TopToolBarArea), m_DefaultArea(Qt::TopToolBarArea), m_Visibility(true), m_Attached(true), m_Widget(NULL) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoToolBarStatus::QGoToolBarStatus(const QGoToolBarStatus & iS) : m_ToolBar(iS.m_ToolBar), m_Menu(iS.m_Menu), m_Area(iS.m_Area), m_DefaultArea(iS.m_Area), m_Visibility(iS.m_Visibility), m_Attached(iS.m_Attached), m_VectorAction(iS.m_VectorAction), m_Widget(iS.m_Widget) { this->setParent(iS.parent()); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoToolBarStatus::QGoToolBarStatus(Qt::ToolBarArea iArea, const bool & iVisibility, const bool & iAttached, QWidget* iParent) : QObject(iParent), m_ToolBar(NULL), m_Menu(NULL), m_Area(iArea), m_DefaultArea(iArea), m_Visibility(iVisibility), m_Attached(iAttached), m_Widget(NULL) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoToolBarStatus::QGoToolBarStatus(QToolBar* iToolBar, QMenu* iMenu, Qt::ToolBarArea iArea, const bool & iVisibility, const bool & iAttached, QWidget* iParent, QWidget* iWidget): QObject(iParent), m_ToolBar(iToolBar), m_Menu(iMenu), m_Area(iArea), m_Visibility(iVisibility), m_Attached(iAttached), m_Widget(iWidget) { if(m_Widget && m_ToolBar) { QAction* Action = this->m_ToolBar->addWidget(iWidget); Action->setVisible(true); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoToolBarStatus:: ~QGoToolBarStatus() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoToolBarStatus::SetArea(Qt::ToolBarArea iArea) { m_Area = iArea; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoToolBarStatus::SetVisibility(bool iVisibility) { m_Visibility = iVisibility; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoToolBarStatus::SetAttached(bool iAttached) { m_Attached = iAttached; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoToolBarStatus::SetUpToolBar() { //if (this->m_ToolBar) // { for ( std::vector< QAction * >::iterator it = this->m_VectorAction.begin(); it != this->m_VectorAction.end(); ++it ) { if (this->m_ToolBar) { this->m_ToolBar->addAction(*it); } if (this->m_Menu) { this->m_Menu->addAction(*it); } } if (this->m_Widget) { QAction* Action = this->m_ToolBar->addWidget(this->m_Widget); Action->setVisible(true); } if(this->m_ToolBar) { this->m_ToolBar->setVisible(this->m_Visibility); } if (!this->m_ToolBar && !this->m_Menu) { std::cout<<"initialize first the toolbar and/or the qmenu "; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoToolBarStatus::ClearToolBar() { if (this->m_ToolBar) { //this->Disconnect(); this->m_Visibility = this->m_ToolBar->isVisible(); //this->m_Area = this->m_ToolBar->geometry(); this->m_Attached = this->m_ToolBar->isFloating(); this->m_ToolBar->clear(); } if (this->m_Menu) { this->m_Menu->clear(); } if (!this->m_ToolBar && !this->m_Menu) { std::cout<<"initialize first the toolbar and the qmenu "; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoToolBarStatus::InitializeToolBarAndMenu(QToolBar* iToolBar, QMenu* iMenu) { this->m_ToolBar = iToolBar; this->m_Menu = iMenu; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /*void QGoToolBarStatus::Connect() { //QObject::connect( m_ToolBar, SIGNAL( dockLocationChanged(Qt::DockWidgetArea) ), // this, SLOT( SetArea(Qt::DockWidgetArea) ) ); // QObject::connect(m_ToolBar->toggleViewAction(), SIGNAL(toggled(bool) ), // this, SLOT(SetVisibility(bool) ) ); QObject::connect(m_ToolBar, SIGNAL(topLevelChanged (bool) ), this, SLOT( SetAttached(bool) ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoToolBarStatus::Disconnect() { if (this->m_ToolBar) { this->m_ToolBar->disconnect(this); this->m_ToolBar->toggleViewAction()->disconnect(this); } else { std::cout<<"initialize first the toolbar and the qmenu "; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } }*/ GoFigure2-v0.9.0/Code/GUI/lib/QGoTrackViewDockWidget.h0000755000175000017500000000556011667757442022075 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTrackViewDockWidget_h #define __QGoTrackViewDockWidget_h #include #include #include #include "QGoDockWidget.h" class QGoTrackViewDockWidget: public QGoDockWidget { Q_OBJECT public: explicit QGoTrackViewDockWidget(QWidget *iParent = 0); ~QGoTrackViewDockWidget(); public slots: void lineWidthValueChanged( double ); void Glyphs( bool ); void glyphValueChanged( double ); void Tubes( bool ); void tubeValueChanged( double ); void ColorCodeTracksByTime(bool); void ColorCodeTracksBySpeed(bool); void ColorCodeTracksByOriginalColor(bool); signals: void UpdateTracksRepresentation(const double&, const double&, const double&); void ChangeColorCode( const QString& ); protected: QCheckBox* m_glyph; QCheckBox* m_tube; QDoubleSpinBox* m_glyphSpinBox; QDoubleSpinBox* m_tubeSpinBox; QDoubleSpinBox* m_linewidthSpinBox; QRadioButton* m_time; QRadioButton* m_real; QRadioButton* m_speed; void SetUpUi(); void SetDoubleSpinBox(QDoubleSpinBox* iSpinBox, double Min, double Max, double Value); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoGUILibConfigure.h.in0000644000175000017500000000061211667757442021541 0ustar mathieumathieu#ifndef __QGoGUILibConfigure_h #define __QGoGUILibConfigure_h #include "vtkConfigure.h" #include /* Whether we are building shared libraries. */ #if defined ( WIN32 ) && defined ( GOFIGURE2_BUILD_SHARED_LIBS ) #if defined ( QGoGUI_EXPORT ) #define QGOGUILIB_EXPORT Q_DECL_EXPORT #else #define QGOGUILIB_EXPORT Q_DECL_IMPORT #endif #else #define QGOGUILIB_EXPORT #endif #endifGoFigure2-v0.9.0/Code/GUI/lib/QGoTabImageViewElementBase.cxx0000644000175000017500000003220111667757442023202 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTabImageViewElementBase.h" #include #include #include #include "vtkContourWidget.h" #include "vtkOrientedGlyphContourRepresentation.h" #include "vtkImageActorPointPlacer.h" #include "vtkPolyData.h" #include "vtkActor.h" #include "vtkProperty.h" #include "ContourContainer.h" #include "MeshContainer.h" #include "QGoNavigationDockWidget.h" #include "QGoContourManualSegmentationWidget.h" //-------------------------------------------------------------------------- /** * \brief Default Constructor * \param iParent */ QGoTabImageViewElementBase::QGoTabImageViewElementBase(QWidget *iParent) : QGoTabElementBase(iParent), m_Color(false), m_BackgroundColor(Qt::black), m_ContourId(0), m_ReEditContourMode(false), m_NavigationDockWidget(0) { /// \todo fix this m_ContourContainer = new ContourContainer(this, NULL); m_MeshContainer = new MeshContainer(this, NULL); CreateManualSegmentationdockWidget(); CreateToolsActions(); /// \todo fix it is not a dockwidget anymore //m_DockWidgetList.push_back( // std::pair( // new QGoDockWidgetStatus(m_ManualSegmentationWidget, // Qt::LeftDockWidgetArea, true, true), // m_ManualSegmentationWidget)); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * \brief Destructor */ QGoTabImageViewElementBase::~QGoTabImageViewElementBase() { } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- /** * \brief */ void QGoTabImageViewElementBase::CreateManualSegmentationdockWidget() { m_ManualSegmentationWidget = new QGoContourManualSegmentationWidget(this); QObject::connect( m_ManualSegmentationWidget, SIGNAL( ValidatePressed() ), this, SLOT( ValidateContour() ) ); QObject::connect( m_ManualSegmentationWidget, SIGNAL( ReinitializePressed() ), this, SLOT( ReinitializeContour() ) ); QObject::connect( m_ManualSegmentationWidget, SIGNAL( UpdateContourRepresentationProperties() ), this, SLOT( ChangeContourRepresentationProperty() ) ); // QAction* tempaction = m_ManualSegmentationWidget->toggleViewAction(); // this->m_SegmentationActions.push_back(tempaction); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageViewElementBase::ChangeContourRepresentationProperty() { float linewidth = static_cast< float >( m_LinesWidth ); QColor linecolor = m_LinesColor; QColor nodecolor = m_NodesColor; QColor activenodecolor = m_ActiveNodesColor; qreal rl, gl, bl; linecolor.getRgbF(&rl, &gl, &bl); qreal rn, gn, bn; nodecolor.getRgbF(&rn, &gn, &bn); qreal ra, ga, ba; activenodecolor.getRgbF(&ra, &ga, &ba); for ( unsigned int i = 0; i < m_ContourRepresentation.size(); i++ ) { m_ContourRepresentation[i]->GetLinesProperty()->SetLineWidth(linewidth); m_ContourRepresentation[i]->GetLinesProperty()->SetColor( static_cast< double >( rl ), static_cast< double >( gl ), static_cast< double >( bl ) ); m_ContourRepresentation[i]->GetProperty()->SetColor( static_cast< double >( rn ), static_cast< double >( gn ), static_cast< double >( bn ) ); m_ContourRepresentation[i]->GetActiveProperty()->SetColor( static_cast< double >( ra ), static_cast< double >( ga ), static_cast< double >( ba ) ); } } //------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param iColor */ void QGoTabImageViewElementBase::SetColor(const bool & iColor) { m_Color = iColor; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * \brief Write settings: * \li \c m_BackgroundColor */ void QGoTabImageViewElementBase::WriteSettings() { QSettings settings; settings.beginGroup("QGoTabImageViewElementBase"); settings.setValue("BackgroundColor", m_BackgroundColor); settings.endGroup(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * \brief Read settings: * \li \c m_BackgroundColor */ void QGoTabImageViewElementBase::ReadSettings() { QSettings settings; settings.beginGroup("QGoTabImageViewElementBase"); QVariant var = settings.value("BackgroundColor"); m_BackgroundColor = var.value< QColor >(); this->SetBackgroundColorToImageViewer(); settings.endGroup(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * \brief Change background color */ void QGoTabImageViewElementBase::ChangeBackgroundColor() { this->GetBackgroundColorFromImageViewer(); QColor temp = QColorDialog::getColor( m_BackgroundColor, this, tr("Choose Background Color") ); if ( temp.isValid() ) { if ( temp != m_BackgroundColor ) { m_BackgroundColor = temp; this->SetBackgroundColorToImageViewer(); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * \param[in] iActivate */ void QGoTabImageViewElementBase::ActivateManualSegmentationEditor(const bool & iActivate) { std::vector< vtkSmartPointer< vtkContourWidget > >::iterator it = m_ContourWidget.begin(); while ( it != m_ContourWidget.end() ) { if ( iActivate ) { ( *it )->On(); } else { ( *it )->Off(); } ++it; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * * @param[in] iId */ void QGoTabImageViewElementBase::ValidateContour(const int & iId) { vtkPolyData *contour = m_ContourRepresentation[iId]->GetContourRepresentationAsPolyData(); // get color from the dock widget double r, g, b, a; r = 0.1; g = 0.5; b = 0.7; a = 1.; vtkProperty *contour_property = vtkProperty::New(); contour_property->SetRepresentationToWireframe(); contour_property->SetColor(r, g, b); contour_property->SetOpacity(a); // Compute Bounding Box double bounds[6]; contour->GetBounds(bounds); // Extract Min and Max from bounds /* double Min[3]; double Max[3]; int k = 0; for ( int i = 0; i < 3; ++i ) { Min[i] = bounds[k++]; Max[i] = bounds[k++]; }*/ // *** Get the Bounding Box *** // int* min_idx = this->GetImageCoordinatesFromWorldCoordinates( Min ); // int* max_idx = this->GetImageCoordinatesFromWorldCoordinates( Max ); // (void) min_idx; // (void) max_idx; // **************************** vtkPolyData *contour_nodes = vtkPolyData::New(); m_ContourRepresentation[iId]->GetNodePolyData(contour_nodes); // get corresponding actor from visualization vtkPolyData *contour_copy = vtkPolyData::New(); contour_copy->ShallowCopy(contour); // std::vector< vtkQuadricLODActor* > contour_actor = std::vector< vtkActor * > contour_actor = this->AddContour(contour_copy, contour_property); contour_copy->Delete(); contour_property->Delete(); /// \todo use m_ContourMeshContainer here! // // get meshid from the dock widget (SpinBox) // // unsigned int meshid = m_ManualSegmentationWidget->GetMeshId(); // unsigned int meshid = 0; // // if( this->m_NavigationDockWidget->GetCurrentCollectionID() != -1 ) // { // meshid = // static_cast< unsigned int >( // this->m_NavigationDockWidget->GetCurrentCollectionID() ); // } // // unsigned int timepoint = 0; // bool highlighted = false; // // // fill the container // // for( unsigned int i = 0; i < contour_actor.size(); i++ ) // { // ContourMeshStructure temp( m_ContourId, contour_actor[i], contour_nodes, // meshid, // timepoint, highlighted, r, g, b, alpha, i ); // m_ContourMeshContainer.insert( temp ); // } // // m_ContourId++; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * */ void QGoTabImageViewElementBase::ValidateContour() { for ( unsigned int i = 0; i < m_ContourWidget.size(); i++ ) { ValidateContour(i); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /** * \brief Re-edit contour given by its id * \param iId */ void QGoTabImageViewElementBase::ReEditContour(const unsigned int & iId) { ContourMeshContainer::MultiIndexContainerTraceIDIterator it = m_ContourContainer->m_Container.get< TraceID >().find(iId); if ( it != m_ContourContainer->m_Container.get< TraceID >().end() ) { vtkPolyData *c_nodes = NULL; /// \todo remove actor from the visualization and update! // c_dir = (*it).Direction; // c_actor = (*it).Actor; // c_nodes = (*it).Nodes; // // RemoveActorFromViewer(c_dir, c_actor); m_ContourContainer->m_Container.erase(iId); if ( m_ContourWidget.size() > 1 ) { int dir = ContourMeshContainer::ComputeDirectionFromContour(c_nodes); if ( dir != -1 ) { m_ReEditContourMode = true; m_ContourId = iId; double p[3]; c_nodes->GetPoint(0, p); int *idx = this->GetImageCoordinatesFromWorldCoordinates(p); this->SetSlice(dir, idx); delete[] idx; m_ContourWidget[dir]->Initialize(c_nodes); m_ManualSegmentationWidget->setEnabled(true); } } else { m_ContourWidget[0]->Initialize(c_nodes); m_ManualSegmentationWidget->setEnabled(true); } } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageViewElementBase::ReinitializeContour() { for ( unsigned int i = 0; i < m_ContourWidget.size(); i++ ) { /// \todo to be fully compliant with more recent version of vtk, /// we should rather use m_ContourWidget[i]->Initialize() m_ContourWidget[i]->Initialize(NULL); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageViewElementBase::CreateToolsActions() { m_TakeSnapshotAction = new QAction(tr("Take Snapshot"), this); QIcon snapshoticon; snapshoticon.addPixmap(QPixmap( QString::fromUtf8(":/fig/camera-photo.png") ), QIcon::Normal, QIcon::Off); m_TakeSnapshotAction->setIcon(snapshoticon); m_TakeSnapshotAction->setStatusTip( tr("You have to be in full screen view to use the snapshot") ); m_TakeSnapshotAction->setEnabled(false); QObject::connect( m_TakeSnapshotAction, SIGNAL( triggered() ), this, SLOT( TakeSnapshot() ) ); this->m_ToolsActions.push_back(m_TakeSnapshotAction); } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/SnapshotHelper.h0000644000175000017500000000570011667757442020552 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __SnapshotHelper_h #define __SnapshotHelper_h class QString; class vtkRenderWindow; class vtkImageData; class QVTKWidget; class vtkViewImage2D; #include "GoFigureGlobalDefinition.h" //------------------------------------------------------------------------- bool BuildScreenshotFromImage(vtkImageData *image, vtkImageData *screenshot, int tsize = 0); //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool BuildScreenshotFromRenderWindow( vtkRenderWindow *win, vtkImageData *screenshot, int tsize = 0); //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString SnapshotView(QVTKWidget *iWidget, const GoFigure::FileType & iType, const QString & iBaseName, const unsigned int & iSnapshotId); //------------------------------------------------------------------------- void SetupViewGivenQVTKWidget(vtkViewImage2D *iView, QVTKWidget *iWidget); #endif GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/0000755000175000017500000000000011667757442021135 5ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedView2D.cxx0000644000175000017500000001463511667757442026001 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSynchronizedView2D.h" #include "QGoSynchronizedView2DCallbacks.h" #include "vtkImageData.h" #include "vtkViewImage2D.h" #include "vtkEventQtSlotConnect.h" #include "SnapshotHelper.h" #include "QGoImageView2D.h" #include "QGoSynchronizedViewManager.h" #include "itkImageToVTKImageFilter.h" #include "itkSmartPointer.h" #include "itkImage.h" //-------------------------------------------------------------------------- /* * Default Constructor. * \param iSynchronizedViewName * \param iParent */ QGoSynchronizedView2D::QGoSynchronizedView2D(QString iViewName, QWidget *iParent) : QGoSynchronizedView(iViewName, iParent), m_View (NULL) { } //-------------------------------------------------------------------------- QGoSynchronizedView2D:: ~QGoSynchronizedView2D() { // remove the comparer from the manager if ( m_ViewManager != NULL ) { m_ViewManager->removeSynchronizedView2D(this); m_ViewManager = NULL; } // delete the view if any if ( HasViewer() ) { deleteViewer(); } } //-------------------------------------------------------------------------- /* Print self informations */ void QGoSynchronizedView2D::PrintOs(ostream & os) { // if we have an imageview, the we print its image information if ( m_Image ) { os << "SynchronizedView 2D " << this << " contains :" << std::endl; m_Image->Print(os); } else { os << "SynchronizedView 2D " << this << " contains no Image :" << std::endl; } } //-------------------------------------------------------------------------- /* Update the viewer contained in the widget */ void QGoSynchronizedView2D::Update() { if ( m_View ) { this->m_View->Update(); // in addition to standard parameters, we don't want to interpolate data this->m_View->SetInterpolate(0); } } //-------------------------------------------------------------------------- /* render the viewer contained in the widget if any */ void QGoSynchronizedView2D::Render() { if ( m_View ) { m_View->GetImageViewer(0)->Render(); } } //-------------------------------------------------------------------------- /* get the camera of the viewer */ vtkCamera * QGoSynchronizedView2D::GetCamera() { if ( m_View ) { return m_View->GetImageViewer(0) ->GetRenderer() ->GetActiveCamera(); } else { return NULL; } } //-------------------------------------------------------------------------- /* true if the widget has a viewer */ bool QGoSynchronizedView2D::HasViewer() { return ( m_View != NULL ); } //-------------------------------------------------------------------------- /* returns the type of comparer (2 for 2D, 3 for 3D) */ int QGoSynchronizedView2D::GetSynchronizedViewType() { return 2; } //-------------------------------------------------------------------------- /* set the image to be displaid */ void QGoSynchronizedView2D::SetImage(vtkImageData *iImage) { if ( iImage ) { // if there is no viewer, we create one if ( !m_View ) { createViewer(); } // set the image to the view dynamic_cast< QGoImageView2D * >( m_View )->SetImage(iImage); // update image m_Image = iImage; this->Update(); } } // ######################################################################## // Private //-------------------------------------------------------------------------- /* delete the viewer contained in the widget */ void QGoSynchronizedView2D::deleteViewer() { // if there is no viewer if ( m_View ) { // delete object delete ( m_View ); // set pointer to NULL m_View = NULL; } } //-------------------------------------------------------------------------- // create the viewer contained in the widget void QGoSynchronizedView2D::createViewer() { // if there is already a viewer if ( !m_View ) { // else we create one QGoImageView2D *v = new QGoImageView2D(this); v->setContentsMargins(1, 1, 1, 1); // setup position of the widget this->gridLayout->addWidget(v); m_View = v; } } //-------------------------------------------------------------------------- QGoImageView2D * QGoSynchronizedView2D::GetImageView() { if ( HasViewer() ) { return dynamic_cast< QGoImageView2D * >( m_View ); } else { return NULL; } } //-------------------------------------------------------------------------- QString QGoSynchronizedView2D::SnapshotViewXY(const GoFigure::FileType & iType, const QString & iBaseName) { QGoImageView2D *viewer = GetImageView(); if ( viewer ) { return viewer->SnapshotViewXY(iType, iBaseName); } else { return QString(); } }GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedView.cxx0000644000175000017500000000762111667757442025610 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSynchronizedView.h" #include "vtkImageData.h" #include "vtkViewImage2D.h" #include "vtkEventQtSlotConnect.h" #include "SnapshotHelper.h" #include "QGoImageView2D.h" #include "QGoSynchronizedViewManager.h" //-------------------------------------------------------------------------- /* * Default Constructor. * \param iViewName * \param iParent */ QGoSynchronizedView::QGoSynchronizedView(QString iViewName, QWidget *iParent) : QWidget (iParent), m_ViewName (iViewName), m_Image (NULL), m_ViewManager (NULL) { setupUi(this); // the widget View is just for representing the place of the viewer // it is useless delete ( View ); gridLayout->setContentsMargins(1, 1, 1, 1); gridLayout->setSpacing(1); this->setWindowTitle(iViewName); this->resize(300, 300); } //-------------------------------------------------------------------------- QGoSynchronizedView:: ~QGoSynchronizedView() { } //-------------------------------------------------------------------------- void QGoSynchronizedView::changeEvent(QEvent *e) { QWidget::changeEvent(e); switch ( e->type() ) { case QEvent::LanguageChange: { retranslateUi(this); break; } default: break; } } ////-------------------------------------------------------------------------- ///* Set image displayed by the comparer //*/ ///* //void //QGoSynchronizedView:: //SetImage(vtkImageData* iImage) //{ // if (iImage == NULL) // { // return; // } // // // if there is no viewer, we create one // if (m_View == NULL) // { // createViewer(); // } // // // set the image to the view // m_View->SetImage(iImage); // // // update image // m_Image = iImage; // // this->Update(); //} //*/ //-------------------------------------------------------------------------- /* get comparer's name */ QString * QGoSynchronizedView::GetName() { return &m_ViewName; } //-------------------------------------------------------------------------- /* Set the address of the manager */ void QGoSynchronizedView::SetViewManager(QGoSynchronizedViewManager *iViewManager) { m_ViewManager = iViewManager; }GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedView3DCallbacks.cxx0000644000175000017500000003345011667757442027576 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSynchronizedView3DCallbacks.h" #include "QGoImageView3D.h" #include "QGoSynchronizedView3D.h" #include "vtkCommand.h" #include "vtkCallbackCommand.h" #include "vtkCamera.h" #include "vtkRenderer.h" #include "vtkSmartPointer.h" #include //-------------------------------------------------------------------------- QGoSynchronizedView3DCallbacks::QGoSynchronizedView3DCallbacks(std::vector< QGoSynchronizedView3D * > ioOpenSynchronizedViews, QObject *iParent) : QObject (iParent) { m_vtkCallBackCamSync.resize(4); // create the callback object SetupCallBack(); // for every opened SynchronizedView : std::vector< QGoSynchronizedView3D * >::iterator SynchronizedViewIt = ioOpenSynchronizedViews.begin(); while ( SynchronizedViewIt != ioOpenSynchronizedViews.end() ) { m_openSynchronizedView.push_back(*SynchronizedViewIt); if ( ( *SynchronizedViewIt )->HasViewer() ) // add the callback to the SynchronizedView's camera { for ( int i = 0; i < 4; i++ ) { ( *SynchronizedViewIt )->GetCamera(i) ->AddObserver(vtkCommand::ModifiedEvent, QGoSynchronizedView3DCallbacks:: m_vtkCallBackCamSync[i]); } // we connect the sliders to the synchronizer (monitor slider changes) : QObject::connect( ( *SynchronizedViewIt )->GetImageView(), SIGNAL( SliceViewXYChanged(int) ), this, SIGNAL( SliceViewXYChanged(int) ) ); QObject::connect( ( *SynchronizedViewIt )->GetImageView(), SIGNAL( SliceViewXZChanged(int) ), this, SIGNAL( SliceViewXZChanged(int) ) ); QObject::connect( ( *SynchronizedViewIt )->GetImageView(), SIGNAL( SliceViewYZChanged(int) ), this, SIGNAL( SliceViewYZChanged(int) ) ); // we connect the synchronizer to the SynchronizedView QObject::connect( this, SIGNAL( SliceViewXYChanged(int) ), ( *SynchronizedViewIt )->GetImageView(), SLOT( SetSliceViewXY(int) ) ); QObject::connect( this, SIGNAL( SliceViewXZChanged(int) ), ( *SynchronizedViewIt )->GetImageView(), SLOT( SetSliceViewXZ(int) ) ); QObject::connect( this, SIGNAL( SliceViewYZChanged(int) ), ( *SynchronizedViewIt )->GetImageView(), SLOT( SetSliceViewYZ(int) ) ); } ++SynchronizedViewIt; } } //-------------------------------------------------------------------------- // the destructor is very important here, we want to leave clean // SynchronizedViews behind QGoSynchronizedView3DCallbacks:: ~QGoSynchronizedView3DCallbacks() { std::vector< QGoSynchronizedView3D * >::iterator SynchronizedViewIt; // we remove the open synchronized SynchronizedViews while ( !m_openSynchronizedView.empty() ) { // remove (AND NOT DELETE, this is the Orchestra's business) // all pointers in the vector // We remove the observer if any if ( m_openSynchronizedView.back()->HasViewer() ) { // remove the callback object from each object's camera for ( int i = 0; i < 4; i++ ) { m_openSynchronizedView.back()->GetCamera(i) ->RemoveObserver(QGoSynchronizedView3DCallbacks:: m_vtkCallBackCamSync[i]); } } m_openSynchronizedView.pop_back(); } // we can now delete the callbacks ! for ( int i = 0; i < 4; i++ ) { m_vtkCallBackCamSync[i]->Delete(); } } //-------------------------------------------------------------------------- // this is the callback function : do deep copies to keep track of // the moving camera's position void QGoSynchronizedView3DCallbacks::synchronizeCameras0(vtkObject *caller, long unsigned int eventId, void *clientData, void *callData) { synchronizeCamera(0, caller, eventId, clientData, callData); } //-------------------------------------------------------------------------- // this is the callback function : do deep copies to keep track of // master's camera position // void QGoSynchronizedView3DCallbacks::synchronizeCameras1(vtkObject *caller, long unsigned int eventId, void *clientData, void *callData) { synchronizeCamera(1, caller, eventId, clientData, callData); } //-------------------------------------------------------------------------- // this is the callback function : do deep copies to keep track of // master's camera position void QGoSynchronizedView3DCallbacks::synchronizeCameras2(vtkObject *caller, long unsigned int eventId, void *clientData, void *callData) { synchronizeCamera(2, caller, eventId, clientData, callData); } //-------------------------------------------------------------------------- // this is the callback function : do deep copies to keep track of // master's camera position void QGoSynchronizedView3DCallbacks::synchronizeCameras3(vtkObject *caller, long unsigned int eventId, void *clientData, void *callData) { synchronizeCamera(3, caller, eventId, clientData, callData); } //-------------------------------------------------------------------------- void QGoSynchronizedView3DCallbacks::synchronizeCamera(int iCamera, vtkObject *caller, long unsigned int eventId, void *clientData, void *callData) { (void)eventId; (void)callData; // client data is a pointer to std::vector // so client data is a std::vector* // we get the p_m_QGoSynchronizedView3D array by the following cast : std::vector< QGoSynchronizedView3D * > p_m_QGoSynchronizedView3Ds = *static_cast< std::vector< QGoSynchronizedView3D * > * >( clientData ); // the observer are set on cameras, so that the caller is a vtk camera* vtkCamera *movedCamera = static_cast< vtkCamera * >( caller ); // for every opened SynchronizedView : std::vector< QGoSynchronizedView3D * >::iterator SynchronizedViewIt = p_m_QGoSynchronizedView3Ds.begin(); while ( SynchronizedViewIt != p_m_QGoSynchronizedView3Ds.end() ) { /* * To inspect : if we don't move even the non visible views, * the positionning is not correct when going back to quadview * solution => a reset camera taking reference at the last fullscreenview ? */ /* // if the SynchronizedView is visible and the modified camera is rendrered if ((*SynchronizedViewIt)->isVisible() && (((*SynchronizedViewIt)->GetFullScreenView() == 0) || ((*SynchronizedViewIt)->GetFullScreenView() == 1))) */ { // we copy the position of the moved camera // into each SynchronizedView's camera if ( ( ( *SynchronizedViewIt )->GetCamera(iCamera) ) && ( ( *SynchronizedViewIt )->GetCamera(iCamera) != movedCamera ) ) { ( *SynchronizedViewIt )->GetCamera(iCamera)->DeepCopy(movedCamera); // we render all SynchronizedViews ( *SynchronizedViewIt )->Render(iCamera); } } ++SynchronizedViewIt; } } //-------------------------------------------------------------------------- void QGoSynchronizedView3DCallbacks::SetupCallBack() { // create the callback object (connection event -> function ) for ( int i = 0; i < 4; i++ ) { m_vtkCallBackCamSync[i] = vtkCallbackCommand::New(); m_vtkCallBackCamSync[i]->SetClientData(&m_openSynchronizedView); } m_vtkCallBackCamSync[0]->SetCallback(QGoSynchronizedView3DCallbacks:: synchronizeCameras0); m_vtkCallBackCamSync[1]->SetCallback(QGoSynchronizedView3DCallbacks:: synchronizeCameras1); m_vtkCallBackCamSync[2]->SetCallback(QGoSynchronizedView3DCallbacks:: synchronizeCameras2); m_vtkCallBackCamSync[3]->SetCallback(QGoSynchronizedView3DCallbacks:: synchronizeCameras3); } //-------------------------------------------------------------------------- void QGoSynchronizedView3DCallbacks::removeSynchronizedView(QGoSynchronizedView3D *ioSynchronizedView) { if ( ioSynchronizedView ) // this should always be true { // We look for the SynchronizedView // in the vector of synchronized SynchronizedViews std::vector< QGoSynchronizedView3D * >::iterator SynchronizedViewIt = std::find(m_openSynchronizedView.begin(), m_openSynchronizedView.end(), ioSynchronizedView); if ( SynchronizedViewIt != m_openSynchronizedView.end() ) // if we found it { // remove the callback object from each object's camera for ( int i = 0; i < 4; i++ ) { ioSynchronizedView->GetCamera(i) ->RemoveObserver(QGoSynchronizedView3DCallbacks:: m_vtkCallBackCamSync[i]); } // we remove the SynchronizedView m_openSynchronizedView.erase(SynchronizedViewIt); } } } //-------------------------------------------------------------------------- void QGoSynchronizedView3DCallbacks::addSynchronizedView(QGoSynchronizedView3D *ioSynchronizedView) { if ( ioSynchronizedView ) // this should always be true { if ( ioSynchronizedView->HasViewer() ) // add the callback to the SynchronizedView's camera { m_openSynchronizedView.push_back(ioSynchronizedView); for ( int i = 0; i < 4; i++ ) { ioSynchronizedView->GetCamera(i) ->AddObserver(vtkCommand::ModifiedEvent, QGoSynchronizedView3DCallbacks:: m_vtkCallBackCamSync[i]); } // we connect the sliders to the synchronizer (monitor slider changes) : QObject::connect( ioSynchronizedView->GetImageView(), SIGNAL( SliceViewXYChanged(int) ), this, SIGNAL( SliceViewXYChanged(int) ) ); QObject::connect( ioSynchronizedView->GetImageView(), SIGNAL( SliceViewXZChanged(int) ), this, SIGNAL( SliceViewXZChanged(int) ) ); QObject::connect( ioSynchronizedView->GetImageView(), SIGNAL( SliceViewYZChanged(int) ), this, SIGNAL( SliceViewYZChanged(int) ) ); // we connect the synchronizer to the SynchronizedView QObject::connect( this, SIGNAL( SliceViewXYChanged(int) ), ioSynchronizedView->GetImageView(), SLOT( SetSliceViewXY(int) ) ); QObject::connect( this, SIGNAL( SliceViewXZChanged(int) ), ioSynchronizedView->GetImageView(), SLOT( SetSliceViewXZ(int) ) ); QObject::connect( this, SIGNAL( SliceViewYZChanged(int) ), ioSynchronizedView->GetImageView(), SLOT( SetSliceViewYZ(int) ) ); } else { std::cerr << "trying to synchronize a visualization object missing a QGoImageView" << std::endl; } } }GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedView2D.h0000644000175000017500000001151711667757442025422 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSynchronizedView2D_h #define __QGoSynchronizedView2D_h #include "itkImageToVTKImageFilter.h" #include "itkCastImageFilter.h" #include "itkSmartPointer.h" #include "itkImage.h" #include "QGoSynchronizedView.h" #include "SnapshotHelper.h" #include "vtkSmartPointer.h" class vtkCamera; class vtkImageData; class vtkEventQtSlotConnect; class QGoImageView2D; /** * \class QGoSynchronizedView2D * \brief class used to display a QWidget containing a two dimensional * a vtkimagedata* or an itkimage*. * QGoSynchronizedView2D provide the interface to synchronize cameras among * several GoSynchronizedView2D. */ class QGoSynchronizedView2D:public QGoSynchronizedView { // QT macro Q_OBJECT // itk typedef : // type of itk image for visualization typedef itk::Image< unsigned char, 2 > VisuImageType; // itk to vtk connector typdef typedef itk::ImageToVTKImageFilter< VisuImageType > itkvtkConnectorType; public: explicit QGoSynchronizedView2D(QString iViewName, QWidget *iParent = 0); ~QGoSynchronizedView2D(); /** \brief Set image displayed by the SynchronizedView */ void SetImage(vtkImageData *iImage); /** \brief Update the viewer contained in the widget */ void Update(void); /** \brief render the viewer contained in the widget if any */ void Render(void); /** \brief get the camera of the current viewer */ vtkCamera * GetCamera(void); /** \brief true if the widget has a viewer */ bool HasViewer(void); /** \brief Print self informations */ void PrintOs(ostream & os); /** \brief returns the type of SynchronizedView (2 for 2D, 3 for 3D) */ int GetSynchronizedViewType(void); /** \brief Set ITK image displayed by the SynchronizedView */ template< typename TPixel > void SetImage(typename itk::Image< TPixel, 2 >::Pointer iImage) { typedef itk::Image< TPixel, 2 > InputImageType; // we cast the input to have a known image to display typedef itk::CastImageFilter< InputImageType, VisuImageType > CastFilterType; typedef typename CastFilterType::Pointer CastFilterTypePointer; CastFilterTypePointer castITKFilter = CastFilterType::New(); m_itkvtkConnector = itkvtkConnectorType::New(); castITKFilter->SetInput(iImage); castITKFilter->Update(); m_itkvtkConnector->SetInput( castITKFilter->GetOutput() ); m_itkvtkConnector->Update(); SetImage( m_itkvtkConnector->GetOutput() ); Update(); } /** \brief Returns the imageview managed by this SynchronizedView */ QGoImageView2D * GetImageView(void); public slots: /** \brief Save a screenshot of the viewer's content */ QString SnapshotViewXY( const GoFigure::FileType & iType, const QString & iBaseName = tr("Snapshot") ); protected: /** delete the viewer contained in the widget */ void deleteViewer(void); /** \brief create the viewer contained in the widget */ void createViewer(void); QGoImageView2D * m_View; itkvtkConnectorType::Pointer m_itkvtkConnector; private: Q_DISABLE_COPY(QGoSynchronizedView2D); }; #endif // __QGoSynchronizedView2D_h GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedView.h0000644000175000017500000001067711667757442025242 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSynchronizedView_h #define __QGoSynchronizedView_h #include "SnapshotHelper.h" #include "vtkSmartPointer.h" #include "ui_QGoSynchronizedView.h" #include "itkImage.h" #include "QGoGUILibConfigure.h" class vtkCamera; class vtkImageData; class vtkEventQtSlotConnect; class QGoImageView; class QGoSynchronizedViewManager; /** * \class QGoSynchronizedView * \brief abstract class for QGoSynchronizedView2D and QGoSynchronizedView3D. * Those classes are used to display a QWidget containing a * a vtkImageData* or an itk::Image<>::Pointer. * They provide the interface to synchronize cameras. * \example GUI/lib/qgosynchronizedview2dtest.cxx */ class QGOGUILIB_EXPORT QGoSynchronizedView:public QWidget, protected Ui::QGoSynchronizedView { Q_OBJECT public: explicit QGoSynchronizedView(QString iViewName, QWidget *iParent = 0); /** \brief Destructor. */ virtual ~QGoSynchronizedView(); /** \brief Set image displayed by the SynchronizedView */ virtual void SetImage(vtkImageData *iImage) = 0; /** \brief Update the viewer contained in the widget */ virtual void Update(void) = 0; /** \brief Set the address of the QGoSynchronizedViewManager */ void SetViewManager(QGoSynchronizedViewManager *iViewManager); /** \brief get SynchronizedView's name */ QString * GetName(void); /** \brief render the viewer contained in the widget if any */ virtual void Render(void) = 0; /** \brief get the camera of the current viewer */ virtual vtkCamera * GetCamera(void) = 0; /** \brief true if the widget has a viewer */ virtual bool HasViewer(void) = 0; /** \brief print the SynchronizedView information : * it consists in the image information if any. */ virtual void PrintOs(ostream & os) = 0; /** \brief returns the type of SynchronizedView (2 for 2D, 3 for 3D) */ virtual int GetSynchronizedViewType(void) = 0; public slots: /** \brief Save a snapshot of the displaid view, in a iType file */ virtual QString SnapshotViewXY( const GoFigure::FileType & iType, const QString & iBaseName = tr("Snapshot") ) = 0; protected: QString m_ViewName; vtkImageData * m_Image; QString m_ImageName; QGoSynchronizedViewManager *m_ViewManager; vtkEventQtSlotConnect * m_VTKEventQtConnector; /** \brief Qt change event function */ void changeEvent(QEvent *e); /** delete the viewer contained in the widget */ virtual void deleteViewer(void) = 0; /** create the viewer contained in the widget */ virtual void createViewer(void) = 0; private: Q_DISABLE_COPY(QGoSynchronizedView); }; #endif //__QGoSynchronizedView_h GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedView2DCallbacks.cxx0000644000175000017500000001605611667757442027600 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSynchronizedView2DCallbacks.h" #include "QGoSynchronizedView.h" #include "vtkCommand.h" #include "vtkCallbackCommand.h" #include "vtkCamera.h" #include "vtkRenderer.h" #include "vtkSmartPointer.h" #include QGoSynchronizedView2DCallbacks::QGoSynchronizedView2DCallbacks( std::vector< QGoSynchronizedView2D * > iOpenSynchronizedViews, QObject *iParent) : QObject(iParent), m_vtkCallBackCamSync( NULL ) { Initialize( iOpenSynchronizedViews.begin(), iOpenSynchronizedViews.end() ); } //-------------------------------------------------------------------------- // the destructor is very important here, we want to leave clean // SynchronizedViews behind QGoSynchronizedView2DCallbacks:: ~QGoSynchronizedView2DCallbacks() { // we pop out the element of the vector until it is empty while ( !m_openSynchronizedView.empty() ) { // remove (AND NOT DELETE, this is the Manager's business) // all pointers in the vector // We remove the observer if any if ( m_openSynchronizedView.back()->HasViewer() ) { // remove the callback object from each object's camera m_openSynchronizedView.back()->GetCamera()->RemoveObserver( QGoSynchronizedView2DCallbacks:: m_vtkCallBackCamSync); } // we remove the SynchronizedView from the vector m_openSynchronizedView.pop_back(); } // we can now delete the callback ! m_vtkCallBackCamSync->Delete(); } //-------------------------------------------------------------------------- // this is the callback function : do deep copies to keep track of // master's camera position void QGoSynchronizedView2DCallbacks::synchronizeCameras(vtkObject *caller, long unsigned int eventId, void *clientData, void *callData) { (void)eventId; (void)callData; // client data is a pointer to std::vector // so client data is a std::vector* // we get the p_m_QGoSynchronizedView2D array by the following cast : std::vector< QGoSynchronizedView2D * > p_m_QGoSynchronizedViews = *static_cast< std::vector< QGoSynchronizedView2D * > * > ( clientData ); // the observer are set on cameras, so that the caller is a vtk camera* vtkCamera *movedCamera = static_cast< vtkCamera * >( caller ); // for every opened SynchronizedView : std::vector< QGoSynchronizedView2D * >::iterator SynchronizedViewIt = p_m_QGoSynchronizedViews.begin(); while ( SynchronizedViewIt != p_m_QGoSynchronizedViews.end() ) { // we copy the position of the moved camera into // each SynchronizedView's camera if ( ( ( *SynchronizedViewIt )->GetCamera() != NULL ) && ( ( *SynchronizedViewIt )->GetCamera() != movedCamera ) ) { ( *SynchronizedViewIt )->GetCamera()->DeepCopy(movedCamera); // we render all SynchronizedViews ( *SynchronizedViewIt )->Render(); } ++SynchronizedViewIt; } } //-------------------------------------------------------------------------- void QGoSynchronizedView2DCallbacks::SetupCallBack() { // create the callback object (connection event -> function ) m_vtkCallBackCamSync = vtkCallbackCommand::New(); m_vtkCallBackCamSync->SetCallback(QGoSynchronizedView2DCallbacks:: synchronizeCameras); m_vtkCallBackCamSync->SetClientData(&m_openSynchronizedView); } //-------------------------------------------------------------------------- void QGoSynchronizedView2DCallbacks::removeSynchronizedView(QGoSynchronizedView2D *ioSynchronizedView) { if ( ioSynchronizedView ) // this should always be true { // We look for the SynchronizedView in the vector // of synchronized SynchronizedViews std::vector< QGoSynchronizedView2D * >::iterator SynchronizedViewIt = std::find(m_openSynchronizedView.begin(), m_openSynchronizedView.end(), ioSynchronizedView); if ( SynchronizedViewIt != m_openSynchronizedView.end() ) // if we found it { if ( ioSynchronizedView->HasViewer() ) { // remove the callback object from each object's camera ioSynchronizedView->GetCamera() ->RemoveObserver(QGoSynchronizedView2DCallbacks:: m_vtkCallBackCamSync); } ( *SynchronizedViewIt ) = NULL; // we remove the SynchronizedView m_openSynchronizedView.erase(SynchronizedViewIt); } } } //-------------------------------------------------------------------------- void QGoSynchronizedView2DCallbacks::addSynchronizedView(QGoSynchronizedView2D *ioSynchronizedView) { if ( ioSynchronizedView ) // this should always be true { m_openSynchronizedView.push_back(ioSynchronizedView); // if this SynchronizedView has a viewer, we add an observer if ( ioSynchronizedView->HasViewer() ) { // add the callback to the SynchronizedView's camera ioSynchronizedView->GetCamera()->AddObserver( vtkCommand::ModifiedEvent, QGoSynchronizedView2DCallbacks::m_vtkCallBackCamSync); } else { std::cerr << "trying to synchronize a visualization object missing a QGoImageView" << std::endl; } } } GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedView3DCallbacks.h0000644000175000017500000001236411667757442027224 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoSynchronizedView3DCallbacks_h #define __GoSynchronizedView3DCallbacks_h #include "vtkCommand.h" #include "QGoSynchronizedView3D.h" class vtkCallbackCommand; class vtkObject; /** * \class QGoSynchronizedView3DCallbacks * \brief This object takes a list of QGoSynchronizedView and * synchronize their cameras by setting up callbacks. * It is recommended to let the * QGoSynchronizedViewManager deal * with SynchronizedView synchronization. */ class QGoSynchronizedView3DCallbacks:public QObject { /** QT macro for signals and slots. * we use signales and slots to synchronize the sliders * for choosing slice. */ Q_OBJECT public: /** \brief the constructor do most of the work : * add observers & callbacks to QGoSynchronizedViews of the vector */ QGoSynchronizedView3DCallbacks( std::vector< QGoSynchronizedView3D * > ioOpenSynchronizedViews, QObject *iParent = 0); ~QGoSynchronizedView3DCallbacks(); /** \brief callback function to synchornize cameras (has to be public) */ static void synchronizeCameras0(vtkObject *caller, long unsigned int eventId, void *clientData, void *callData); /** \brief callback function to synchornize cameras (has to be public) */ static void synchronizeCameras1(vtkObject *caller, long unsigned int eventId, void *clientData, void *callData); /** \brief callback function to synchornize cameras (has to be public) */ static void synchronizeCameras2(vtkObject *caller, long unsigned int eventId, void *clientData, void *callData); /** \brief callback function to synchornize cameras (has to be public) */ static void synchronizeCameras3(vtkObject *caller, long unsigned int eventId, void *clientData, void *callData); static void synchronizeCamera(int iCamera, vtkObject *caller, long unsigned int eventId, void *clientData, void *callData); /** \brief remove a QGoSynchronizedView3D from the vector of synchronized Managers * (this method takes care of removing the callback) */ void removeSynchronizedView(QGoSynchronizedView3D *ioSynchronizedView); /** \brief add a QGoSynchronizedView3D to the vector of synchronized Managers * (this method takes care of adding the callback) */ void addSynchronizedView(QGoSynchronizedView3D *ioSynchronizedView); signals: /** \brief signals for synchronizing sliders (gives current XYslice * of any changing QGoSynchronizedView) */ void SliceViewXYChanged(int oSlice); /** \brief signals for synchronizing sliders (gives current XZ slice * of any changing QGoSynchronizedView) */ void SliceViewXZChanged(int oSlice); /** \brief signals for synchronizing sliders (gives current YZ slice * of any changing QGoSynchronizedView) */ void SliceViewYZChanged(int oSlice); private: /** \brief setup the callback command object * (client data, called function...etc) */ void SetupCallBack(); /** callback object to link callback * function to QGoSynchronizedView's event */ std::vector< vtkCallbackCommand * > m_vtkCallBackCamSync; /** all open QGoSynchronizedView3D are stored in this array, * to transmit it to the callback function */ std::vector< QGoSynchronizedView3D * > m_openSynchronizedView; }; #endif // QGoSynchronizedView3D3DSYNC_H GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedViewManager.cxx0000644000175000017500000004046011667757442027101 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSynchronizedViewManager.h" #include "QGoSynchronizedView2D.h" #include "QGoSynchronizedView3D.h" #include "QGoSynchronizedView2DCallbacks.h" #include "QGoSynchronizedView3DCallbacks.h" #include //-------------------------------------------------------------------------- QGoSynchronizedViewManager::QGoSynchronizedViewManager(QObject *iParent) : QObject (iParent), m_Synchronizer (NULL), m_Synchronizer3D (NULL) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoSynchronizedViewManager:: ~QGoSynchronizedViewManager() { std::vector< QGoSynchronizedView2D * >::iterator SynchronizedViewIt; std::vector< QGoSynchronizedView3D * >::iterator SynchronizedView3DIt; QGoSynchronizedView2D * tempComp; QGoSynchronizedView3D * tempComp3D; // first we delete the synchronizer if any if ( m_Synchronizer != NULL ) { delete ( m_Synchronizer ); } if ( m_Synchronizer3D != NULL ) { delete ( m_Synchronizer3D ); } // and the we delete the SynchronizedViews2D SynchronizedViewIt = m_openSynchronizedViews.begin(); while ( !m_openSynchronizedViews.empty() ) { // delete all pointers in the vector tempComp = *SynchronizedViewIt; m_openSynchronizedViews.erase(SynchronizedViewIt); delete ( tempComp ); } // and the we delete the SynchronizedViews3D SynchronizedView3DIt = m_openSynchronizedViews3D.begin(); while ( !m_openSynchronizedViews3D.empty() ) { // delete all pointers in the vector tempComp3D = *SynchronizedView3DIt; m_openSynchronizedViews3D.erase(SynchronizedView3DIt); delete ( tempComp3D ); } } //-------------------------------------------------------------------------- QGoSynchronizedView * QGoSynchronizedViewManager::newSynchronizedView( QString iSynchronizedViewName, vtkImageData *iImage) { if ( iImage == NULL ) { return NULL; } int dim[3]; iImage->GetDimensions(dim); if ( ( dim[0] != 1 ) && ( dim[1] != 1 ) && ( dim[2] != 1 ) ) { return static_cast< QGoSynchronizedView * >( newSynchronizedView3D(iSynchronizedViewName, iImage) ); } else { return static_cast< QGoSynchronizedView * >( newSynchronizedView2D(iSynchronizedViewName, iImage) ); } } //-------------------------------------------------------------------------- // add a SynchronizedView to QGoSynchronizedViewManager's parent Object/Widget QGoSynchronizedView2D * QGoSynchronizedViewManager::newSynchronizedView2D(QString iSynchronizedViewName, vtkImageData *iImage) { if ( ( iSynchronizedViewName.isEmpty() ) || ( iImage == NULL ) ) { return NULL; } // we create a new SynchronizedView with the same parent windows as this QGoSynchronizedView2D *nSynchronizedView = new QGoSynchronizedView2D( iSynchronizedViewName, static_cast< QWidget * >( this->parent() ) ); // we add the vtkimage to it nSynchronizedView->SetImage(iImage); // we add the SynchronizedView to the list of open SynchronizedViews m_openSynchronizedViews.push_back(nSynchronizedView); // if we are synchronizing different SynchronizedViews if ( m_Synchronizer != NULL ) { // we tell the synchronizer to also synchronize the new SynchronizedView m_Synchronizer->addSynchronizedView(nSynchronizedView); } // tell the SynchronizedView who is his Manager nSynchronizedView->SetViewManager(this); return nSynchronizedView; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // add a SynchronizedView to QGoSynchronizedViewManager's parent Object/Widget QGoSynchronizedView3D * QGoSynchronizedViewManager::newSynchronizedView3D(QString iSynchronizedViewName, vtkImageData *iImage) { if ( ( iSynchronizedViewName.isEmpty() ) || ( iImage == NULL ) ) { return NULL; } // we create a new SynchronizedView with the same parent windows as this QGoSynchronizedView3D *nSynchronizedView = new QGoSynchronizedView3D( iSynchronizedViewName, static_cast< QWidget * >( this->parent() ) ); // we add the vtkimage to it nSynchronizedView->SetImage(iImage); // we add the SynchronizedView to the list of open SynchronizedViews m_openSynchronizedViews3D.push_back(nSynchronizedView); // if we are synchronizing different SynchronizedViews if ( m_Synchronizer3D != NULL ) { // we tell the synchronizer to also synchronize the new SynchronizedView m_Synchronizer3D->addSynchronizedView(nSynchronizedView); } // tell the SynchronizedView who is his Manager nSynchronizedView->SetViewManager(this); return nSynchronizedView; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // delete a SynchronizedView from QGoSynchronizedViewManager's parent // Object/Widget void QGoSynchronizedViewManager::deleteSynchronizedView2D(QGoSynchronizedView2D *ioSynchronizedView) { std::vector< QGoSynchronizedView2D * >::iterator SynchronizedViewIt; if ( ioSynchronizedView == NULL ) { return; } // We look for the SynchronizedView in the vector of synchronized // SynchronizedViews SynchronizedViewIt = std::find(m_openSynchronizedViews.begin(), m_openSynchronizedViews.end(), ioSynchronizedView); if ( SynchronizedViewIt == m_openSynchronizedViews.end() ) { return; } // if we are synchronizing different SynchronizedViews if ( m_Synchronizer != NULL ) { // we tell the synchronizer to remove the SynchronizedView m_Synchronizer->removeSynchronizedView(ioSynchronizedView); } ioSynchronizedView->close(); delete ioSynchronizedView; // we remove the SynchronizedView to the list of open SynchronizedViews m_openSynchronizedViews.erase(SynchronizedViewIt); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // delete a SynchronizedView from QGoSynchronizedViewManager's parent // Object/Widget void QGoSynchronizedViewManager::deleteSynchronizedView2D(const int & iIndex) { QGoSynchronizedView2D *tempComp; // if there is a problem acessing the SynchronizedView if ( m_openSynchronizedViews.at(iIndex) == NULL ) { return; } tempComp = m_openSynchronizedViews.at(iIndex); // if we are synchronizing different SynchronizedViews if ( m_Synchronizer != NULL ) { // we tell the synchronizer to remove the SynchronizedView m_Synchronizer->removeSynchronizedView(tempComp); } tempComp->close(); delete tempComp; // we remove the SynchronizedView to the list of open SynchronizedViews m_openSynchronizedViews.erase(m_openSynchronizedViews.begin() + iIndex); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // take a SynchronizedView out of the Manager lists, without deleting it. void QGoSynchronizedViewManager::removeSynchronizedView2D(QGoSynchronizedView2D *ioSynchronizedView) { if ( ioSynchronizedView == NULL ) { return; } std::vector< QGoSynchronizedView2D * >::iterator SynchronizedViewIt; // We look for the SynchronizedView in the vector of synchronized // SynchronizedViews SynchronizedViewIt = std::find(m_openSynchronizedViews.begin(), m_openSynchronizedViews.end(), ioSynchronizedView); // if we don't find it if ( SynchronizedViewIt == m_openSynchronizedViews.end() ) { return; } // if we are synchronizing SynchronizedViews if ( m_Synchronizer != NULL ) // we tell the synchronizer to remove the // SynchronizedView { m_Synchronizer->removeSynchronizedView(ioSynchronizedView); } ioSynchronizedView->close(); // we remove the SynchronizedView to the list of open SynchronizedViews m_openSynchronizedViews.erase(SynchronizedViewIt); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // delete a SynchronizedView from QGoSynchronizedViewManager's parent // Object/Widget void QGoSynchronizedViewManager::deleteSynchronizedView3D(QGoSynchronizedView3D *ioSynchronizedView) { std::vector< QGoSynchronizedView3D * >::iterator SynchronizedView3DIt; if ( ioSynchronizedView == NULL ) { return; } // We look for the SynchronizedView in the vector of synchronized // SynchronizedViews SynchronizedView3DIt = std::find(m_openSynchronizedViews3D.begin(), m_openSynchronizedViews3D.end(), ioSynchronizedView); // if we don't find it if ( SynchronizedView3DIt == m_openSynchronizedViews3D.end() ) { return; } // if we are synchronizing SynchronizedViews if ( m_Synchronizer3D != NULL ) { // we tell the synchronizer to remove the SynchronizedView m_Synchronizer3D->removeSynchronizedView(ioSynchronizedView); } ioSynchronizedView->close(); delete ioSynchronizedView; // we remove the SynchronizedView fromo the list of open SynchronizedViews m_openSynchronizedViews3D.erase(SynchronizedView3DIt); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // delete a SynchronizedView from QGoSynchronizedViewManager's parent // Object/Widget void QGoSynchronizedViewManager::deleteSynchronizedView3D(const int & iIndex) { QGoSynchronizedView3D *tempComp3D; // if there is a problem acessing the SynchronizedView if ( m_openSynchronizedViews3D.at(iIndex) == NULL ) { return; } tempComp3D = m_openSynchronizedViews3D.at(iIndex); // if we are synchronizing different SynchronizedViews if ( m_Synchronizer3D != NULL ) { // we tell the synchronizer to remove the SynchronizedView m_Synchronizer3D->removeSynchronizedView(tempComp3D); } tempComp3D->close(); delete tempComp3D; // we remove the SynchronizedView to the list of open SynchronizedViews m_openSynchronizedViews3D.erase(m_openSynchronizedViews3D.begin() + iIndex); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // take a SynchronizedView out of the Manager lists, without deleting it. void QGoSynchronizedViewManager::removeSynchronizedView3D(QGoSynchronizedView3D *ioSynchronizedView) { if ( ioSynchronizedView == NULL ) { return; } std::vector< QGoSynchronizedView3D * >::iterator SynchronizedView3DIt; // We look for the SynchronizedView in the vector of synchronized // SynchronizedViews SynchronizedView3DIt = std::find(m_openSynchronizedViews3D.begin(), m_openSynchronizedViews3D.end(), ioSynchronizedView); // if we don't find it if ( SynchronizedView3DIt == m_openSynchronizedViews3D.end() ) { return; } // if we are synchronizing different SynchronizedViews if ( m_Synchronizer3D != NULL ) { // we tell the synchronizer to remove the SynchronizedView m_Synchronizer3D->removeSynchronizedView(ioSynchronizedView); } ioSynchronizedView->close(); // we remove the SynchronizedView to the list of open SynchronizedViews m_openSynchronizedViews3D.erase(SynchronizedView3DIt); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // remove the synchronizer leaving the SynchronizedViews independent void QGoSynchronizedViewManager::unSynchronizeOpenSynchronizedViews() { if ( m_Synchronizer != NULL ) { delete ( m_Synchronizer ); } if ( m_Synchronizer3D != NULL ) { delete ( m_Synchronizer3D ); } m_Synchronizer = NULL; m_Synchronizer3D = NULL; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // synchronize all open SynchronizedViews void QGoSynchronizedViewManager::synchronizeOpenSynchronizedViews() { if ( m_Synchronizer == NULL ) { m_Synchronizer = new QGoSynchronizedView2DCallbacks(m_openSynchronizedViews); } if ( m_Synchronizer3D == NULL ) { m_Synchronizer3D = new QGoSynchronizedView3DCallbacks(m_openSynchronizedViews3D); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // true if the orchestra synchronizes copmarers bool QGoSynchronizedViewManager::isSynchronizing() { if ( ( m_Synchronizer != NULL ) || ( m_Synchronizer3D != NULL ) ) { return true; } else { return false; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // synchronize all open SynchronizedViews void QGoSynchronizedViewManager::Update() { std::vector< QGoSynchronizedView2D * >::iterator SynchronizedViewIt; // we update all SynchronizedViews for ( SynchronizedViewIt = m_openSynchronizedViews.begin(); SynchronizedViewIt != m_openSynchronizedViews.end(); ++SynchronizedViewIt ) { ( *SynchronizedViewIt )->Update(); } std::vector< QGoSynchronizedView3D * >::iterator SynchronizedView3DIt; // we update all SynchronizedViews for ( SynchronizedView3DIt = m_openSynchronizedViews3D.begin(); SynchronizedView3DIt != m_openSynchronizedViews3D.end(); ++SynchronizedView3DIt ) { ( *SynchronizedView3DIt )->Update(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //show all the SynchronizedViews void QGoSynchronizedViewManager::show() { std::vector< QGoSynchronizedView2D * >::iterator SynchronizedViewIt; // we update all SynchronizedViews for ( SynchronizedViewIt = m_openSynchronizedViews.begin(); SynchronizedViewIt != m_openSynchronizedViews.end(); ++SynchronizedViewIt ) { ( *SynchronizedViewIt )->show(); } std::vector< QGoSynchronizedView3D * >::iterator SynchronizedView3DIt; // we update all SynchronizedViews for ( SynchronizedView3DIt = m_openSynchronizedViews3D.begin(); SynchronizedView3DIt != m_openSynchronizedViews3D.end(); ++SynchronizedView3DIt ) { ( *SynchronizedView3DIt )->show(); } } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedView3D.h0000644000175000017500000001437411667757442025427 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSynchronizedView3D_h #define __QGoSynchronizedView3D_h #include "itkImageToVTKImageFilter.h" #include "itkCastImageFilter.h" #include "itkSmartPointer.h" #include "itkImage.h" #include "QGoSynchronizedView.h" #include "vtkSmartPointer.h" #include "QGoGUILibConfigure.h" class vtkCamera; class vtkImageData; class vtkEventQtSlotConnect; class QGoImageView3D; /** * \class QGoSynchronizedView3D * \brief class used to display a QWidget containing a two dimensional * vtkimagedata* or itkimage*. * QGoSynchronizedView3D provide the interface to synchronize cameras among * several GoSynchronizedView3D. * \example GUI/lib/qgosynchronizedview3dtest.cxx */ class QGOGUILIB_EXPORT QGoSynchronizedView3D:public QGoSynchronizedView { Q_OBJECT public: // itk typedef : // type of itk image for visualization typedef itk::Image< unsigned char, 3 > VisuImageType; // itk to vtk connector typedef itk::ImageToVTKImageFilter< VisuImageType > itkvtkConnectorType; explicit QGoSynchronizedView3D(QString iViewName, QWidget *iParent = 0); ~QGoSynchronizedView3D(); /** Set image displayed by the SynchronizedView */ void SetImage(vtkImageData *iImage); /** \brief Set ITK image displayed by the SynchronizedView */ template< typename TPixel > void SetImage(typename itk::Image< TPixel, 3 >::Pointer iImage) { typedef itk::Image< TPixel, 3 > InputImageType; // we cast the input to have a known image to display typedef itk::CastImageFilter< InputImageType, VisuImageType > CastFilterType; typedef typename CastFilterType::Pointer CastFilterTypePointer; CastFilterTypePointer castITKFilter = CastFilterType::New(); m_itkvtkConnector = itkvtkConnectorType::New(); castITKFilter->SetInput(iImage); castITKFilter->Update(); m_itkvtkConnector->SetInput( castITKFilter->GetOutput() ); m_itkvtkConnector->Update(); SetImage( m_itkvtkConnector->GetOutput() ); Update(); } /** \brief Update the viewer contained in the widget */ void Update(void); /** \brief render the all visualizations of the * viewer contained in the widget if any. */ void Render(void); /** render the iId'th imageview: * 3D visualization usually contains 4 imageviewers : * three 2D projection and a 3D view : iId=[0-3] */ void Render(const int & iId); /** \brief get the camera of the current fullscreen view */ vtkCamera * GetCamera(void); /** get the camera of the current viewer; * iId=[0-3] */ vtkCamera * GetCamera(const int & iId); /** \brief true if the widget has a viewer */ bool HasViewer(void); /** print the SynchronizedView information : * it consists in the image information if any. */ void PrintOs(ostream & os); /** \brief returns the type of SynchronizedView (2 for 2D, 3 for 3D) */ int GetSynchronizedViewType(void); /** Returns the QGoImageView3D* displaid. */ QGoImageView3D * GetImageView(); /** Get the fullscreen view : * 0 : Quadview (all 4 views) * 1 : XY * 2 : XZ * 3 : YZ * 4 : 3D view */ int GetFullScreenView(); public slots: QString SnapshotViewXY( const GoFigure::FileType & iType, const QString & iBaseName = tr("Snapshot-xy-") ); QString SnapshotViewXZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xz-") ); QString SnapshotViewYZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-yz-") ); QString SnapshotViewXYZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xyz-") ); /** Set the fullscreen view : iId = [0-4] * 0 : Quadview (all 4 views) * 1 : XY * 2 : XZ * 3 : YZ * 4 : 3D view */ void SetFullScreenView(const int & iId); /** Set the fullscreen view : XY */ void SetFullXYScreenView(); /** Set the fullscreen view : XZ */ void SetFullXZScreenView(); /** Set the fullscreen view : YZ */ void SetFullYZScreenView(); /** Set the fullscreen view : XYZ */ void SetFullXYZScreenView(); /** Set the fullscreen view : 3D view */ void SetQuadView(); protected: /** delete the viewer contained in the widget */ void deleteViewer(void); /** Create the viewer in the widget */ void createViewer(); QGoImageView3D * m_View; itkvtkConnectorType::Pointer m_itkvtkConnector; private: Q_DISABLE_COPY(QGoSynchronizedView3D); }; #endif // QGoSynchronizedView3D_H GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedView3D.cxx0000644000175000017500000002340411667757442025774 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSynchronizedView3D.h" #include "QGoSynchronizedView3DCallbacks.h" #include "vtkImageData.h" #include "vtkViewImage3D.h" #include "vtkViewImage2D.h" #include "vtkEventQtSlotConnect.h" #include "QGoImageView3D.h" #include "QGoSynchronizedViewManager.h" #include "SnapshotHelper.h" //-------------------------------------------------------------------------- QGoSynchronizedView3D::QGoSynchronizedView3D(QString iViewName, QWidget *iParent) : QGoSynchronizedView(iViewName, iParent), m_View (NULL) { } //-------------------------------------------------------------------------- QGoSynchronizedView3D:: ~QGoSynchronizedView3D() { // remove the SynchronizedView from the orchestra if ( m_ViewManager ) { m_ViewManager->removeSynchronizedView3D(this); m_ViewManager = NULL; } // delete the view if any if ( m_View ) { // we delete the viewer delete ( m_View ); m_View = NULL; } } //-------------------------------------------------------------------------- /* Update the viewer contained in the widget */ void QGoSynchronizedView3D::Update() { if ( m_View ) { this->m_View->Update(); // in addition to standard parameters, we don't want to interpolate data this->m_View->SetInterpolate(0); } } //-------------------------------------------------------------------------- void QGoSynchronizedView3D::PrintOs(ostream & os) { // if we have an imageview, the we print its image information if ( m_Image != NULL ) { os << "SynchronizedView 3D " << this << " contains :" << std::endl; m_Image->Print(os); } else { os << "SynchronizedView 3D " << this << " contains no Image :" << std::endl; } } //-------------------------------------------------------------------------- /* returns the type of SynchronizedView (2 for 2D, 3 for 3D) */ int QGoSynchronizedView3D::GetSynchronizedViewType() { return 3; } //-------------------------------------------------------------------------- void QGoSynchronizedView3D::SetImage(vtkImageData *iImage) { if ( iImage ) { // if there is no viewer, we create one if ( !m_View ) { createViewer(); } // set the image to the current view m_View->SetImage(iImage); // update current image m_Image = iImage; this->Update(); } } //-------------------------------------------------------------------------- void QGoSynchronizedView3D::Render() { if ( HasViewer() ) { m_View->GetImageViewer(0)->Render(); m_View->GetImageViewer(1)->Render(); m_View->GetImageViewer(2)->Render(); m_View->GetImageViewer3D()->Render(); } } //-------------------------------------------------------------------------- void QGoSynchronizedView3D::Render(const int & iId) { if ( HasViewer() ) { if ( ( iId >= 0 ) && ( iId <= 2 ) ) // if we want to render one of the 2D // view { m_View->GetImageViewer(iId)->Render(); } else // if we want to render the 3D view { m_View->GetImageViewer3D()->Render(); } } } //-------------------------------------------------------------------------- /* get the camera of the current viewer */ vtkCamera * QGoSynchronizedView3D::GetCamera() { int currentView = GetFullScreenView(); if ( HasViewer() ) { if ( ( currentView >= 1 ) && ( currentView <= 3 ) ) { return m_View->GetImageViewer(currentView) ->GetRenderer() ->GetActiveCamera(); } else { return m_View->GetImageViewer3D() ->GetRenderer() ->GetActiveCamera(); } } return NULL; } //-------------------------------------------------------------------------- /* get the camera of the current viewer */ vtkCamera * QGoSynchronizedView3D::GetCamera(const int & iId) { if ( HasViewer() ) { if ( ( iId >= 0 ) && ( iId <= 2 ) ) { return m_View->GetImageViewer(iId) ->GetRenderer() ->GetActiveCamera(); } else { return m_View->GetImageViewer3D() ->GetRenderer() ->GetActiveCamera(); } } return NULL; } //-------------------------------------------------------------------------- /* true if the widget has a viewer */ bool QGoSynchronizedView3D::HasViewer() { return ( m_View != NULL ); } //-------------------------------------------------------------------------- int QGoSynchronizedView3D::GetFullScreenView() { if ( HasViewer() ) { return m_View->GetFullScreenView(); } else { return -1; } } //-------------------------------------------------------------------------- QGoImageView3D * QGoSynchronizedView3D::GetImageView() { if ( HasViewer() ) { return m_View; } else { return NULL; } } //-------------------------------------------------------------------------- QString QGoSynchronizedView3D::SnapshotViewXY(const GoFigure::FileType & iType, const QString & iBaseName) { QGoImageView3D *viewer = this->GetImageView(); if ( HasViewer() ) { return viewer->SnapshotViewXY(iType, iBaseName); } else { return QString(); } } //-------------------------------------------------------------------------- QString QGoSynchronizedView3D::SnapshotViewXZ(const GoFigure::FileType & iType, const QString & iBaseName) { QGoImageView3D *viewer = this->GetImageView(); if ( viewer ) { return viewer->SnapshotViewXZ(iType, iBaseName); } else { return QString(); } } //-------------------------------------------------------------------------- QString QGoSynchronizedView3D::SnapshotViewYZ(const GoFigure::FileType & iType, const QString & iBaseName) { QGoImageView3D *viewer = this->GetImageView(); if ( viewer ) { return viewer->SnapshotViewYZ(iType, iBaseName); } else { return QString(); } } //-------------------------------------------------------------------------- QString QGoSynchronizedView3D::SnapshotViewXYZ(const GoFigure::FileType & iType, const QString & iBaseName) { QGoImageView3D *viewer = this->GetImageView(); if ( viewer ) { return viewer->SnapshotViewXYZ(iType, iBaseName); } else { return QString(); } } //-------------------------------------------------------------------------- void QGoSynchronizedView3D::SetFullScreenView(const int & iId) { if ( HasViewer() ) { m_View->SetFullScreenView(iId); } } //-------------------------------------------------------------------------- void QGoSynchronizedView3D::SetFullXYScreenView() { SetFullScreenView(1); } //-------------------------------------------------------------------------- void QGoSynchronizedView3D::SetFullXZScreenView() { SetFullScreenView(2); } //-------------------------------------------------------------------------- void QGoSynchronizedView3D::SetFullYZScreenView() { SetFullScreenView(3); } //-------------------------------------------------------------------------- void QGoSynchronizedView3D::SetFullXYZScreenView() { SetFullScreenView(4); } //-------------------------------------------------------------------------- void QGoSynchronizedView3D::SetQuadView() { SetFullScreenView(0); } // ######################################################################## // Private //-------------------------------------------------------------------------- /* delete the viewer contained in the widget */ void QGoSynchronizedView3D::deleteViewer() { // if there is no viewer if ( m_View ) { // delete object delete ( m_View ); // set pointer to NULL m_View = NULL; } } //-------------------------------------------------------------------------- /* Create the viewer in the widget */ void QGoSynchronizedView3D::createViewer() { // if there is no viewer if ( !HasViewer() ) { // we create one m_View = new QGoImageView3D(this); dynamic_cast< QGoImageView3D * > ( m_View )->setContentsMargins(1, 1, 1, 1); // setup position of the widget gridLayout->addWidget(m_View); } }GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedViewManager.h0000644000175000017500000001737311667757442026535 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSynchronizedViewManager_h #define __QGoSynchronizedViewManager_h #include #include "QGoSynchronizedView2D.h" #include "QGoSynchronizedView3D.h" #include "itkImage.h" #include "QGoSynchronizedView3DCallbacks.h" #include "QGoSynchronizedView2DCallbacks.h" #include "QGoGUILibConfigure.h" class QGoSynchronizedView2DCallbacks; class QGoSynchronizedView3DCallbacks; class vtkImageData; /** \class QGoSynchronizedViewManager * \brief High level class for * QGoSynchronizedView2D, QGoSynchronizedView2DCallbacks * QGoSynchronizedView3D, QGoSynchronizedView3DCallbacks. * * This class is dealing with QGoSynchronizedViews for correct * synchronization and handling provides a simple interface * to create/delete/synchronize QGoSynchronizedView s. * This class should be used with any class using QGoSynchronizedView * and QGoSynchronize. * \example GUI/lib/qgosynchronizedviewmanagertest.cxx */ class QGOGUILIB_EXPORT QGoSynchronizedViewManager:public QObject { Q_OBJECT public: explicit QGoSynchronizedViewManager(QObject *parent = 0); ~QGoSynchronizedViewManager(); /** \brief create and add a QGoSynchronizedView to * QGoSynchronizedViewManager's parent Object/Widget */ template< typename TPixel > QGoSynchronizedView3D * newSynchronizedView( QString iSynchronizedViewName, typename itk::Image< TPixel, 3 >::Pointer iImage) { // verify input if ( ( iSynchronizedViewName.isEmpty() ) || ( iImage.IsNull() ) ) { return NULL; } // we create a new QGoSynchronizedView with the same parent windows as this QGoSynchronizedView3D *tempNewSynchronizedView = new QGoSynchronizedView3D( iSynchronizedViewName, static_cast< QWidget * >( this->parent() ) ); // we add the image to it tempNewSynchronizedView->SetImage< TPixel >(iImage); // if we are synchronizing different QGoSynchronizedView s if ( m_Synchronizer3D != NULL ) { // we tell the synchronizer to also synchronize // the new QGoSynchronizedView m_Synchronizer3D->addSynchronizedView(tempNewSynchronizedView); } // tell the QGoSynchronizedView who is his Manager tempNewSynchronizedView->SetViewManager(this); // we add the QGoSynchronizedView to the list of open // QGoSynchronizedViews m_openSynchronizedViews3D.push_back(tempNewSynchronizedView); return tempNewSynchronizedView; } template< typename TPixel > QGoSynchronizedView2D * newSynchronizedView( QString iSynchronizedViewName, typename itk::Image< TPixel, 2 >::Pointer iImage) { // verify input if ( ( iSynchronizedViewName.isEmpty() ) || ( iImage.IsNull() ) ) { return NULL; } // we create a new QGoSynchronizedView // with the same parent windows as this QGoSynchronizedView2D *tempNewSynchronizedView = new QGoSynchronizedView2D( iSynchronizedViewName, static_cast< QWidget * >( this->parent() ) ); // we add the image to it tempNewSynchronizedView->SetImage< TPixel >(iImage); // if we are synchronizing different QGoSynchronizedViews if ( m_Synchronizer != NULL ) { // we tell the synchronizer to also synchronize the new // QGoSynchronizedView m_Synchronizer->addSynchronizedView(tempNewSynchronizedView); } // tell the QGoSynchronizedView who is his Manager tempNewSynchronizedView->SetViewManager(this); // we add the QGoSynchronizedView to the list of //open QGoSynchronizedViews m_openSynchronizedViews.push_back(tempNewSynchronizedView); return tempNewSynchronizedView; } public slots: /** \brief create and add a QGoSynchronizedView to * QGoSynchronizedViewManager's parent Object/Widget * depending on the vtk image given as an input, the * returned QGoSynchronizedView can be downcasted to * QGoSynchronizedView2D or QGoSynchronizedView3D * safe downcasting is user's responsibility. */ QGoSynchronizedView * newSynchronizedView( QString iSynchronizedViewName, vtkImageData *iImage); /** \brief create and add a QGoSynchronizedView2D to * QGoSynchronizedViewManager's parent Object/Widget */ QGoSynchronizedView2D * newSynchronizedView2D( QString iSynchronizedViewName, vtkImageData *iImage); /** \brief create and add a QGoSynchronizedView3D to * QGoSynchronizedViewManager's parent Object/Widget */ QGoSynchronizedView3D * newSynchronizedView3D( QString iSynchronizedViewName, vtkImageData *iImage); /** \brief delete a QGoSynchronizedView from QGoSynchronizedViewManager's parent * Object/Widget * delete the QGoSynchronizedView */ void deleteSynchronizedView2D(QGoSynchronizedView2D *ioSynchronizedView); void deleteSynchronizedView2D(const int & iIndex); void deleteSynchronizedView3D(QGoSynchronizedView3D *ioSynchronizedView); void deleteSynchronizedView3D(const int & iIndex); /** \brief take a QGoSynchronizedView out of the Manager lists, without deleting it. */ void removeSynchronizedView2D(QGoSynchronizedView2D *ioSynchronizedView); void removeSynchronizedView3D(QGoSynchronizedView3D *ioSynchronizedView); /** \brief synchronize all open QGoSynchronizedViews */ void synchronizeOpenSynchronizedViews(); /** \brief remove the synchronization leaving the all QGoSynchronizedView * independent */ void unSynchronizeOpenSynchronizedViews(); /** \brief true if the manager synchronizes some QGoSynchronizedView */ bool isSynchronizing(); /** \brief update the QGoSynchronizedView s */ void Update(); /** \brief show all the QGoSynchronizedView s */ void show(); protected: // vector to store the open QGoSynchronizedView s std::vector< QGoSynchronizedView2D * > m_openSynchronizedViews; std::vector< QGoSynchronizedView3D * > m_openSynchronizedViews3D; QGoSynchronizedView2DCallbacks *m_Synchronizer; QGoSynchronizedView3DCallbacks *m_Synchronizer3D; private: Q_DISABLE_COPY(QGoSynchronizedViewManager); }; #endif // __QGoSynchronizedViewManager_h GoFigure2-v0.9.0/Code/GUI/lib/SynchronizedViews/QGoSynchronizedView2DCallbacks.h0000644000175000017500000001061311667757442027216 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSynchronizedView2DCallbacks_h #define __QGoSynchronizedView2DCallbacks_h #include "vtkCommand.h" #include "QGoSynchronizedView2D.h" class vtkObject; class vtkCallbackCommand; /** * \class QGoSynchronizedView2DCallbacks * \brief This object takes a list of QGoSynchronizedView and * synchronize their cameras by setting up callbacks. * It is recommended to let the * QGoSynchronizedViewManager deal * with SynchronizedView synchronization. */ class QGoSynchronizedView2DCallbacks:public QObject { Q_OBJECT public: /** \brief the constructor do most of the work : * add observers & callbacks to QGoSynchronizedViews of the vector * \tparam TContainer container of QGoSynchronizedView2D* */ explicit QGoSynchronizedView2DCallbacks( std::vector< QGoSynchronizedView2D * > iOpenSynchronizedViews, QObject *iParent = 0); ~QGoSynchronizedView2DCallbacks(); /** \brief callback function to synchornize cameras (has to be public) */ static void synchronizeCameras(vtkObject *caller, long unsigned int eventId, void *clientData, void *callData); /** \brief remove a SynchronizedView from the vector * of synchronized SynchronizedViews * (this method takes care of removing the callback) */ void removeSynchronizedView(QGoSynchronizedView2D *ioSynchronizedView); /** \brief add a SynchronizedView to the vector * of synchronized SynchronizedViews * (this method takes care of adding the callback) */ void addSynchronizedView(QGoSynchronizedView2D *ioSynchronizedView); private: /** \brief setup the callback command object * (client data, called function...etc) */ void SetupCallBack(); /** \brief callback object to link callback function to * SynchronizedView's event */ vtkCallbackCommand *m_vtkCallBackCamSync; /** \brief all open SynchronizedViews are stored in this array, * to transmit it to the callback function */ std::vector< QGoSynchronizedView2D * > m_openSynchronizedView; template< typename TIterator > void Initialize(TIterator iBegin, TIterator iEnd) { m_openSynchronizedView.clear(); // create the callback object SetupCallBack(); TIterator it = iBegin; // for every opened SynchronizedView : while ( it != iEnd ) { // add the callback object as an observer of each SynchronizedView's // camera ( *it )->GetCamera()->AddObserver(vtkCommand::ModifiedEvent, QGoSynchronizedView2DCallbacks::m_vtkCallBackCamSync); m_openSynchronizedView.push_back(*it); ++it; } } }; #endif // QGoSynchronizedView2DCallbacks_H GoFigure2-v0.9.0/Code/GUI/lib/QGoCollectionColorComboBox.h0000755000175000017500000000543111667757442022751 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoCollectionColorComboBox_h #define __QGoCollectionColorComboBox_h #include "QGoColorComboBox.h" /** \class QGoCollectionColorComboBox \brief this class inherits from QGoColorComboBox, has only the add item option and update the text according to the iCollectionName. It handles the printing of the collection IDs \ingroup GUI */ class QGOGUILIB_EXPORT QGoCollectionColorComboBox:public QGoColorComboBox { Q_OBJECT public: explicit QGoCollectionColorComboBox(QWidget *iparent = 0); virtual ~QGoCollectionColorComboBox(); signals: void NewCollectionToCreate(); public slots: /** \overload */ void SetItemsFromListWithColor(std::list< ItemColorComboboxData > iDataFromList, std::string iCollectionName); /** \overload */ void InitializeTheListWithColor(std::list< ItemColorComboboxData > iDataFromList, std::string iCollectionName); protected slots: //mother class method virtual void ActionWhenNewOneRequested(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoAboutWidget.h0000644000175000017500000000621711667757442020444 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoAboutWidget_h #define __QGoAboutWidget_h #include #include #include #include #include "QGoGUILibConfigure.h" /** * \class QGoAboutWidget * \brief About Widget which includes the list of authors, licenses, * copyrights, dates, versions... */ class QGOGUILIB_EXPORT QGoAboutWidget:public QWidget { Q_OBJECT public: /** \brief Constructor */ explicit QGoAboutWidget(QWidget *iParent = NULL); /** \brief Destructor */ ~QGoAboutWidget(); protected: /** \brief Add one tab (for the license) in the widget. * \param[in] iTextLicense License / Copyright * \param[in] iTabTitle Title of the tab (Library Name) * \param[in] iTabWidget TabWidget to add this element to. */ void AddTabAbout(QString iTextLicense, QString iTabTitle, QTabWidget *iTabWidget); /** \brief Get the list of contributors. */ QString GetContributors(); /** \brief */ void SetTabWidget(QTabWidget *iTabWidget); /** \brief */ void SetTheBackGround(QLabel *iLabel, QTabWidget *TabWidget, QLabel *iLabeltwo); /** \brief Read License file. * \param[in] iFilename input license filename * \return Contents of the license file. * */ QString ReadLicenseText(QString iFilename); /** * \brief */ void WriteLicenseText(QTabWidget *iTabWidget); private: Q_DISABLE_COPY(QGoAboutWidget); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoCollectionColorComboBox.cxx0000644000175000017500000000720711667757442023324 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoCollectionColorComboBox.h" #include QGoCollectionColorComboBox::QGoCollectionColorComboBox(QWidget *iparent) : QGoColorComboBox("Add a new mesh...", iparent) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoCollectionColorComboBox::~QGoCollectionColorComboBox() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoCollectionColorComboBox::ActionWhenNewOneRequested() { emit NewCollectionToCreate(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoCollectionColorComboBox::InitializeTheListWithColor( std::list< ItemColorComboboxData > iDataFromList, std::string iCollectionName) { this->SetItemsFromListWithColor(iDataFromList, iCollectionName); //if it is the 1rst time for the list to be displayed, there has to be an // activated //item: //by default, the one selected by the combobox is the one to stick to: this->EmitActivatedItem( this->currentIndex() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoCollectionColorComboBox::SetItemsFromListWithColor( std::list< ItemColorComboboxData > iDataFromList, std::string iCollectionName) { QString TextForNewOne( tr("Add a new %1 ...").arg( iCollectionName.c_str() ) ); this->m_TextToAddANewOne = TextForNewOne.toStdString(); QGoColorComboBox::SetItemsFromListWithColor(iDataFromList); } //-------------------------------------------------------------------------- //--------------------------------------------------------------------------GoFigure2-v0.9.0/Code/GUI/lib/Wizard/0000755000175000017500000000000011667757442016700 5ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoOpenCreateImgSessionPage.cxx0000644000175000017500000002516411667757442024666 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoOpenCreateImgSessionPage.h" #include "QueryDataBaseHelper.h" #include "SelectQueryDatabaseHelper.h" #include "QGoWizardDB.h" #include QGoOpenCreateImgSessionPage::QGoOpenCreateImgSessionPage(QWidget *iParent) : QWizardPage(iParent), m_DatabaseConnector(0) { QFont tfont; tfont.setBold(false); this->setFont(tfont); CreateImgSessionRadioButton = new QRadioButton( tr("Create a new Imaging Session ") ); OpenImgSessionRadioButton = new QRadioButton( tr("Open an existing Imaging Session") ); textChoiceImgSession = new QLabel( tr("Imaging Session to open:") ); ChoiceImgSession = new QComboBox; textDescription = new QLabel( tr("Description:") ); lineDescription = new QTextEdit; lineImgSessionID = new QLineEdit; lineImgSessionName = new QLineEdit; QVBoxLayout *vlayout = new QVBoxLayout; QVBoxLayout *RadioButtonLayout = new QVBoxLayout; RadioButtonLayout->addWidget(CreateImgSessionRadioButton); RadioButtonLayout->addWidget(OpenImgSessionRadioButton); vlayout->addLayout(RadioButtonLayout); vlayout->setAlignment(RadioButtonLayout, Qt::AlignHCenter); QGridLayout *gridlayout = new QGridLayout; gridlayout->addWidget(textChoiceImgSession, 0, 0); gridlayout->addWidget(ChoiceImgSession, 0, 1); gridlayout->addWidget(textDescription, 3, 0); gridlayout->addWidget(lineDescription, 3, 1); vlayout->addLayout(gridlayout); setLayout(vlayout); registerField("ImgSessionName", lineImgSessionName); registerField("ImgSessionID", lineImgSessionID); QObject::connect( this->ChoiceImgSession, SIGNAL( currentIndexChanged(QString) ), this, SLOT( DisplayInfoImgSession(QString) ) ); QObject::connect( this->OpenImgSessionRadioButton, SIGNAL( clicked() ), this, SLOT( ChangeToOpenImgSessionDisplay() ) ); QObject::connect( this->CreateImgSessionRadioButton, SIGNAL( clicked() ), this, SLOT( ChangeToCreateImgSessionDisplay() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoOpenCreateImgSessionPage::~QGoOpenCreateImgSessionPage() { delete lineImgSessionID; delete lineImgSessionName; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateImgSessionPage::initializePage() { if ( !m_ListImgSession.isEmpty() ) { m_ListImgSession.clear(); } ChoiceImgSession->clear(); OpenDBConnection(); if ( !GetListImgSession() ) { std::cout << "Pb, there is no existing Img session" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } else { OpenImgSessionRadioButton->setChecked(true); ChangeToOpenImgSessionDisplay(); ChoiceImgSession->addItems(m_ListImgSession); DisplayInfoImgSession( ChoiceImgSession->currentText() ); this->setFinalPage(false); } lineDescription->setReadOnly(true); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoOpenCreateImgSessionPage::GetListImgSession() { m_ListImgSession.clear(); ChoiceImgSession->clear(); m_MapImgSessionIDName.clear(); //m_MapImgSessionIDName = MapTwoColumnsFromTable( m_DatabaseConnector, // "Name", "ImagingSessionID", // "imagingsession", "ProjectName", // // // // // // // // // // // // // // // // // // field("ProjectName").toString().toStdString() // ); std::vector< std::string > ImgSessionAttributes (2); ImgSessionAttributes[0] = "Name"; ImgSessionAttributes[1] = "ImagingSessionID"; m_MapImgSessionIDName = MapTwoColumnsFromTable( m_DatabaseConnector, ImgSessionAttributes, "imagingsession", "ProjectName", field( "ProjectName").toString().toStdString() ); boost::unordered_map< std::string, std::string >::iterator it = m_MapImgSessionIDName.begin(); if ( !m_MapImgSessionIDName.empty() ) { while ( it != m_MapImgSessionIDName.end() ) { m_ListImgSession.append( it->first.c_str() ); ++it; } return true; } return false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoOpenCreateImgSessionPage::nextId() const { if ( m_DatabaseConnector == 0 && !LeavingPage ) { OpenDBConnection(); } if ( CreateImgSessionRadioButton->isChecked() ) { return QGoWizardDB::CreateImgSessionPageID; } return -1; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoOpenCreateImgSessionPage::validatePage() { if ( CloseDatabaseConnection(m_DatabaseConnector) ) { m_DatabaseConnector = 0; } LeavingPage = true; //get the imagingsessionID from the selected imagingsession in the combobox //in case the user wants to open an imagingsession: if ( OpenImgSessionRadioButton->isChecked() ) { std::string ImgID = m_MapImgSessionIDName[ChoiceImgSession->currentText().toStdString()]; setField( "ImgSessionID", ImgID.c_str() ); setField( "ImgSessionName", ChoiceImgSession->currentText() ); } return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateImgSessionPage::cleanupPage() { if ( CloseDatabaseConnection(m_DatabaseConnector) ) { m_DatabaseConnector = 0; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateImgSessionPage::OpenDBConnection() const { std::string Server = field("ServerName").toString().toStdString(); std::string User = field("User").toString().toStdString(); std::string Password = field("Password").toString().toStdString(); std::string DBName = field("DBName").toString().toStdString(); m_DatabaseConnector = OpenDatabaseConnection(Server, User, Password, DBName); LeavingPage = false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateImgSessionPage::DisplayInfoImgSession( QString ImgSessionName) { // First, get the corresponding ImagingSessionID from the map: std::string ImagingSessionID = "0"; if ( ImgSessionName != "" ) { boost::unordered_map< std::string, std::string >::iterator it = m_MapImgSessionIDName.begin(); while ( it != m_MapImgSessionIDName.end() && ImagingSessionID == "0" ) { if ( it->first == ImgSessionName.toStdString() ) { ImagingSessionID = it->second; } ++it; } std::vector< std::string > ListDescription = ListSpecificValuesForOneColumn( m_DatabaseConnector, "imagingsession", "Description", "ImagingSessionID", ImagingSessionID); if ( ListDescription.size() != 1 ) { std::cout << "Pb, the imagingsession " << ImgSessionName.toStdString().c_str() << "has more than 1 description" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } lineDescription->setText( ListDescription[0].c_str() ); } this->setFinalPage(false); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateImgSessionPage::ChangeToCreateImgSessionDisplay() { setSubTitle( tr("Click on 'Next' if you want to import a new dataset\n or choose 'Open an imaging session':") ); textChoiceImgSession->setVisible(false); ChoiceImgSession->setVisible(false); lineDescription->setVisible(false); textDescription->setVisible(false); this->setFinalPage(false); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateImgSessionPage::ChangeToOpenImgSessionDisplay() { setSubTitle( tr( "Select the imaging session you want to open and click on 'Finish' to load the corresponding images or choose 'Create a new imaging session':") ); textChoiceImgSession->setVisible(true); ChoiceImgSession->setVisible(true); lineDescription->setVisible(true); textDescription->setVisible(true); this->setFinalPage(false); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoDBInitCreateAuthorsPage.h0000755000175000017500000000527211667757442024071 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBInitCreateAuthorsPage_h #define __QGoDBInitCreateAuthorsPage_h #include #include #include #include "vtkMySQLDatabase.h" class QGoDBInitCreateAuthorsPage:public QWizardPage { Q_OBJECT public: explicit QGoDBInitCreateAuthorsPage(QWidget *iparent = 0); ~QGoDBInitCreateAuthorsPage() {} bool validatePage(); //int nextId() const; void SetDatabaseVariables( std::string iUser, std::string iPassword); protected slots: void CreateAuthor(); signals: void NewAuthorCreated(); private: Q_DISABLE_COPY(QGoDBInitCreateAuthorsPage); QLineEdit * lineLastName; QLineEdit * lineMiddleName; QLineEdit * lineFirstName; QPushButton * CreateButton; vtkMySQLDatabase *m_DatabaseConnector; std::string m_Server; std::string m_User; std::string m_Password; std::string m_DBName; void OpenDBConnection(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoWizardDB.h0000644000175000017500000000747311667757442021141 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoWizardDB_h #define __QGoWizardDB_h #include #include #include #include #include #include #include #include #include #include #include #include #include "GoFigureFileInfoMultiIndexContainerHelper.h" #include "QGoConnectServerPage.h" #include "vtkMySQLDatabase.h" #include "QGoGUILibConfigure.h" /** * \class QGoWizardDB * \brief This class leads the user to chose its imagingsession and enables * to get the corresponding filenames from the database. * \sa QGoConnectServerPage * \sa QGoOpenCreateProjectPage * \sa QGoOpenCreateImgSessionPage * */ class QGOGUILIB_EXPORT QGoWizardDB:public QWizard { Q_OBJECT public: enum { ConnectServerPageID = 0, OpenOrCreateProjectPageID, OpenOrCreateImgSessionPageID, CreateImgSessionPageID }; explicit QGoWizardDB(QWidget *parent = 0); ~QGoWizardDB(){} QString GetNameDB(); QString GetServer(); QString GetLogin(); QString GetPassword(); QString GetImagingSessionName(); int GetImagingSessionID(); bool GetIsAnOpenRecentFile(); QPushButton *nextButton; /** * \brief return a list for each channel of the filenames for the images * in the database as a vector of vector */ std::vector< std::vector< std::string > > GetFilenamesFromDB(); GoFigureFileInfoHelperMultiIndexContainer GetMultiIndexFileContainer(); std::string GetMegaCaptureHeaderFilename(); void setImgSessionName(std::string iImgSessionName); std::string GetFirstFileName(); void SetIsAnOpenRecentFile(bool iIsAnOpenRecentFile); signals: void GofigureDatabaseExists(); void NoGofigureDatabase(); protected: void closeEvent(QCloseEvent *iEvent); void SetFirstFileName(); QGoConnectServerPage *m_ConnectServerPage; std::string m_ImgSessionName; std::string m_FirstFileName; int m_ImgSessionID; bool m_IsAnOpenRecentFile; private: Q_DISABLE_COPY(QGoWizardDB); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoDBInitCreateMicroscopePage.h0000644000175000017500000000522211667757442024537 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBInitCreateMicroscopePage_h #define __QGoDBInitCreateMicroscopePage_h #include #include #include #include "vtkMySQLDatabase.h" class QGoDBInitCreateMicroscopePage:public QWizardPage { Q_OBJECT public: explicit QGoDBInitCreateMicroscopePage(QWidget *iparent = 0); ~QGoDBInitCreateMicroscopePage() {} void SetDatabaseVariables( std::string iUser, std::string iPassword); bool validatePage(); //int nextId() const; protected slots: void CreateMicroscope(); signals: void NewMicroscopeCreated(); private: Q_DISABLE_COPY(QGoDBInitCreateMicroscopePage); QLineEdit * lineMicroscopeName; QPushButton * CreateButton; vtkMySQLDatabase *m_DatabaseConnector; std::string m_Server; std::string m_User; std::string m_Password; std::string m_DBName; void OpenDBConnection(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoCreateImgSessionPage.cxx0000644000175000017500000006450711667757442024050 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoCreateImgSessionPage.h" #include "QueryDataBaseHelper.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBImgSessionRow.h" #include "GoDBImageRow.h" #include "GoDBCoordinateRow.h" #include "GoDBChannelRow.h" #include "GoDBColorRow.h" #include "GoDBRecordSetHelper.h" #include "itkMegaCaptureImport.h" #include "ConvertToStringHelper.h" #include "QGoDBInitCreateMicroscopePage.h" #include #include #include #include #include QGoCreateImgSessionPage::QGoCreateImgSessionPage(QWidget *iParent) : QWizardPage(iParent) { QFont tfont; tfont.setBold(false); this->setFont(tfont); textNewImgSessionName = new QLabel( tr("Name of the New Imaging Session*: ") ); lineNewImgSessionName = new QLineEdit; lineNewImgSessionName->setMaxLength(255); textDescription = new QLabel( tr("Description:") ); lineDescription = new QTextEditChild(this, 1000); textChoiceMicroscope = new QLabel( tr("Choose the Microscope used*:") ); ChoiceMicroscope = new QComboBox; BrowseButton = new QPushButton("&Browse", this); QLabel *textBrowseButton = new QLabel( tr("Select only 1 file\nfrom the Image Set*:") ); lineFilename = new QTextEdit; AddMicroscopeButton = new QPushButton(tr("Add Microscope"), this); QGridLayout *gridlayout = new QGridLayout; gridlayout->addWidget(textNewImgSessionName, 0, 0); gridlayout->addWidget(lineNewImgSessionName, 0, 1); gridlayout->addWidget(textDescription, 1, 0); gridlayout->addWidget(lineDescription, 1, 1); gridlayout->addWidget(textChoiceMicroscope, 2, 0); gridlayout->addWidget(ChoiceMicroscope, 2, 1); gridlayout->addWidget(AddMicroscopeButton, 2, 2); QGridLayout *BrowseButtonLayout = new QGridLayout; BrowseButtonLayout->addWidget(BrowseButton, 0, 2); BrowseButtonLayout->addWidget(textBrowseButton, 0, 0); BrowseButtonLayout->addWidget(lineFilename, 0, 1); BrowseButtonLayout->setColumnStretch (0, 2); BrowseButtonLayout->setColumnStretch (1, 4); BrowseButtonLayout->setColumnStretch (2, 1); QVBoxLayout *vlayout = new QVBoxLayout; vlayout->addLayout(gridlayout); vlayout->addLayout(BrowseButtonLayout); setLayout(vlayout); FirstImage = new QFileInfo; QObject::connect( this->BrowseButton, SIGNAL( clicked() ), this, SLOT( SelectImages() ) ); QObject::connect( AddMicroscopeButton, SIGNAL( clicked() ), this, SLOT( AddMicroscopes() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoCreateImgSessionPage::~QGoCreateImgSessionPage() { delete FirstImage; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoCreateImgSessionPage::initializePage() { lineFilename->clear(); OpenDBConnection(); setSubTitle( tr("Import a new dataset for the project '%1'\n (*fields are required) and click on 'Finish' to load them:") .arg( field("ProjectName").toString() ) ); this->UpdateListMicroscopes(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoCreateImgSessionPage::SelectImages() { QString filename = QFileDialog::getOpenFileName( this, tr("Import Image"), "", tr("Images (*.png *.bmp *.jpg *.jpeg *tif *.tiff *.mha *.mhd *.img *.lsm)") ); lineFilename->setText(filename); FirstImage->setFile(filename); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QStringList QGoCreateImgSessionPage::GetListMicroscopes() { QStringList ListMicroscopes; std::vector< std::string > vectListMicroscopes = ListAllValuesForOneColumn(m_DatabaseConnector, "Name", "microscope"); if ( !vectListMicroscopes.empty() ) { for ( unsigned int i = 0; i < vectListMicroscopes.size(); ++i ) { ListMicroscopes.append( vectListMicroscopes[i].c_str() ); } } return ListMicroscopes; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoCreateImgSessionPage::CreateImgSession(vtkMySQLDatabase *DatabaseConnector) { std::string m_ProjectName = field("ProjectName").toString().toStdString(); int TimeInterval = m_HeaderFileInfo.m_TimeInterval; float RealPixelHeight = m_HeaderFileInfo.m_VoxelSizeX; float RealPixelWidth = m_HeaderFileInfo.m_VoxelSizeY; float RealPixelDepth = m_HeaderFileInfo.m_VoxelSizeZ; unsigned int XImageSize = m_HeaderFileInfo.m_DimensionX; unsigned int YImageSize = m_HeaderFileInfo.m_DimensionY; float XTileOverlap = 0; //todo get it from the header file float YTileOverlap = 0; //todo get it from the header file float ZTileOverlap = 0; //todo get it from the header file std::string CreationDateTime = m_HeaderFileInfo.m_CreationDate; GoDBImgSessionRow myNewImgSession; myNewImgSession.SetField( "Name", lineNewImgSessionName->displayText().toStdString() ); myNewImgSession.SetField( "Description", this->lineDescription->toPlainText().toStdString() ); myNewImgSession.SetField("ImagesTimeInterval", TimeInterval); myNewImgSession.SetField("RealPixelDepth", RealPixelDepth); myNewImgSession.SetField("RealPixelHeight", RealPixelHeight); myNewImgSession.SetField("RealPixelWidth", RealPixelWidth); myNewImgSession.SetField("ProjectName", m_ProjectName); myNewImgSession.SetField( "MicroscopeName", ChoiceMicroscope->currentText().toStdString() ); myNewImgSession.SetField("CreationDate", CreationDateTime); myNewImgSession.SetField("XImageSize", XImageSize); myNewImgSession.SetField("YImageSize", YImageSize); myNewImgSession.SetField("XTileOverlap", XTileOverlap); myNewImgSession.SetField("YTileOverlap", YTileOverlap); myNewImgSession.SetField("ZTileOverlap", ZTileOverlap); int ExistingImgSession = myNewImgSession.DoesThisImagingSessionExist(DatabaseConnector); //if this is not a duplicate, the ExistingImgSession is = -1, so it is OK //to record it in the DB: if ( ExistingImgSession == -1 ) { return AddOnlyOneNewObjectInTable< GoDBImgSessionRow >(DatabaseConnector, "imagingsession", myNewImgSession, "ImagingSessionID"); } //if the img session already exists, the function will return -1: return -1; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoCreateImgSessionPage::validatePage() { if ( lineNewImgSessionName->displayText() == "" ) { QMessageBox msgBox; msgBox.setText( tr("Please make sure that all the required fields (*) are not empty.") ); msgBox.exec(); return false; } if ( lineNewImgSessionName->displayText() != "" ) { std::vector< std::string > ProjectNameTaken = ListSpecificValuesForOneColumn( m_DatabaseConnector, "imagingsession", "Name", "Name", lineNewImgSessionName->displayText().toStdString() ); if ( ProjectNameTaken.size() != 0 ) { QMessageBox msgBox; msgBox.setText( tr("This name is already taken for an existing Imaging Session.\nPlease select another one.") ); msgBox.exec(); return false; } if ( ChoiceMicroscope->currentText() == "" ) { QMessageBox msgBox; msgBox.setText( tr("Please choose a microscope for your imaging session.") ); msgBox.exec(); return false; } } if ( !itk::MegaCaptureImport::IsNewMegaCapture( lineFilename->toPlainText().toStdString() ) ) { QMessageBox msgBox; msgBox.setText( tr("The images you selected are of an old megacapture format, not supported by this database.") ); msgBox.exec(); } //if all the info filled by the user are ok, try to save the info into the // database: bool cleanFileToBeImported = SaveInfoInDatabase(); if(!cleanFileToBeImported) { return cleanFileToBeImported; } CloseDatabaseConnection(m_DatabaseConnector); setField( "ImgSessionName", lineNewImgSessionName->text() ); return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoCreateImgSessionPage::cleanupPage() { CloseDatabaseConnection(m_DatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoCreateImgSessionPage::ImportImages(vtkMySQLDatabase *DatabaseConnector) { if ( DatabaseConnector != 0 ) { try { //Create a Record Set with all the images to be saved in the DB: typedef GoDBRecordSet< GoDBImageRow > myRecordSetType; myRecordSetType *RecordSet = new myRecordSetType; RecordSet->SetConnector(DatabaseConnector); RecordSet->SetTableName("image"); GoFigureFileInfoHelperMultiIndexContainer filelist = GetMultiIndexFileContainer(); m_PCoordMin = filelist.get< m_PCoord >().begin()->m_PCoord; m_PCoordMax = filelist.get< m_PCoord >().rbegin()->m_PCoord; m_RCoordMin = filelist.get< m_RCoord >().begin()->m_RCoord; m_RCoordMax = filelist.get< m_RCoord >().rbegin()->m_RCoord; m_CCoordMin = filelist.get< m_CCoord >().begin()->m_CCoord; m_CCoordMax = filelist.get< m_CCoord >().rbegin()->m_CCoord; m_XTileCoordMin = filelist.get< m_XTileCoord >().begin()->m_XTileCoord; m_XTileCoordMax = filelist.get< m_XTileCoord >().rbegin()->m_XTileCoord; m_YTileCoordMin = filelist.get< m_YTileCoord >().begin()->m_YTileCoord; m_YTileCoordMax = filelist.get< m_YTileCoord >().rbegin()->m_YTileCoord; m_ZTileCoordMin = filelist.get< m_ZTileCoord >().begin()->m_ZTileCoord; m_ZTileCoordMax = filelist.get< m_ZTileCoord >().rbegin()->m_ZTileCoord; m_TCoordMin = filelist.get< m_TCoord >().begin()->m_TCoord; m_TCoordMax = filelist.get< m_TCoord >().rbegin()->m_TCoord; m_ZCoordMin = filelist.get< m_ZCoord >().begin()->m_ZCoord; m_ZCoordMax = filelist.get< m_ZCoord >().rbegin()->m_ZCoord; MultiIndexContainerIteratorType f_it = filelist.begin(); MultiIndexContainerIteratorType f_end = filelist.end(); while ( f_it != f_end ) { GoDBImageRow Image = CreateImage( DatabaseConnector, f_it, field("ImgSessionID").toInt() ); RecordSet->AddObject(Image); ++f_it; } //Save all the images in the recordset in the Database: if ( !RecordSet->SaveInDB() ) { std::cout << "The images have not been saved in the DB" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return; } delete RecordSet; } catch ( const itk::ExceptionObject & e ) { std::cerr << " caught an ITK exception: " << std::endl; e.Print(std::cerr); return; } catch ( const std::exception & e ) { std::cerr << " caught an std exception: " << std::endl; std::cerr << e.what() << std::endl; return; } catch ( ... ) { std::cerr << " caught an unknown exception!" << std::endl; return; } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoCreateImgSessionPage::ImportInfoFromMegacapture(QString iNewfilename) { try { // will throw an itk exceptio if an error occurs m_importFileInfoList = itk::MegaCaptureImport::New(); m_importFileInfoList->SetFileName( iNewfilename.toAscii().data() ); // QProgressBar pBar; //importFileInfoList->SetProgressBar( &pBar ); m_importFileInfoList->Update(); //Get the headerfile once the headerfilename is gotten //from megacapture import: std::string HeaderFilename = m_importFileInfoList->GetHeaderFilename(); m_HeaderFileInfo.SetFileName(HeaderFilename); m_HeaderFileInfo.Read(); } catch ( const itk::ExceptionObject & e ) { std::cerr << " caught an ITK exception: " << std::endl; e.Print(std::cerr); return false; } catch ( const std::exception & e ) { std::cerr << " caught an std exception: " << std::endl; std::cerr << e.what() << std::endl; return false; } catch ( std::string & e ) { std::cerr << " caught an exception: " << std::endl; std::cerr << e << std::endl; return false; } catch ( ... ) { std::cerr << " caught an unknown exception!" << std::endl; return false; } return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoCreateImgSessionPage::CreateChannels(vtkMySQLDatabase *DatabaseConnector, int ImagingSessionID) { //creation of the record set to be filled with all the new channels to save in // DB: typedef GoDBRecordSet< GoDBChannelRow > myRecordSetType; myRecordSetType *RecordSet = new myRecordSetType; RecordSet->SetConnector(DatabaseConnector); RecordSet->SetTableName("channel"); std::cout << "m_HeaderFileInfo.m_NumberOfChannels: " << m_HeaderFileInfo.m_NumberOfChannels << std::endl; for ( unsigned int i = 0; i < m_HeaderFileInfo.m_NumberOfChannels; i++ ) { //for each channel, the color first has to be created from the headerfile //into the DB: GoDBColorRow myNewColor; std::string StringChannelNumber = ConvertToString< int >(i); std::string ChannelName = "Channel " + StringChannelNumber; std::string ColorName = "ColorFor"; ColorName += ChannelName; /** \todo Lydie: take the channel names from the header file*/ int Red = m_HeaderFileInfo.m_ChannelColor[i][0]; int Green = m_HeaderFileInfo.m_ChannelColor[i][1]; int Blue = m_HeaderFileInfo.m_ChannelColor[i][2]; int Alpha = 255; myNewColor.SetField("Name", ColorName); myNewColor.SetField("Red", Red); myNewColor.SetField("Green", Green); myNewColor.SetField("Blue", Blue); myNewColor.SetField("Alpha", Alpha); int ColorID = myNewColor.SaveInDB(DatabaseConnector); //creation of the corresponding channel: GoDBChannelRow myNewChannel; myNewChannel.SetField("ColorID", ColorID); myNewChannel.SetField("Name", ChannelName); myNewChannel.SetField("ImagingSessionID", ImagingSessionID); myNewChannel.SetField("ChannelNumber", i); myNewChannel.SetField("NumberOfBits", m_HeaderFileInfo.m_ChannelDepth); RecordSet->AddObject(myNewChannel); } RecordSet->SaveInDB(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoCreateImgSessionPage::CreateImageCoordMin(vtkMySQLDatabase *DatabaseConnector, MultiIndexContainerIteratorType It) { GoDBCoordinateRow myNewImageCoordMin; myNewImageCoordMin.SetField("PCoord", It->m_PCoord); myNewImageCoordMin.SetField("RCoord", It->m_RCoord); myNewImageCoordMin.SetField("CCoord", It->m_CCoord); myNewImageCoordMin.SetField("XTileCoord", It->m_XTileCoord); myNewImageCoordMin.SetField("YTileCoord", It->m_YTileCoord); myNewImageCoordMin.SetField("ZTileCoord", It->m_ZTileCoord); myNewImageCoordMin.SetField("XCoord", It->m_XCoord); myNewImageCoordMin.SetField("YCoord", It->m_YCoord); myNewImageCoordMin.SetField("ZCoord", It->m_ZCoord); myNewImageCoordMin.SetField("TCoord", It->m_TCoord); /*std::map< std::string, std::string >::iterator IterNewCoord = myNewImageCoordMin.MapBegin(); std::map< std::string, std::string >::iterator IterNewCoordEnd = myNewImageCoordMin.MapEnd(); std::map< std::string, std::string >::iterator IterMinCoord = m_ImgSessionCoordMin.MapBegin(); std::map< std::string, std::string >::iterator IterMaxCoord = m_ImgSessionCoordMax.MapBegin(); while ( IterNewCoord != IterNewCoordEnd ) { IterMinCoord->second = ConvertToString< int >( std::min( temp, atoi( IterMinCoord->second.c_str() ) ) ); IterMaxCoord->second = ConvertToString< int >( std::max( temp, atoi( IterMaxCoord->second.c_str() ) ) ); ++IterMinCoord; ++IterNewCoord; ++IterMaxCoord; }*/ return myNewImageCoordMin.SaveInDB(DatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoCreateImgSessionPage::FindChannelIDForImage(vtkMySQLDatabase *DatabaseConnector, int ImagingSessionID, int ChannelNumber) { std::vector< FieldWithValue > Conditions(2); FieldWithValue ImgSession = { "ImagingSessionID", ConvertToString< int >(ImagingSessionID), "=" }; FieldWithValue Channel = { "ChannelNumber", ConvertToString< int >(ChannelNumber), "=" }; Conditions[0] = ImgSession; Conditions[1] = Channel; return FindOneID(DatabaseConnector, "channel", "channelID", Conditions); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBImageRow QGoCreateImgSessionPage::CreateImage(vtkMySQLDatabase *DatabaseConnector, MultiIndexContainerIteratorType It, int ImagingSessionID) { GoDBImageRow myNewImage; myNewImage.SetField("ImagingSessionID", ImagingSessionID); myNewImage.SetField( "CoordIDMin", CreateImageCoordMin(DatabaseConnector, It) ); myNewImage.SetField("Filename", It->m_Filename); //find the channelID for the image which corresponds to the channel number //found in the filename (m_Channel): int channel = FindChannelIDForImage(m_DatabaseConnector, ImagingSessionID, It->m_Channel); if ( channel == -1 ) { std::cout << "The channel doesn't exist in the DB" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return myNewImage; } myNewImage.SetField("ChannelID", channel); return myNewImage; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoCreateImgSessionPage::CreateImgSessionCoord( vtkMySQLDatabase *DatabaseConnector, int ImagingSessionID) { std::string imgsessionid = ConvertToString< int >(ImagingSessionID); int XImageSize = m_HeaderFileInfo.m_DimensionX; int YImageSize = m_HeaderFileInfo.m_DimensionY; m_ImgSessionCoordMax.SetField("PCoord", m_PCoordMax); m_ImgSessionCoordMax.SetField("RCoord", m_RCoordMax); m_ImgSessionCoordMax.SetField("CCoord", m_CCoordMax); m_ImgSessionCoordMax.SetField("XTileCoord", m_XTileCoordMax); m_ImgSessionCoordMax.SetField("YTileCoord", m_YTileCoordMax); m_ImgSessionCoordMax.SetField("ZTileCoord", m_ZTileCoordMax); m_ImgSessionCoordMax.SetField("TCoord", m_TCoordMax); m_ImgSessionCoordMax.SetField("ZCoord", m_ZCoordMax); m_ImgSessionCoordMax.SetField("XCoord", XImageSize); m_ImgSessionCoordMax.SetField("YCoord", YImageSize); //add a new coordinate to enter the info for ImgSession CoordMax int CoordIDMax = m_ImgSessionCoordMax.SaveInDB(DatabaseConnector); //update the CoordMaxID in Imgsession with the new created coordinate UpdateValueInDB(DatabaseConnector, "imagingsession", "CoordIDMax", ConvertToString< int >(CoordIDMax), "ImagingSessionID", imgsessionid); m_ImgSessionCoordMin.SetField("PCoord", m_PCoordMin); m_ImgSessionCoordMin.SetField("RCoord", m_RCoordMin); m_ImgSessionCoordMin.SetField("CCoord", m_CCoordMin); m_ImgSessionCoordMin.SetField("XTileCoord", m_XTileCoordMin); m_ImgSessionCoordMin.SetField("YTileCoord", m_YTileCoordMin); m_ImgSessionCoordMin.SetField("ZTileCoord", m_ZTileCoordMin); m_ImgSessionCoordMin.SetField("TCoord", m_TCoordMin); m_ImgSessionCoordMin.SetField("ZCoord", m_ZCoordMin); m_ImgSessionCoordMin.SetField("XCoord", 0); m_ImgSessionCoordMin.SetField("YCoord", 0); //add a new coordinate to enter the info for ImgSession CoordMin int CoordIDMin = m_ImgSessionCoordMin.SaveInDB(DatabaseConnector); //update the CoordMaxID in Imgsession with the new created coordinate UpdateValueInDB(DatabaseConnector, "imagingsession", "CoordIDMin", ConvertToString< int >(CoordIDMin), "ImagingSessionID", imgsessionid); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoCreateImgSessionPage::OpenDBConnection() { std::string Server = field("ServerName").toString().toStdString(); std::string User = field("User").toString().toStdString(); std::string Password = field("Password").toString().toStdString(); std::string DBName = field("DBName").toString().toStdString(); m_DatabaseConnector = OpenDatabaseConnection(Server, User, Password, DBName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoCreateImgSessionPage::SaveInfoInDatabase() { /*First, get the info from the filenames and the headerfile: */ bool cleanFileToBeImported = ImportInfoFromMegacapture(lineFilename->toPlainText() ); if(!cleanFileToBeImported) { QMessageBox msgBox; msgBox.setText( tr("The images you try to import are corrupted.") ); msgBox.exec(); return false; } /*Second, save in the DB the related ImagingSession as it is not possible to save in DB the images without knowing the corresponding ImagingSessionID:*/ int ImgSessionID = CreateImgSession(m_DatabaseConnector); setField("ImgSessionID", ImgSessionID); if ( ImgSessionID != -1 ) { QString ImgSessionName = lineNewImgSessionName->displayText(); //setField("ImgSessionName",ImgSessionName); /*Save in the DB the channels corresponding to the ImagingSession and to the channelnumber of the images:*/ CreateChannels( m_DatabaseConnector, field("ImgSessionID").toInt() ); /*Record all the images from the image set into the DB, and fill the ImgSessionCoordMin and Max with the values related to the images:*/ ImportImages(m_DatabaseConnector); //,lineFilename->toPlainText()); //Update CoordMin and CoordMax for ImagingSession: CreateImgSessionCoord( m_DatabaseConnector, field("ImgSessionID").toInt() ); return true; } QMessageBox msgBox; msgBox.setText( tr("The images imported already belongs to an existing Imaging Session.") ); msgBox.exec(); return false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigureFileInfoHelperMultiIndexContainer QGoCreateImgSessionPage::GetMultiIndexFileContainer() { if ( m_importFileInfoList.IsNotNull() ) { return m_importFileInfoList->GetOutput(); } else { return GoFigureFileInfoHelperMultiIndexContainer(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoCreateImgSessionPage::GetMegaCaptureHeaderFilename() { return m_importFileInfoList->GetHeaderFilename(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoCreateImgSessionPage::AddMicroscopes() { QGoDBInitCreateMicroscopePage *CreateMicroscopePage = new QGoDBInitCreateMicroscopePage; CreateMicroscopePage->SetDatabaseVariables( field("User").toString().toStdString(), field("Password").toString().toStdString() ); CreateMicroscopePage->show(); QObject::connect( CreateMicroscopePage, SIGNAL( NewAuthorCreated() ), this, SLOT( UpdateListMicroscopes() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoCreateImgSessionPage::UpdateListMicroscopes() { ChoiceMicroscope->clear(); ChoiceMicroscope->addItems( GetListMicroscopes() ); } GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoDBInitCreateUserPage.h0000755000175000017500000000542511667757442023362 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBInitCreateUserPage_h #define __QGoDBInitCreateUserPage_h #include #include #include #include "vtkMySQLDatabase.h" class QGoDBInitCreateUserPage:public QWizardPage { Q_OBJECT public: explicit QGoDBInitCreateUserPage(QWidget *iparent = 0); ~QGoDBInitCreateUserPage() {} bool validatePage(); private: Q_DISABLE_COPY(QGoDBInitCreateUserPage); QLineEdit * lineUserName; QLineEdit * linePassword; std::string m_ServerName; std::string m_DBName; bool CreateUser(); bool CreateGofigureUserWithDatabaseConnector( vtkMySQLDatabase *DatabaseConnector, std::string iLogin, std::string iServerName, std::string iPassword); bool UserNameAlreadyExits( vtkMySQLDatabase *DatabaseConnector, std::string iLogin); /** \brief create a dialog with OK and Cancel button asking iquestion to the user, return true if the user press OK, false if press Cancel*/ bool QuestionToUser(QString iQuestion); signals: void UserAndDatabaseCreated(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoOpenCreateImgSessionPage.h0000644000175000017500000000701611667757442024307 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoOpenCreateImgSessionPage_h #define __QGoOpenCreateImgSessionPage_h #include #include #include #include #include #include #include #include #include #include "boost/unordered_map.hpp" #include "vtkMySQLDatabase.h" class QGoOpenCreateImgSessionPage:public QWizardPage { Q_OBJECT public: explicit QGoOpenCreateImgSessionPage(QWidget *parent = 0); ~QGoOpenCreateImgSessionPage(); void initializePage(); bool validatePage(); int nextId() const; void cleanupPage(); mutable vtkMySQLDatabase *m_DatabaseConnector; private: /** * \brief fill the m_MapImgSessionIDName with the names of the existing imaging * session stored in the database and their corresponding ID, fill the m_ListImgSession * with the names only and return true if this list is not empty. */ bool GetListImgSession(); void OpenDBConnection() const; QLabel * textDescription; QTextEdit * lineDescription; QLabel * textChoiceImgSession; QComboBox * ChoiceImgSession; QString OpenOrCreateImgSession; QRadioButton *OpenImgSessionRadioButton; QRadioButton *CreateImgSessionRadioButton; QLineEdit * lineImgSessionID; QLineEdit * lineImgSessionName; mutable bool LeavingPage; QStringList m_ListImgSession; boost::unordered_map< std::string, std::string > m_MapImgSessionIDName; protected slots: /** * \brief display in the description text the existing description stored * in the database for a given Imaging Session. */ void DisplayInfoImgSession(QString ImgSessionName); void ChangeToCreateImgSessionDisplay(); void ChangeToOpenImgSessionDisplay(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoDBInitCreateUserPage.cxx0000644000175000017500000002165111667757442023731 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBInitCreateUserPage.h" #include "CreateDataBaseHelper.h" #include "QGoDBInitializationWizard.h" #include "vtkSQLQuery.h" #include #include #include #include #include #include #include #include QGoDBInitCreateUserPage::QGoDBInitCreateUserPage(QWidget *iParent) : QWizardPage(iParent) { QFont tfont; tfont.setBold(false); this->setFont(tfont); m_ServerName = "localhost"; m_DBName = "gofiguredatabase"; setSubTitle( tr("Create a user for MySQL Database local Server:") ); QFormLayout *formLayout = new QFormLayout; lineUserName = new QLineEdit; linePassword = new QLineEdit; linePassword->setEchoMode(QLineEdit::Password); linePassword->displayText(); formLayout->addRow(tr("Choose a User name:"), lineUserName); formLayout->addRow(tr("Choose a Password:"), linePassword); setLayout(formLayout); setLayout(formLayout); registerField("User", lineUserName); registerField("Password", linePassword); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoDBInitCreateUserPage::validatePage() { QMessageBox msgBox; if ( field("User").toString() == "" || field("Password").toString() == "" ) { msgBox.setText( tr("Please fill all the fields.") ); msgBox.exec(); return false; } if ( !this->CreateUser() ) { return false; } if ( !CreateGoFigureDataBase(this->m_ServerName, field("User").toString().toStdString(), field("Password").toString().toStdString(), this->m_DBName) ) { msgBox.setText( tr("There is a problem with the creation of your database,check the password for your user.") ); msgBox.exec(); return false; } emit UserAndDatabaseCreated(); return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoDBInitCreateUserPage::CreateUser() { std::string Login = field("User").toString().toStdString(); std::string Password = field("Password").toString().toStdString(); vtkMySQLDatabase *DataBaseConnector = vtkMySQLDatabase::New(); DataBaseConnector->SetHostName( this->m_ServerName.c_str() ); DataBaseConnector->SetUser("root"); bool ok; QString text = QInputDialog::getText(0, "Enter your root password for MySQL:", "Root Password for MySQL:", QLineEdit::Password, QDir::home().dirName(), &ok); if ( ok ) { if ( text.isEmpty() ) { DataBaseConnector->SetPassword(""); } else { DataBaseConnector->SetPassword( text.toStdString().c_str() ); } if ( !DataBaseConnector->Open() ) { QMessageBox msgBox; msgBox.setText( tr("There is a problem with the connection to your root.") ); msgBox.exec(); return false; } } else //the user clicks on something else than ok when asking for the mysql // root password: { return false; } if ( !this->UserNameAlreadyExits(DataBaseConnector, Login) ) { if ( this->QuestionToUser( tr("Do you want to create this new user with a new database?") ) ) { return this->CreateGofigureUserWithDatabaseConnector(DataBaseConnector, Login, this->m_ServerName, Password); } else { return false; } } else { return this->QuestionToUser( tr("The user you entered already exists, \ndo you want to create a database for this user?") ); } return false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoDBInitCreateUserPage::CreateGofigureUserWithDatabaseConnector( vtkMySQLDatabase *DatabaseConnector, std::string iLogin, std::string iServerName, std::string iPassword) { vtkSQLQuery * query = DatabaseConnector->GetQueryInstance(); std::stringstream queryScript; queryScript << "CREATE USER '"; queryScript << iLogin; queryScript << "'@'"; queryScript << iServerName; queryScript << "' IDENTIFIED BY '"; queryScript << iPassword; queryScript << "';"; query->SetQuery( queryScript.str().c_str() ); query->Execute(); query->Delete(); vtkSQLQuery * queryPrivileges = DatabaseConnector->GetQueryInstance(); std::stringstream PrivilegesScript; PrivilegesScript << "GRANT ALL PRIVILEGES ON *.* TO '"; PrivilegesScript << iLogin; PrivilegesScript << "'@'"; PrivilegesScript << iServerName; PrivilegesScript << "';"; queryPrivileges->SetQuery( PrivilegesScript.str().c_str() ); if ( !queryPrivileges->Execute() ) { DatabaseConnector->Close(); DatabaseConnector->Delete(); queryPrivileges->Delete(); QMessageBox msgBox; msgBox.setText( tr("Sorry, there is a problem with the creation of your user.") ); msgBox.exec(); return false; } queryPrivileges->Delete(); DatabaseConnector->Close(); DatabaseConnector->Delete(); return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoDBInitCreateUserPage::UserNameAlreadyExits(vtkMySQLDatabase *DatabaseConnector, std::string iLogin) { vtkSQLQuery * queryUserExist = DatabaseConnector->GetQueryInstance(); std::stringstream UserExistScript; UserExistScript << "SELECT USER FROM mysql.user WHERE user = '"; UserExistScript << iLogin; UserExistScript << "';"; queryUserExist->SetQuery( UserExistScript.str().c_str() ); if ( !queryUserExist->Execute() ) { QMessageBox msgBox; msgBox.setText( tr("There is a problem to check your existing users.") ); msgBox.exec(); queryUserExist->Delete(); DatabaseConnector->Close(); DatabaseConnector->Delete(); queryUserExist->Delete(); return false; } if ( queryUserExist->NextRow() ) { queryUserExist->Delete(); DatabaseConnector->Close(); DatabaseConnector->Delete(); return true; } queryUserExist->Delete(); return false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoDBInitCreateUserPage::QuestionToUser(QString iQuestion) { QDialogButtonBox *button = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); QDialog * Dialog = new QDialog; QLabel * Label = new QLabel(iQuestion); QFormLayout *Layout = new QFormLayout(this); Layout->addWidget(Label); Layout->addWidget(button); Dialog->setLayout(Layout); QObject::connect( button, SIGNAL( accepted() ), Dialog, SLOT( accept() ) ); QObject::connect( button, SIGNAL( rejected() ), Dialog, SLOT( reject() ) ); int Result = Dialog->exec(); if ( Result == 0 ) { return false; } return true; }GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoCreateImgSessionPage.h0000644000175000017500000001466611667757442023476 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoCreateImgSessionPage_h #define __QGoCreateImgSessionPage_h #include #include #include #include #include #include #include #include #include #include #include #include "GoDBImageRow.h" #include "GoDBCoordinateRow.h" #include "GoFigureFileInfoMultiIndexContainerHelper.h" #include "vtkMySQLDatabase.h" #include "MegaCaptureHeaderReader.h" #include "itkMegaCaptureImport.h" #include "QTextEditChild.h" #include "QGoGUILibConfigure.h" class QGOGUILIB_EXPORT QGoCreateImgSessionPage:public QWizardPage { Q_OBJECT public: explicit QGoCreateImgSessionPage(QWidget *parent = 0); ~QGoCreateImgSessionPage(); void initializePage(); bool validatePage(); void cleanupPage(); vtkMySQLDatabase *m_DatabaseConnector; GoFigureFileInfoHelperMultiIndexContainer GetMultiIndexFileContainer(); std::string GetMegaCaptureHeaderFilename(); private: /**\brief get the list of the existing microscopes registered in the DB */ QStringList GetListMicroscopes(); /** \brief create a new imaging session into the DB with the information filled by the user and collected from the filenames, and return the ImagingSessionID just created or -1 if the img session already exists*/ int CreateImgSession(vtkMySQLDatabase *DatabaseConnector); /** \brief create the imaging session, all the channels into the DB, then the images selected by the user and at the end, update the CoordIDMax and Min of the imaging session into the DB*/ void ImportImages(vtkMySQLDatabase *DatabaseConnector); //,QString // newfilename); typedef GoFigureFileInfoHelperMultiIndexContainer::iterator MultiIndexContainerIteratorType; /** \brief create the coordinate CoordMin in the DB, check and update if its values are less than the other CoordMin created for the images belonging to the same imaging session and return the CoordID of the coordinate just created */ int CreateImageCoordMin(vtkMySQLDatabase *DatabaseConnector, MultiIndexContainerIteratorType It); /** \brief return the ChannelID from the DB corresponding to the imaging session and to the channel number given by the image filename*/ int FindChannelIDForImage(vtkMySQLDatabase *DatabaseConnector, int ImagingSessionID, int ChannelNumber); /** \brief return a GoDBImageRow filled with all the data corresponding */ GoDBImageRow CreateImage(vtkMySQLDatabase *DatabaseConnector, MultiIndexContainerIteratorType It, int ImagingSessionID); /** \brief create the channels and their corresponding colors in the database, from the data gotten from the headerfile*/ void CreateChannels(vtkMySQLDatabase *DatabaseConnector, int ImagingSessionID); /** \brief create into the DB the coordinates corresponding to the CoordID Min and Max for the Imaging Session and update the CoordIDMax and Min for the imaging session in the DB with the newly created coordinates*/ void CreateImgSessionCoord(vtkMySQLDatabase *DatabaseConnector, int ImagingSessionID); void OpenDBConnection(); bool SaveInfoInDatabase(); /** \brief fill m_importFileInfoList from the filenames of the images and m_HeaderFileInfo from the header file*/ bool ImportInfoFromMegacapture(QString newfilename); QLabel * textNewImgSessionName; QLineEdit * lineNewImgSessionName; QLabel * textDescription; QTextEditChild *lineDescription; QLabel * textChoiceMicroscope; QComboBox * ChoiceMicroscope; QPushButton * AddMicroscopeButton; QPushButton * BrowseButton; QTextEdit * lineFilename; QString newfilename; QFileInfo * FirstImage; QLineEdit * lineImgSessionID; QLineEdit * lineImgSessionName; GoDBCoordinateRow m_ImgSessionCoordMax; GoDBCoordinateRow m_ImgSessionCoordMin; MegaCaptureHeaderReader m_HeaderFileInfo; itk::MegaCaptureImport::Pointer m_importFileInfoList; protected slots: void SelectImages(); void AddMicroscopes(); void UpdateListMicroscopes(); private: unsigned int m_PCoordMin; unsigned int m_PCoordMax; unsigned int m_RCoordMin; unsigned int m_RCoordMax; unsigned int m_CCoordMin; unsigned int m_CCoordMax; unsigned int m_XTileCoordMin; unsigned int m_XTileCoordMax; unsigned int m_YTileCoordMin; unsigned int m_YTileCoordMax; unsigned int m_ZTileCoordMin; unsigned int m_ZTileCoordMax; unsigned int m_ZCoordMin; unsigned int m_ZCoordMax; unsigned int m_TCoordMin; unsigned int m_TCoordMax; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoOpenCreateProjectPage.cxx0000644000175000017500000004330511667757442024211 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoOpenCreateProjectPage.h" #include "QueryDataBaseHelper.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBRecordSetHelper.h" #include "GoDBProjectRow.h" #include "QGoWizardDB.h" #include "ConvertToStringHelper.h" #include "QGoDBInitCreateAuthorsPage.h" #include #include #include #include #include #include #include QGoOpenCreateProjectPage::QGoOpenCreateProjectPage(QWidget *iParent) : QWizardPage(iParent), m_DatabaseConnector(0), ExistingImgSession(false) { QFont tfont; tfont.setBold(false); this->setFont(tfont); m_DatabaseVersion = "Version2"; CreateProjectRadioButton = new QRadioButton( tr("Create a new Project ") ); OpenProjectRadioButton = new QRadioButton( tr("Open an existing Project") ); NewAuthorButton = new QPushButton(tr("Add author"), this); textChoiceProject = new QLabel( tr("Project to open:") ); ChoiceProject = new QComboBox; textNewProjectName = new QLabel( tr("Name of the Project: ") ); lineNewProjectName = new QLineEdit; lineNewProjectName->setMaxLength(255); textDescription = new QLabel( tr("Description:") ); lineDescription = new QTextEditChild(this, 1000); textChoiceAuthor = new QLabel( tr("Choose the name of the author: ") ); ChoiceAuthor = new QComboBox; textAuthor = new QLabel ( tr("Author of the project: ") ); lineAuthor = new QLineEdit; lineAuthor->setReadOnly(true); QVBoxLayout *vlayout = new QVBoxLayout; QVBoxLayout *RadioButtonLayout = new QVBoxLayout; RadioButtonLayout->addWidget(CreateProjectRadioButton); RadioButtonLayout->addWidget(OpenProjectRadioButton); vlayout->addLayout(RadioButtonLayout); vlayout->setAlignment(RadioButtonLayout, Qt::AlignHCenter); QGridLayout *gridlayout = new QGridLayout; gridlayout->addWidget(textChoiceProject, 0, 0); gridlayout->addWidget(ChoiceProject, 0, 1); gridlayout->addWidget(textNewProjectName, 3, 0); gridlayout->addWidget(lineNewProjectName, 3, 1); gridlayout->addWidget(textChoiceAuthor, 4, 0); gridlayout->addWidget(ChoiceAuthor, 4, 1); gridlayout->addWidget(textAuthor, 5, 0); gridlayout->addWidget(lineAuthor, 5, 1); gridlayout->addWidget(NewAuthorButton, 4, 3); gridlayout->addWidget(textDescription, 6, 0); gridlayout->addWidget(lineDescription, 6, 1); vlayout->addLayout(gridlayout); setLayout(vlayout); registerField("ProjectName", lineNewProjectName); registerField("Author", ChoiceAuthor); QObject::connect( this->OpenProjectRadioButton, SIGNAL( clicked() ), this, SLOT( ChangeToOpenProjectDisplay() ) ); QObject::connect( this->CreateProjectRadioButton, SIGNAL( clicked() ), this, SLOT( ChangeToCreateProjectDisplay() ) ); QObject::connect( this->ChoiceProject, SIGNAL( currentIndexChanged(QString) ), this, SLOT( DisplayInfoProject(QString) ) ); QObject::connect( NewAuthorButton, SIGNAL( clicked() ), this, SLOT( AddAuthors() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateProjectPage::initializePage() { if ( !m_ListProject.isEmpty() ) { m_ListProject.clear(); } if ( ChoiceProject->count() != 0 ) { ChoiceProject->clear(); } OpenDBConnection(); setSubTitle( tr("You are currently using The Database %1 ").arg( field("DBName").toString() ) ); OpenProjectRadioButton->setChecked(false); CreateProjectRadioButton->setChecked(true); if ( !GetListProject() ) { ChangeToCreateProjectDisplay(); OpenProjectRadioButton->setChecked(false); OpenProjectRadioButton->hide(); CreateProjectRadioButton->setChecked(true); } else { ChangeToOpenProjectDisplay(); OpenProjectRadioButton->setChecked(true); CreateProjectRadioButton->setChecked(false); OpenProjectRadioButton->setVisible(true); } field("ProjectName").clear(); field("Author").clear(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoOpenCreateProjectPage::GetListProject() const { m_ListProject.clear(); ChoiceProject->clear(); std::vector< std::string > vectListProjName = ListAllValuesForOneColumn(m_DatabaseConnector, "Name", "project"); if ( !vectListProjName.empty() ) { for ( unsigned int i = 0; i < vectListProjName.size(); ++i ) { m_ListProject.append( vectListProjName[i].c_str() ); } ChoiceProject->addItems(m_ListProject); return true; } else { return false; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateProjectPage::CreateProject() { QDate DateOfToday = QDate::currentDate(); GoDBProjectRow myNewProject; myNewProject.SetField( "Name", field("ProjectName").toString().toStdString() ); myNewProject.SetField( "Description", this->lineDescription->toPlainText().toStdString() ); myNewProject.SetField( "AuthorID", AuthorIDForNewProject() ); myNewProject.SetField( "CreationDate", DateOfToday.toString(Qt::ISODate).toStdString() ); myNewProject.SetField("DatabaseVersion", m_DatabaseVersion); if ( m_DatabaseConnector == 0 ) { OpenDBConnection(); } AddOnlyOneNewObjectInTable< GoDBProjectRow >(m_DatabaseConnector, "project", myNewProject); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoOpenCreateProjectPage::AuthorIDForNewProject() { QString Author = ChoiceAuthor->currentText(); int spaces = Author.count( QRegExp(" ") ); std::stringstream AuthorName; AuthorName << Author.toStdString(); if ( spaces < 2 ) { AuthorName << " "; } return m_MapAuthorIDName[AuthorName.str()]; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QStringList QGoOpenCreateProjectPage::GetListAuthors() { QStringList ListAuthors; if ( m_DatabaseConnector == 0 ) { OpenDBConnection(); } std::vector< std::string > ListFirstNames = ListAllValuesForOneColumn( m_DatabaseConnector, "FirstName", "author"); std::vector< std::string > ListMiddleNames = ListAllValuesForOneColumn( m_DatabaseConnector, "MiddleName", "author"); std::vector< std::string > ListLastNames = ListAllValuesForOneColumn( m_DatabaseConnector, "LastName", "author"); std::vector< std::string > ListID = ListAllValuesForOneColumn( m_DatabaseConnector, "AuthorID", "author"); if ( !ListFirstNames.empty() ) { for ( unsigned int i = 0; i < ListFirstNames.size(); i++ ) { std::stringstream AuthorTotalName; AuthorTotalName << ListLastNames[i]; AuthorTotalName << " "; AuthorTotalName << ListFirstNames[i]; AuthorTotalName << " "; AuthorTotalName << ListMiddleNames[i]; std::vector< FieldWithValue > Conditions(3); FieldWithValue FirstName = { "FirstName", ListFirstNames[i], "=" }; Conditions[0] = FirstName; FieldWithValue MiddleName = { "MiddleName", ListMiddleNames[i], "=" }; Conditions[1] = MiddleName; FieldWithValue LastName = { "LastName", ListLastNames[i], "=" }; Conditions[2] = LastName; m_MapAuthorIDName[AuthorTotalName.str()] = FindOneID(m_DatabaseConnector, "author", "AuthorID", Conditions); } for ( std::map< std::string, int >::iterator iter = m_MapAuthorIDName.begin(); iter != m_MapAuthorIDName.end(); ++iter ) { QString AuthorName = ( *iter ).first.c_str(); if ( AuthorName.contains( QRegExp("") ) ) { AuthorName.chop(7); } ListAuthors.append(AuthorName); } } else { QMessageBox msgBox; msgBox.setText( tr("Please create the author of your project:") ); msgBox.exec(); } return ListAuthors; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateProjectPage::ChangeToCreateProjectDisplay() { setSubTitle( tr( "When you click on 'Next' the project will be created in the Gofigure Database\n or select 'Open an existing project':") ); QStringList ListAuthors; textChoiceProject->setVisible(false); ChoiceProject->setVisible(false); textNewProjectName->setVisible(true); textNewProjectName->setText( tr("Name of the new Project") ); lineNewProjectName->clear(); lineNewProjectName->setVisible(true); lineDescription->setReadOnly(false); lineDescription->clear(); textChoiceAuthor->setVisible(true); ChoiceAuthor->setVisible(true); NewAuthorButton->setVisible(true); textAuthor->setVisible(false); lineAuthor->setVisible(false); //if(ListAuthors.isEmpty()) //{ this->UpdateListAuthors(); // } ChoiceAuthor->setVisible(true); OpenOrCreateProject = "Create"; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateProjectPage::ChangeToOpenProjectDisplay() { setSubTitle( tr("Select the project you want to open or choose 'Create a new project':") ); textChoiceProject->setVisible(true); ChoiceProject->setVisible(true); textNewProjectName->setVisible(false); lineNewProjectName->setVisible(false); lineDescription->setReadOnly(true); textChoiceAuthor->setVisible(false); ChoiceAuthor->setVisible(false); NewAuthorButton->setVisible(false); textAuthor->setVisible(true); lineAuthor->setVisible(true); OpenOrCreateProject = "Open"; if ( !m_ListProject.isEmpty() ) { DisplayInfoProject(m_ListProject[0]); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateProjectPage::DisplayInfoProject(QString ProjectName) { if ( ProjectName != "" ) { /*Display the description of the existing project "ProjectName" */ QString Description; if ( m_DatabaseConnector == 0 ) { OpenDBConnection(); } std::vector< std::string > ResultQuery; ResultQuery = ListSpecificValuesForOneColumn( m_DatabaseConnector, "project", "Description", "Name", ProjectName.toStdString() ); /*only one field in the ResultQuery as the project name is the primary key of the Project Table: */ Description = ResultQuery[0].c_str(); lineDescription->setText(Description); /*Display the AuthorName of the exisiting project "ProjectName" first, have to find the corresponding AuthorID in the Database :*/ ResultQuery.clear(); ResultQuery = ListSpecificValuesForOneColumn( m_DatabaseConnector, "project", "AuthorID", "Name", ProjectName.toStdString() ); int AuthorID = atoi( ResultQuery[0].c_str() ); /*second, have to find the corresponding AuthorName in the map*/ if ( m_MapAuthorIDName.empty() ) { GetListAuthors(); } QString AuthorName; for ( std::map< std::string, int >::iterator iter = m_MapAuthorIDName.begin(); iter != m_MapAuthorIDName.end() && AuthorName.isEmpty(); ++iter ) { if ( iter->second == AuthorID ) { AuthorName = ( *iter ).first.c_str(); if ( AuthorName.contains( QRegExp("") ) ) { AuthorName.chop(7); } } } lineAuthor->setText(AuthorName); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoOpenCreateProjectPage::validatePage() { if ( OpenOrCreateProject == "Open" ) { setField( "ProjectName", ChoiceProject->currentText() ); } else { if ( lineNewProjectName->displayText() == "" ) { QMessageBox msgBox; msgBox.setText( tr("Please enter a name for your new project.") ); msgBox.exec(); return false; } if ( m_ListProject.contains(field("ProjectName").toString(), Qt::CaseInsensitive) ) { QMessageBox msgBox; msgBox.setText( tr("The name you entered for your project already exists.") ); msgBox.exec(); return false; } if ( ChoiceAuthor->currentText() == "" ) { QMessageBox msgBox; msgBox.setText( tr("Please select an Author for your project.") ); msgBox.exec(); return false; } CreateProject(); } if ( m_DatabaseConnector == 0 ) { OpenDBConnection(); } ExistingImgSession = DoesProjectHaveExistingImgSession(); if ( CloseDatabaseConnection(m_DatabaseConnector) ) { m_DatabaseConnector = 0; } LeavingPage = true; return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateProjectPage::cleanupPage() { if ( CloseDatabaseConnection(m_DatabaseConnector) ) { m_DatabaseConnector = 0; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoOpenCreateProjectPage::nextId() const { if ( m_DatabaseConnector == 0 && !LeavingPage ) { BackFromNextPage(); } if ( !ExistingImgSession ) { return QGoWizardDB::CreateImgSessionPageID; } return QGoWizardDB::OpenOrCreateImgSessionPageID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateProjectPage::OpenDBConnection() const { std::string Server = field("ServerName").toString().toStdString(); std::string User = field("User").toString().toStdString(); std::string Password = field("Password").toString().toStdString(); std::string DBName = field("DBName").toString().toStdString(); m_DatabaseConnector = OpenDatabaseConnection(Server, User, Password, DBName); LeavingPage = false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoOpenCreateProjectPage::DoesProjectHaveExistingImgSession() const { if ( m_DatabaseConnector == 0 ) { OpenDBConnection(); } std::vector< std::string > ListImgSessionID = ListSpecificValuesForOneColumn( m_DatabaseConnector, "imagingsession", "imagingsessionID", "projectName", field("ProjectName").toString().toStdString() ); return !ListImgSessionID.empty(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateProjectPage::BackFromNextPage() const { this->OpenDBConnection(); this->GetListProject(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateProjectPage::AddAuthors() { QGoDBInitCreateAuthorsPage *CreateAuthorPage = new QGoDBInitCreateAuthorsPage; CreateAuthorPage->SetDatabaseVariables( field("User").toString().toStdString(), field("Password").toString().toStdString() ); CreateAuthorPage->show(); QObject::connect( CreateAuthorPage, SIGNAL( NewAuthorCreated() ), this, SLOT( UpdateListAuthors() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoOpenCreateProjectPage::UpdateListAuthors() { QStringList ListAuthors = GetListAuthors(); ChoiceAuthor->clear(); ChoiceAuthor->addItems(ListAuthors); } GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoDBInitCreateMicroscopePage.cxx0000644000175000017500000001437011667757442025116 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBInitCreateMicroscopePage.h" #include "CreateDataBaseHelper.h" #include "QGoDBInitializationWizard.h" #include "vtkSQLQuery.h" #include "QueryDataBaseHelper.h" #include "SelectQueryDatabaseHelper.h" #include #include #include #include #include #include QGoDBInitCreateMicroscopePage::QGoDBInitCreateMicroscopePage(QWidget *iParent) : QWizardPage(iParent) { QFont tfont; tfont.setBold(false); this->setFont(tfont); m_DatabaseConnector = 0; setSubTitle( tr("Create the microscopes for the gofigure projects:") ); QFormLayout *formLayout = new QFormLayout; lineMicroscopeName = new QLineEdit; CreateButton = new QPushButton( tr("Create Microscope") ); formLayout->addRow(tr("Enter the Microscope Name:"), lineMicroscopeName); formLayout->addWidget(CreateButton); QObject::connect( this->CreateButton, SIGNAL( clicked() ), this, SLOT( CreateMicroscope() ) ); setLayout(formLayout); //registerField( "MicroscopeName", lineMicroscopeName ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoDBInitCreateMicroscopePage::validatePage() { this->OpenDBConnection(); QMessageBox msgBox; if ( ListAllValuesForOneColumn(this->m_DatabaseConnector, "Name", "microscope").empty() ) { msgBox.setText( tr("Please create at least one microscope.") ); msgBox.exec(); if ( CloseDatabaseConnection(m_DatabaseConnector) ) { m_DatabaseConnector = 0; } return false; } if ( CloseDatabaseConnection(m_DatabaseConnector) ) { m_DatabaseConnector = 0; } msgBox.setText( QObject::tr( "The MySql user and the GoFigure Database \n\ have been successfully created !!\n\ Now you can save the work you do with GoFigure into the Database !!") ); msgBox.exec(); return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBInitCreateMicroscopePage::CreateMicroscope() { this->OpenDBConnection(); QMessageBox msgBox; //std::string MicroscopeName = // field("MicroscopeName").toString().toStdString(); std::string MicroscopeName = this->lineMicroscopeName->text().toStdString(); if ( MicroscopeName.empty() ) { msgBox.setText( tr("Please enter a name for your microscope.") ); msgBox.exec(); return; } if ( ListSpecificValuesForOneColumn(this->m_DatabaseConnector, "microscope", "Name", "Name", MicroscopeName).size() > 0 ) { msgBox.setText( tr("There is already a Microscope with the same name, please choose another one") ); msgBox.exec(); return; } vtkSQLQuery * query = this->m_DatabaseConnector->GetQueryInstance(); std::stringstream queryScript; queryScript << "INSERT INTO microscope VALUES ('"; queryScript << MicroscopeName; queryScript << "') ;"; query->SetQuery( queryScript.str().c_str() ); if ( !query->Execute() ) { std::cout << "Insert Microscope query failed." << std::endl; query->Delete(); return; } query->Delete(); msgBox.setText( tr("Your microscope has been successfully created") ); msgBox.exec(); emit NewMicroscopeCreated(); if ( CloseDatabaseConnection(m_DatabaseConnector) ) { m_DatabaseConnector = 0; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void QGoDBInitCreateMicroscopePage::OpenDBConnection() { if ( this->m_User.empty() || this->m_Password.empty() ) { this->SetDatabaseVariables( field("User").toString().toStdString(), field("Password").toString().toStdString() ); } if ( this->m_DatabaseConnector == 0 ) { m_DatabaseConnector = OpenDatabaseConnection( this->m_Server, this->m_User, this->m_Password, this->m_DBName); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBInitCreateMicroscopePage::SetDatabaseVariables( std::string iUser, std::string iPassword) { this->m_User = iUser; this->m_Password = iPassword; this->m_Server = "localhost"; this->m_DBName = "gofiguredatabase"; }GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoDBInitCreateAuthorsPage.cxx0000644000175000017500000001505011667757442024434 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBInitCreateAuthorsPage.h" #include "CreateDataBaseHelper.h" #include "QGoDBInitializationWizard.h" #include "vtkSQLQuery.h" #include "QueryDataBaseHelper.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBAuthorRow.h" #include #include #include #include #include #include QGoDBInitCreateAuthorsPage::QGoDBInitCreateAuthorsPage(QWidget *iParent) : QWizardPage(iParent) { QFont tfont; tfont.setBold(false); this->setFont(tfont); m_DatabaseConnector = 0; setSubTitle( tr("Create the authors for the gofigure projects:") ); QFormLayout *formLayout = new QFormLayout; lineLastName = new QLineEdit; lineMiddleName = new QLineEdit; lineFirstName = new QLineEdit; CreateButton = new QPushButton( tr("Create Author") ); formLayout->addRow(tr("Enter the Author FirstName:"), lineFirstName); formLayout->addRow(tr("Enter the Author MiddleName:"), lineMiddleName); formLayout->addRow(tr("Enter the Author LastName:"), lineLastName); formLayout->addWidget(CreateButton); QObject::connect( this->CreateButton, SIGNAL( clicked() ), this, SLOT( CreateAuthor() ) ); setLayout(formLayout); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoDBInitCreateAuthorsPage::validatePage() { this->OpenDBConnection(); if ( ListAllValuesForOneColumn(this->m_DatabaseConnector, "AuthorID", "author").empty() ) { QMessageBox msgBox; msgBox.setText( tr("Please create at least one author for your project.") ); msgBox.exec(); if ( CloseDatabaseConnection(m_DatabaseConnector) ) { m_DatabaseConnector = 0; } return false; } if ( CloseDatabaseConnection(m_DatabaseConnector) ) { m_DatabaseConnector = 0; } return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBInitCreateAuthorsPage::CreateAuthor() { this->OpenDBConnection(); QMessageBox msgBox; std::string LastNameValue = lineLastName->text().toStdString(); std::string FirstNameValue = lineFirstName->text().toStdString(); std::string MiddleNameValue = lineMiddleName->text().toStdString(); if ( FirstNameValue.empty() || LastNameValue.empty() ) { msgBox.setText( tr("Please enter at least the lastname and the firstname of your author") ); msgBox.exec(); return; } std::vector< FieldWithValue > Conditions; FieldWithValue FirstName = { "FirstName", FirstNameValue, "=" }; FieldWithValue LastName = { "LastName", LastNameValue, "=" }; Conditions.push_back(FirstName); Conditions.push_back(LastName); if ( FindOneID(this->m_DatabaseConnector, "author", "AuthorID", Conditions) != -1 && MiddleNameValue.empty() ) { msgBox.setText( tr("There is already an Author with the same lastname and firstname, please enter a middlename") ); msgBox.exec(); return; } GoDBAuthorRow NewAuthor; NewAuthor.SetField( "FirstName", lineFirstName->text().toStdString() ); NewAuthor.SetField( "LastName", lineLastName->text().toStdString() ); NewAuthor.SetField( "MiddleName", lineMiddleName->text().toStdString() ); if ( NewAuthor.DoesThisAuthorAlreadyExists(this->m_DatabaseConnector) != -1 ) { msgBox.setText( tr("This author already exists") ); msgBox.exec(); return; } NewAuthor.SaveInDB(this->m_DatabaseConnector); msgBox.setText( tr("Your author has been successfully created") ); msgBox.exec(); emit NewAuthorCreated(); if ( CloseDatabaseConnection(m_DatabaseConnector) ) { m_DatabaseConnector = 0; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void QGoDBInitCreateAuthorsPage::OpenDBConnection() { if ( this->m_User.empty() || this->m_Password.empty() ) { this->SetDatabaseVariables( field("User").toString().toStdString(), field("Password").toString().toStdString() ); } if ( this->m_DatabaseConnector == 0 ) { m_DatabaseConnector = OpenDatabaseConnection( this->m_Server, this->m_User, this->m_Password, this->m_DBName); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBInitCreateAuthorsPage::SetDatabaseVariables( std::string iUser, std::string iPassword) { this->m_User = iUser; this->m_Password = iPassword; this->m_Server = "localhost"; this->m_DBName = "gofiguredatabase"; }GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoWizardDB.cxx0000644000175000017500000003346311667757442021512 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoWizardDB.h" #include "QGoOpenCreateProjectPage.h" #include "QGoOpenCreateImgSessionPage.h" #include "QGoCreateImgSessionPage.h" #include "CreateDataBaseHelper.h" #include "QueryDataBaseHelper.h" #include "SelectQueryDatabaseHelper.h" #include "GoDBRecordSet.h" #include "GoDBRecordSetHelper.h" #include "itkMegaCaptureImport.h" #include "GoFigureFileInfoMultiIndexContainerHelper.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include //------------------------------------------------------------------------- QGoWizardDB::QGoWizardDB(QWidget *iParent) : QWizard(iParent) { this->m_ImgSessionName = ""; this->m_ImgSessionID = 0; this->m_IsAnOpenRecentFile = false; QFont tfont; tfont.setBold(true); this->setFont(tfont); QFont font2; font2.setBold(false); nextButton = new QPushButton( tr("Next") ); nextButton->setFont(font2); this->setButton (QWizard::NextButton, nextButton); QPushButton *backButton = new QPushButton( tr("Back") ); backButton->setFont(font2); this->setButton (QWizard::BackButton, backButton); this->setOptions(QWizard::NoCancelButton); QPushButton *finishButton = new QPushButton( tr("Finish") ); finishButton->setFont(font2); this->setButton (QWizard::FinishButton, finishButton); this->m_ConnectServerPage = new QGoConnectServerPage; setPage(ConnectServerPageID, this->m_ConnectServerPage); setPage(OpenOrCreateProjectPageID, new QGoOpenCreateProjectPage); setPage(OpenOrCreateImgSessionPageID, new QGoOpenCreateImgSessionPage); setPage(CreateImgSessionPageID, new QGoCreateImgSessionPage); setWindowTitle( tr("Use DataBase") ); QObject::connect( this->m_ConnectServerPage, SIGNAL( NoGofigureDatabase() ), this, SLOT( hide() ) ); QObject::connect( this->m_ConnectServerPage, SIGNAL( NoGofigureDatabase() ), this, SIGNAL( NoGofigureDatabase() ) ); QObject::connect( this->m_ConnectServerPage, SIGNAL( GofigureDatabaseExists() ), this, SIGNAL ( GofigureDatabaseExists() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector< std::vector< std::string > > QGoWizardDB::GetFilenamesFromDB() { std::vector< std::vector< std::string > > oFilenames; //first, open a connection to the database: std::string Server = field("ServerName").toString().toStdString(); std::string User = field("User").toString().toStdString(); std::string Password = field("Password").toString().toStdString(); std::string DBName = field("DBName").toString().toStdString(); std::pair< bool, vtkMySQLDatabase * > ConnectionDatabase = ConnectToDatabase( Server, User, Password, DBName); if ( !ConnectionDatabase.first ) { std::cout << "No connection open for QGoOpenOrCreateImgSession" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } vtkMySQLDatabase *DatabaseConnector = ConnectionDatabase.second; //Get the number of channels with their id as a map //ListChannelsIDNumber[channelID]=ChannelNumber: std::vector< std::string > ChannelAttributes (2); ChannelAttributes[0] = "channelID"; ChannelAttributes[1] = "ChannelNumber"; boost::unordered_map< std::string, std::string > ListChannelsIDNumber = MapTwoColumnsFromTable( DatabaseConnector, ChannelAttributes, "channel", "ImagingSessionID", field("ImgSessionID").toString().toStdString() ); // std::map< std::string, std::string > ListChannelsIDNumber = // MapTwoColumnsFromTable( DatabaseConnector, "channelID", "ChannelNumber", // "channel", "ImagingSessionID", // field("ImgSessionID").toString().toStdString() ); boost::unordered_map< std::string, std::string >::iterator it = ListChannelsIDNumber.begin(); oFilenames.resize( ListChannelsIDNumber.size() ); int i = 0; while ( it != ListChannelsIDNumber.end() ) { std::string ChannelID = it->first; //get the filenames of all the images corresponding to ChannelID: oFilenames[i] = ListSpecificValuesForOneColumn( DatabaseConnector, "image", "Filename", "channelID", ChannelID); ++it; ++i; } //close the database connection: DatabaseConnector->Close(); DatabaseConnector->Delete(); return oFilenames; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoWizardDB::GetNameDB() { return field("NameDB").toString(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoWizardDB::GetImagingSessionID() { if ( field("ImgSessionID").toInt() != 0 ) { return field("ImgSessionID").toInt(); } if ( this->m_ImgSessionID != 0 ) { return this->m_ImgSessionID; } return 0; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoWizardDB::GetImagingSessionName() { if ( this->m_ImgSessionName.empty() ) { return field("ImgSessionName").toString(); } else { return this->m_ImgSessionName.c_str(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoWizardDB::GetServer() { return field("ServerName").toString(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoWizardDB::GetLogin() { return field("User").toString(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoWizardDB::GetPassword() { return field("Password").toString(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoWizardDB::closeEvent(QCloseEvent *iEvent) { int CurrentPageID = this->currentId(); QWizardPage *CurrentPage = this->currentPage(); if ( !field("ImgSessionName").toString().toStdString().empty() ) { this->m_ImgSessionName = field("ImgSessionName").toString().toStdString(); this->m_ImgSessionID = 0; } if ( !field("DBName").toString().toStdString().empty() ) { this->SetFirstFileName(); } this->m_ImgSessionName.clear(); this->m_IsAnOpenRecentFile = false; //this->restart(); switch ( CurrentPageID ) { case 0: { //QGoConnectServerPage* ServerPage = // dynamic_cast(CurrentPage); //ServerPage->m_ConnectionServer.second->Close(); //ServerPage->m_ConnectionServer.second->Delete(); //delete ServerPage; break; } case 1: { QGoOpenCreateProjectPage *ProjectPage = dynamic_cast< QGoOpenCreateProjectPage * >( CurrentPage ); if ( ProjectPage->m_DatabaseConnector ) { ProjectPage->m_DatabaseConnector->Close(); ProjectPage->m_DatabaseConnector = 0; } break; } case 2: { QGoOpenCreateImgSessionPage *ImgSessionPage = dynamic_cast< QGoOpenCreateImgSessionPage * >( CurrentPage ); if ( ImgSessionPage->m_DatabaseConnector ) { ImgSessionPage->m_DatabaseConnector->Close(); ImgSessionPage->m_DatabaseConnector = 0; } break; } case 3: { QGoCreateImgSessionPage *CreateImgSessionPage = dynamic_cast< QGoCreateImgSessionPage * >( CurrentPage ); if ( CreateImgSessionPage->m_DatabaseConnector ) { CreateImgSessionPage->m_DatabaseConnector->Close(); CreateImgSessionPage->m_DatabaseConnector = 0; } break; } default: { break; } } /* QGoOpenCreateImgSessionPage* F = dynamic_cast(CurrentPage); if (F !=0) { F->m_DatabaseConnector->Close(); F->m_DatabaseConnector->Delete(); } delete F;*/ iEvent->accept(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigureFileInfoHelperMultiIndexContainer QGoWizardDB::GetMultiIndexFileContainer() { QGoCreateImgSessionPage *img_page = dynamic_cast< QGoCreateImgSessionPage * >( this->page(CreateImgSessionPageID) ); if ( img_page ) { return img_page->GetMultiIndexFileContainer(); } else { return GoFigureFileInfoHelperMultiIndexContainer(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoWizardDB::GetMegaCaptureHeaderFilename() { QGoCreateImgSessionPage *img_page = dynamic_cast< QGoCreateImgSessionPage * >( this->page(CreateImgSessionPageID) ); std::string oFilename; if ( img_page ) { oFilename = img_page->GetMegaCaptureHeaderFilename(); } return oFilename; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoWizardDB::setImgSessionName(std::string iImgSessionName) { this->m_ImgSessionName = iImgSessionName; this->m_IsAnOpenRecentFile = true; this->m_ConnectServerPage->SetImgSessionName(iImgSessionName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoWizardDB::SetFirstFileName() { /** \todo Lydie: redundant, create an OpenDBConnection....*/ std::string Server = field("ServerName").toString().toStdString(); std::string User = field("User").toString().toStdString(); std::string Password = field("Password").toString().toStdString(); std::string DBName = field("DBName").toString().toStdString(); std::pair< bool, vtkMySQLDatabase * > ConnectionDatabase = ConnectToDatabase( Server, User, Password, DBName); if ( !ConnectionDatabase.first ) { std::cout << "No connection open for QGoOpenOrCreateImgSession" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } vtkMySQLDatabase *DatabaseConnector = ConnectionDatabase.second; this->m_ImgSessionID = FindOneID(DatabaseConnector, "imagingsession", "ImagingSessionID", "Name", this->m_ImgSessionName); this->m_FirstFileName = ReturnOnlyOneValue( DatabaseConnector, "image", "Filename", "ImagingSessionID", ConvertToString< int >(this->m_ImgSessionID) ); DatabaseConnector->Close(); DatabaseConnector->Delete(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::string QGoWizardDB::GetFirstFileName() { if ( !this->m_IsAnOpenRecentFile ) { this->m_ImgSessionName = field("ImgSessionName").toString().toStdString(); } this->SetFirstFileName(); this->m_ImgSessionName.clear(); this->m_ConnectServerPage->SetIsAnOpenRecentFile(false); return this->m_FirstFileName; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoWizardDB::GetIsAnOpenRecentFile() { return this->m_IsAnOpenRecentFile; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoWizardDB::SetIsAnOpenRecentFile(bool iIsAnOpenRecentFile) { this->m_IsAnOpenRecentFile = iIsAnOpenRecentFile; } GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoConnectServerPage.cxx0000644000175000017500000002016511667757442023414 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoConnectServerPage.h" #include "CreateDataBaseHelper.h" #include "QGoWizardDB.h" #include "QueryDataBaseHelper.h" #include #include #include #include #include QGoConnectServerPage::QGoConnectServerPage(QWidget *iParent) : QWizardPage(iParent) { this->m_ImgSessionName.clear(); this->m_IsAnOpenRecentFile = false; QFont tfont; tfont.setBold(false); this->setFont(tfont); setSubTitle( tr("Connect to a MySQL DataBase Server:") ); QFormLayout *formLayout = new QFormLayout; lineServerName = new QLineEdit( tr("localhost") ); lineUserName = new QLineEdit( tr("gofigure") ); linePassword = new QLineEdit( tr("gofigure") ); linePassword->setEchoMode(QLineEdit::Password); linePassword->displayText(); lineDBName = new QLineEdit; formLayout->addRow(tr("&ServerName:"), lineServerName); formLayout->addRow(tr("&User:"), lineUserName); formLayout->addRow(tr("&Password:"), linePassword); setLayout(formLayout); setLayout(formLayout); registerField("ServerName", lineServerName); registerField("User", lineUserName); registerField("Password", linePassword); registerField("DBName", lineDBName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoConnectServerPage::~QGoConnectServerPage() { delete lineDBName; // make sure vtkMySQLDatabase* has been deleted CloseServerConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoConnectServerPage::validatePage() { if ( field("ServerName").toString() == "" || field("User").toString() == "" || field("Password").toString() == "" ) { QMessageBox msgBox; msgBox.setText( tr("Please fill all the fields.") ); msgBox.exec(); return false; } this->OpenConnectionToServer(); if ( !m_ConnectionServer.first ) { QMessageBox msgBox; msgBox.setText( tr("Unable to connect to the server: please make sure you entered the right fields.") ); msgBox.exec(); return false; } std::list< std::string > ListGoDB = ListGofigureDatabases(); if ( ListGoDB.empty() ) { QMessageBox msgBox; msgBox.setText( tr( "You have not yet set up your Gofigure Database\nPlease go to the menu 'Settings' and select 'Set Up Database'.") ); msgBox.exec(); emit NoGofigureDatabase(); return false; } if ( ListGoDB.size() > 1 ) { std::cout << "There is more than one Gofigure DataBase" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return false; } std::list< std::string >::iterator i = ListGoDB.begin(); std::string DBName = *i; this->wizard()->setField( "DBName", DBName.c_str() ); emit GofigureDatabaseExists(); //std::cout << "the db name to open is: " << // field("DBName").toString().toStdString().c_str() << std::endl; return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoConnectServerPage::nextId() const { if ( !this->m_IsAnOpenRecentFile ) { return QGoWizardDB::OpenOrCreateProjectPageID; } else { return -1; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< std::string > QGoConnectServerPage::ListGofigureDatabases() const { //Get the list of all the existing databases: this->OpenConnectionToServer(); std::vector< std::string > vectListDB = ListDatabases(m_ConnectionServer.second); CloseServerConnection(); /*For each existing database, check if they are of Gofigure Type, if so, put them in the ListGoDB*/ std::list< std::string > ListGoDB; for ( unsigned int i = 0; i < vectListDB.size(); ++i ) { //First, create the connection to the database named vectListDB[i]and check // it is open: std::pair< bool, vtkMySQLDatabase * > DatabaseConnection = ConnectToDatabase( field("ServerName").toString().toStdString(), field("User").toString().toStdString(), field("Password").toString().toStdString(), vectListDB[i]); if ( !DatabaseConnection.first ) { std::cout << "Cannot check if " << vectListDB[i].c_str() << " is of\ Gofigure Type" << std::endl; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } //test if it is of GofigureType: if ( IsDatabaseOfGoFigureType(DatabaseConnection.second) ) { ListGoDB.push_back(vectListDB[i]); } DatabaseConnection.second->Close(); DatabaseConnection.second->Delete(); } return ListGoDB; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoConnectServerPage::CloseServerConnection() const { if ( m_ConnectionServer.second ) { m_ConnectionServer.second->Close(); m_ConnectionServer.second->Delete(); m_ConnectionServer.second = 0; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoConnectServerPage::OpenConnectionToServer() const { if ( this->m_ConnectionServer.second == 0 ) { m_ConnectionServer = ConnectToServer( field("ServerName").toString().toStdString(), field("User").toString().toStdString(), field("Password").toString().toStdString() ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoConnectServerPage::SetImgSessionName(std::string iImgSessionName) { this->m_ImgSessionName = iImgSessionName; this->m_IsAnOpenRecentFile = true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoConnectServerPage::SetIsAnOpenRecentFile(bool iIsAnOpenRecentFile) { this->m_IsAnOpenRecentFile = iIsAnOpenRecentFile; }GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoOpenCreateProjectPage.h0000644000175000017500000001112311667757442023627 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoOpenCreateProjectPage_h #define __QGoOpenCreateProjectPage_h #include #include #include #include #include #include #include #include #include #include "vtkMySQLDatabase.h" #include "QTextEditChild.h" class QGoOpenCreateProjectPage:public QWizardPage { Q_OBJECT public: QGoOpenCreateProjectPage(QWidget *parent = 0); mutable vtkMySQLDatabase *m_DatabaseConnector; void initializePage(); bool validatePage(); void cleanupPage(); int nextId() const; private: /** \brief update the m_ListProject and return true if the list is not empty, false if there is no existing project.*/ bool GetListProject() const; /** \brief insert the new project in the database with the information filled by the user*/ void CreateProject(); /** \brief return the QStringList of the authors to be visualized by the user (concatenation of the firstname, middle name and last name and fill the map mapping the concatenated names with the AuthorID.*/ QStringList GetListAuthors(); /** \brief return the AuthorID corresponding to the one in the database based on the name selected by the user in the combobox.*/ int AuthorIDForNewProject(); /** \brief open a connection to the database.*/ void OpenDBConnection() const; /** \brief get the list of the existing imaging session for the selected project and return true if the list is not empty.*/ bool DoesProjectHaveExistingImgSession() const; void BackFromNextPage() const; std::string m_DatabaseVersion; QLabel * textNewProjectName; QLineEdit * lineNewProjectName; QLabel * textDescription; QTextEditChild *lineDescription; QLabel * textChoiceProject; QComboBox * ChoiceProject; QLabel * textChoiceAuthor; QPushButton * NewAuthorButton; QComboBox * ChoiceAuthor; QLabel * textAuthor; QLineEdit * lineAuthor; QString OpenOrCreateProject; QRadioButton * OpenProjectRadioButton; QRadioButton * CreateProjectRadioButton; mutable QStringList m_ListProject; std::map< std::string, int > m_MapAuthorIDName; bool ExistingImgSession; mutable bool LeavingPage; protected slots: /** \brief hides/shows the related QLabel,QLineEdit...and enables the fields where the user has to enter information to create a project*/ void ChangeToCreateProjectDisplay(); /** \brief hides/shows the related QLabel,QLineEdit...and display the related information of the first existing project on the combobox */ void ChangeToOpenProjectDisplay(); /** \brief display the information related to the given existing project*/ void DisplayInfoProject(QString ProjectName); void AddAuthors(); void UpdateListAuthors(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoDBInitializationWizard.cxx0000644000175000017500000000466211667757442024421 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDBInitializationWizard.h" #include "CreateDataBaseHelper.h" #include "QGoDBInitCreateUserPage.h" #include "QGoDBInitCreateAuthorsPage.h" #include "QGoDBInitCreateMicroscopePage.h" QGoDBInitializationWizard::QGoDBInitializationWizard(QWidget *iParent) : QWizard(iParent) { this->m_CreateUserPage = new QGoDBInitCreateUserPage; setPage(CreateUserPageID, this->m_CreateUserPage); setPage(CreateAuthorsPageID, new QGoDBInitCreateAuthorsPage); setPage(CreateMicroscopePageID, new QGoDBInitCreateMicroscopePage); QObject::connect( this->m_CreateUserPage, SIGNAL( UserAndDatabaseCreated() ), this, SIGNAL( DatabaseAndUserCreated() ) ); }GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoDBInitializationWizard.h0000755000175000017500000000565611667757442024055 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoDBInitializationWizard_h #define __QGoDBInitializationWizard_h #include #include "CreateDataBaseHelper.h" #include "QGoGUILibConfigure.h" #include "QGoDBInitCreateUserPage.h" class QGOGUILIB_EXPORT QGoDBInitializationWizard:public QWizard { Q_OBJECT public: enum { CreateUserPageID = 0, CreateAuthorsPageID, CreateMicroscopePageID /*ConnectServerPageID = 0, CreateDataBasePageID, OpenOrCreateProjectPageID, OpenOrCreateImgSessionPageID, CreateImgSessionPageID*/ }; explicit QGoDBInitializationWizard(QWidget *parent = 0); ~QGoDBInitializationWizard() {} /*QString GetServer(); QString GetLogin(); QString GetPassword();*/ QPushButton *nextButton; protected: /*void closeEvent(QCloseEvent* iEvent); void SetFirstFileName(); QGoConnectServerPage* m_ConnectServerPage; std::string m_ImgSessionName; std::string m_FirstFileName; int m_ImgSessionID; bool m_IsAnOpenRecentFile;*/ QGoDBInitCreateUserPage *m_CreateUserPage; private: Q_DISABLE_COPY(QGoDBInitializationWizard); signals: void DatabaseAndUserCreated(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/Wizard/QGoConnectServerPage.h0000644000175000017500000000573111667757442023043 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoConnectServerPage_h #define __QGoConnectServerPage_h #include #include #include #include "vtkMySQLDatabase.h" /** * \class QGoConnectServerPage * \brief * \image html QGoConnectServerPage.png * */ class QGoConnectServerPage:public QWizardPage { Q_OBJECT public: explicit QGoConnectServerPage(QWidget *parent = 0); ~QGoConnectServerPage(); bool validatePage(); int nextId() const; mutable std::pair< bool, vtkMySQLDatabase * > m_ConnectionServer; void SetImgSessionName(std::string iImgSessionName); void SetIsAnOpenRecentFile(bool iIsAnOpenRecentFile); private: Q_DISABLE_COPY(QGoConnectServerPage); void OpenConnectionToServer() const; void CloseServerConnection() const; QLineEdit * lineServerName; QLineEdit * lineUserName; QLineEdit * linePassword; QLineEdit * lineDBName; mutable std::string m_ImgSessionName; bool m_IsAnOpenRecentFile; /** * \brief return the list of the names of the databases of * gofigure type * */ std::list< std::string > ListGofigureDatabases() const; signals: void NoGofigureDatabase() const; void GofigureDatabaseExists() const; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoTabImageView2D.h0000644000175000017500000000763111667757442020721 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTabImageView2D_h #define __QGoTabImageView2D_h class vtkImageData; class QAction; class QToolBar; class QDockWidget; class QGoImageView2D; #include "QGoTabImageViewNDBase.h" #include "QGoGUILibConfigure.h" /** \class QGoTabImageView2D \brief Element of the QTabWidget to be used to visualized 2D images. \example GUI/lib/qgotabimageview2d.cxx */ class QGOGUILIB_EXPORT QGoTabImageView2D:public QGoTabImageViewNDBase { Q_OBJECT public: explicit QGoTabImageView2D(QWidget *parent = 0); virtual ~QGoTabImageView2D(); typedef QGoTabImageViewNDBase::QGoDockWidgetStatusPair QGoDockWidgetStatusPair; GoFigure::TabDimensionType GetTabDimensionType() const; virtual void Update(); void setupUi(QWidget *parent); void retranslateUi(QWidget *parent); virtual void WriteSettings(); virtual void ReadSettings(); public slots: void ChangeLookupTable(); void ShowScalarBar(const bool &); void ChangeBackgroundColor(); void TakeSnapshot(); /** * \brief Mouse interaction style set as default */ virtual void DefaultInteractorBehavior(bool); /** * \brief Mouse interaction style allows user to zoom in/out volume with all * buttons */ virtual void ZoomInteractorBehavior(bool); /** * \brief Mouse interaction style allows user to pan volume with all buttons */ virtual void PanInteractorBehavior(bool); protected: QGoImageView2D *m_ImageView; QAction * m_TakeSnapshotAction; void GetBackgroundColorFromImageViewer(); void SetBackgroundColorToImageViewer(); void SetImageToImageViewer(vtkImageData *image); int *GetImageCoordinatesFromWorldCoordinates(double pos[3]); // std::vector< vtkQuadricLODActor* > std::vector< vtkActor * > AddContour(vtkPolyData *dataset, vtkProperty *property = NULL); QAction *m_BackgroundColorAction; virtual void RemoveActorFromViewer(const int & iId, vtkActor *iActor); virtual void DisplayActorInViewer(const int & iId, vtkActor *iActor); virtual void SetSlice(int iDir, int *iIdx); void CreateModeToolBar(QMenu* iMenu, QToolBar* iToolBar); private: Q_DISABLE_COPY(QGoTabImageView2D); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoPrintDatabase.h0000644000175000017500000010244011667757442020742 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoPrintDatabase_h #define __QGoPrintDatabase_h #include #include #include #include #include #include "MegaVTK2Configure.h" #include "GoDBRecordSet.h" #include "GoDBContourRow.h" #include "vtkMySQLDatabase.h" #include "vtkPolyData.h" #include "GoDBTraceInfoForVisu.h" #include "ContourMeshStructure.h" #include "TraceInfoStructure.h" #include "QGoDBBookmarkManager.h" #include "QGoGUILibConfigure.h" #include "GoFigureMeshAttributes.h" #include "QGoTraceSettingsWidget.h" #include "QGoDBCellTypeManager.h" #include "QGoDBSubCellTypeManager.h" #include "QGoDBColorManager.h" #include "QGoDBMeshManager.h" #include "QGoDBContourManager.h" #include "QGoDBTrackManager.h" #include "QGoDBLineageManager.h" #include "ContourContainer.h" #include "MeshContainer.h" #include "TrackContainer.h" #include "QGoDockWidget.h" /** \defgroup DB Database \defgroup GUI GUI */ /** \class QGoPrintDatabase \brief manages all the database components: table widget, trace settings editing widdet, QGoDBTraceManager... \ingroup DB GUI */ class QGOGUILIB_EXPORT QGoPrintDatabase:public QGoDockWidget { Q_OBJECT public: /** \brief Constructor */ explicit QGoPrintDatabase(QWidget *iParent = 0); /** \brief Destructor */ virtual ~QGoPrintDatabase(); typedef GoDBCollectionOfTraces::TWContainerType TWContainerType; typedef QGoDBBookmarkManager::NamesDescrContainerType NamesDescrContainerType; typedef QGoTraceSettingsWidget::ItemColorComboboxData ItemColorComboboxData; typedef std::pair< int, QColor > IDWithColorData; /** \brief set all the values needed for the database*/ void SetDatabaseVariables( const std::string & iNameDB, const std::string & iServer, const std::string & iUser, const std::string & iPassword, const unsigned int & iImgSessionID, const std::string & iImgSessionName); /** \brief Create the QTableWidgetChild,get the columns names and the * values stored in the database, display them in the QTableWidgetChild * and fill the info for the contours and meshes*/ void FillTableFromDatabase( const unsigned int& iTreshold); /** \brief Return a vector of all the contours for the given timepoint*/ std::vector< ContourMeshStructure > GetContoursForAGivenTimepoint( unsigned int iTimePoint); /** \brief Return a vector of all the meshes for the given timepoint*/ std::vector< ContourMeshStructure > GetMeshesForAGivenTimepoint( unsigned int iTimePoint); /** \brief save a new contour from the visu into the database, update the table widget and the CurrentElement of the visu container if reeditMode is set to false; if not, update the contour in the DB and in the TW, for both modes, update the mesh the contour is part of. */ void SaveContoursFromVisuInDB(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iTCoord, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iContourNodes); /** \brief save the mesh into the database for a mesh generated in the visualization, if the mesh is an updated mesh which already exists(for example a new contour is added to this mesh, the NewMesh has to be set to false \param[in] iTrackID Track ID we want the mesh to belong to. if -1, we get the track ID from the trace editing widget. */ void SaveMeshFromVisuInDB(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, int iTCoord, vtkPolyData *iMeshNodes, GoFigureMeshAttributes *iMeshAttributes, int iTrackID = -1); /** \brief save a new contour in the database, the TW and the container for the contours to sphere action \param[in] iXCoordMin xcoord of the minimum for the boundingbox \param[in] iYCoordMin ycoord of the minimum for the boundingbox \param[in] iZCoordMin zcoord of the minimum for the boundingbox \param[in] iXCoordMax xcoord of the maximum for the boundingbox \param[in] iYCoordMax ycoord of the maximum for the boundingbox \param[in] iZCoordMax zcoord of the maximum for the boundingbox \param[in] iTraceNodes nodes to be saved as points in the database \return unsigned int ID of the new created contour */ unsigned int SaveNewContourForMeshToContours(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iTraceNodes); void AddBookmark(int iXCoord, int iYCoord, int iZCoord, int iTCoord); /** \brief Return the Name of the tab currently used in the table widget, * which correspond to the TraceName of the CollectionOfTraces: */ std::string InWhichTableAreWe(); NamesDescrContainerType GetListBookmarks(); GoDBCoordinateRow GetCoordinateForBookmark(std::string iName); /** \brief return a bool to know if the user is using the database or * not*/ bool IsDatabaseUsed(); //QAction * toggleViewAction(); /** \brief get the info from a textfile, save it into the database, update the container for visu and the TW */ void ImportContours(); /** \brief get the info from a textfile, save it into the database, update the container for visu and the TW */ void ImportMeshes(); /** \brief get the info from a textfile, save it into the database, update the container for visu and the TW and recalculate the points for the tracks \return all the new trackIDs */ std::vector ImportTracks(); /** \brief display in the table widget the volume and area from iMeshAttributes for iMeshID \param[in] iMeshAttributes contains the values to be displayed \param[in] iMeshID ID of the mesh */ void PrintVolumeAreaForMesh(GoFigureMeshAttributes * iMeshAttributes, unsigned int iMeshID); /** \brief display in the table widget the values from iTrackAttributes for iTrackID \param[in] iTrackAttributes contains the values to be displayed \param[in] iTrackID ID of the track */ void PrintCalculatedValuesForTrack(GoFigureTrackAttributes * iTrackAttributes, unsigned int iTrackID); /** \brief return the TraceSettingsDockWidget*/ QGoTraceSettingsWidget* GetTraceSettingsWidget(); QGoTraceSettingsWidget* GetTraceSettingsWidgetForToolBar(); /** \brief update the traceSettingswidget for the trace with the corresponding list of collectionID and set the tablewidget for the trace table \param[in] iTraceName name of the corresponding trace */ void SetTraceNameForTableWidget(std::string iTraceName); /** \brief Initialize or reinitialized the celltype,subcelltype and color list from the database into the traceSettingswidget*/ void InitializeTheComboboxesNotTraceRelated(); /** \brief set the pointer m_TraceInfoForVisu of the ContoursManager to iContoursContainer \param[in] iContoursContainer pointer for the container of contours for the visu */ void SetContoursContainer(ContourContainer *iContoursContainer); /** \brief set the pointer m_TraceInfoForVisu of the MeshesManager to iMeshesContainer \param[in] iMeshesContainer pointer for the container of meshes for the visu */ void SetMeshesContainer(MeshContainer *iMeshesContainer); /** \brief set the pointer m_TrackInfoForVisu of the TracksManager to iTracksContainer \param[in] iContainer pointer for the container of tracks for the visu */ void SetTracksContainer(TrackContainer *iContainer); /** \brief set the pointer m_LineageInfoForVisu of the LineagesManager to iContainer \param[in] iContainer pointer for the container of lineages for the visu \Param[in] iTrackContainer pointer for the container of tracks */ void SetLineagesContainers(LineageContainer *iContainer, TrackContainer *iTrackContainer); /** \brief check if the tracesettingsWidget is visible, if not, return true. */ bool NeedTraceSettingsToolBarVisible(); /** \brief Update the table widget and the visualization container contents based on the given time point and the previous visible time points. It erases actors and remove them from the visualization. It doesn't create actors after adding polydata to container. */ std::list UpdateTableWidgetAndContainersForGivenTimePoint( const unsigned int& iNewTimePoint); std::list GetVisibleTimePoints(); int GetNumberOfElementForTraceAndTimePoint(std::string iTrace, int iTimePoint); public slots: void DeleteBookmarks(); //void SetTable(std::string iTablename); void ExportContours(); void ExportMeshes(); void UpdateSelectedTimePoint(int iTimePoint); void SaveNewMeshForMeshToContours(int iNumberOfContours); signals: void PrintDBReady(); void DBVariablesSet(); void TraceToReEdit(unsigned int); void OpenBookmarksToUpdate(); void NewMeshToGenerate(std::list< unsigned int > ListContourIDs, int iNewMeshID); /** \brief signal emitted when a signal is emitted from a m_TraceManager for "go to the trace " from the context menu */ void NeedToGoToTheLocation(int XCoord, int YCoord, int ZCoord, int TCoord); void NeedToGoToTheRealLocation(double XCoord, double YCoord, double ZCoord, int TCoord); void PrintMessage(QString iMessage, int iTimeOut = 0); protected: //related to 3dwt: int* m_SelectedTimePoint; QGoDBBookmarkManager* m_BookmarkManager; //related to TraceSettings Widget: QGoDBCellTypeManager* m_CellTypeManager; QGoDBSubCellTypeManager* m_SubCellTypeManager; QGoDBColorManager* m_ColorManager; QGoTraceSettingsWidget* m_TraceSettingsWidget; QGoTraceSettingsWidget* m_TraceSettingsWidgetForToolBar; QGoDBContourManager* m_ContoursManager; QGoDBMeshManager* m_MeshesManager; QGoDBTrackManager* m_TracksManager; QGoDBLineageManager* m_LineagesManager; QStackedWidget* m_StackedTables; //Database variables: vtkMySQLDatabase* m_DatabaseConnector; std::string m_Server; std::string m_User; std::string m_Password; std::string m_DBName; unsigned int m_ImgSessionID; std::string m_ImgSessionName; bool m_IsDatabaseUsed; bool m_ReeditMode; bool m_MeshGenerationMode; bool m_TraceSettingsVisible; void OpenDBConnection(); void SetUpUi(); /** \brief set the tracesettings widget to be in the mainwindow toolbar and the connection between the 2 instances of tracesettingswidget */ void SetConnectionsBetweenTheInstancesOfTraceSettings(); /** \brief create the m_ContoursManager and its SLOT/SIGNAL connection */ void SetContoursManager(); /** \brief create the m_MeshesManager and its SLOT/SIGNAL connection */ void SetMeshesManager(); /** \brief create the m_TracksManager and its SLOT/SIGNAL connection */ void SetTracksManager(); /** \brief create the m_LineagesManager and its SLOT/SIGNAL connection */ void SetLineagesManager(); //******************Methods related to Trace Settings Editing Widget*********** /** \brief create all the connections between the QGoPrintDatabase and the QGoTraceSettingsWidget (TS) */ void CreateConnectionsForTraceSettingsWidget(QGoTraceSettingsWidget* iTraceSettingsWidget); /** \brief get the list of celltypes from the database, put them in the Trace Settings combobox and if the string is not empty, the combobox will have as selected item the string \param[in] iCellTypeToSelect name of the celltype to be selected */ void SetTSListCellTypes(std::string iCellTypeToSelect = ""); /** \brief get the list of celltypes from the database, put them in the Trace Settings combobox and the combobox will have as selected item the one previously selected */ void SetTSListCellTypesWithPreviousSelectedOne(); /** \brief get the list of subcelltypes from the database, put them in the Trace Settings combobox and if the string is not empty, the combobox will have as selected item the string \param[in] iSubCellTypeToSelect name of the subcelltype to be selected */ void SetTSListSubCellTypes(std::string iSubCellTypeToSelect = ""); /** \brief get the list of subcelltypes from the database, put them in the Trace Settings combobox and the combobox will have as selected item the one previously selected */ void SetTSListSubCellTypesWithPreviousSelectedOne(); /** \brief get the data for the colorcombobox from the database, put them in the Trace Settings colorcombobox and if the string is not empty, the combobox will have as selected item the string \param[in] iColorToSelect name of the color to be selected in the combobox */ void SetTSListColors(std::string iColorToSelect = ""); /** \brief get the list of colors from the database, put them in the Trace Settings combobox and the combobox will have as selected item the one previously selected */ void SetTSListColorsWithPreviousSelectedOne(); //******************End of Methods related to Trace Settings Editing // Widget*********** /** \brief get the collection id with their corresponding color from the database \param[in] iDatabaseConnector connection to the database \param[in] ioIDToSelect ID to be selected in the combobox */ std::list< ItemColorComboboxData > GetListCollectionIDFromDB( vtkMySQLDatabase *iDatabaseConnector, std::string & ioIDToSelect); //void closeEvent(QCloseEvent *event); /** \brief set all the traces manager */ void SetTracesManager(); /** \brief get the data from the database for contours, meshes and tracks, display them in the TableWidget and load the different containers for the visu with the info from the database */ void GetContentAndDisplayAllTracesInfo(vtkMySQLDatabase *iDatabaseConnector); void GetContentAndDisplayAllTracesInfoFor3TPs(vtkMySQLDatabase *iDatabaseConnector); void RemoveTracesFromListTimePoints( vtkMySQLDatabase *iDatabaseConnector, std::list iListTimePoints); /** \brief get the RGB Alpha values from the iTraceRow and set a QColor with them \tparam T any children of GoDBTraceRow \param[in] iTraceRow the trace from which the QColor is created \param[in] iDatabaseConnector connection to the database \return QColor with the values corresponding to the color values of the iTraceRow */ /*template< typename T > QColor GetQColorFromTraceRow(T iTraceRow, vtkMySQLDatabase *iDatabaseConnector) { GoDBColorRow ColorRow; ColorRow.SetValuesForSpecificID(iTraceRow.GetMapValue("ColorID"), iDatabaseConnector); QColor Color( ColorRow.GetMapValue("Red"), ColorRow.GetMapValue("Green"), ColorRow.GetMapValue("Blue"), ColorRow.GetMapValue("Alpha") ); return Color; } */ /** \brief set the color of the traceRow according to the iColor \param[in,out] ioRow traceRow with the color to be set up \param[in] iColor color for the traceRow \tparam T children of GoDBTraceRow */ template< typename T > void SetTheColorForTheRow(T & ioRow, QColor iColor) { ioRow.SetField( "Red", iColor.red() ); ioRow.SetField( "Green", iColor.green() ); ioRow.SetField( "Blue", iColor.blue() ); ioRow.SetField( "Alpha", iColor.alpha() ); } /** \brief update the color for the checked traces and the rows in the table widget for the collectionOf \param[in] iTraceManager manager for the trace (expl: mesh) \param[in] iCollectionOfManager manager for the collectionOf (expl:contour) \tparam TTrace children of QGoDBTraceManager \tparam TCollection children of QGoDBTraceManager */ template< typename TTrace, typename TCollection > void ChangeTraceColor(TTrace *iTraceManager, TCollection *iCollectionOfManager) { this->OpenDBConnection(); //update everything for the traces and get the list of collection ID they //are collection of: std::list< unsigned int > ListCollectionOfIDsToUpdate = iTraceManager->UpdateTheTracesColor(this->m_DatabaseConnector);//, *this->m_SelectedColorData); iCollectionOfManager->DisplayInfoForExistingTraces(this->m_DatabaseConnector, ListCollectionOfIDsToUpdate); this->CloseDBConnection(); } /** todo once lineage container is set up, the bool track needs to be removed*/ /** \brief delete the checked traces from the database,TW,visu container, udpate the collectionof collectionID in database and TW and update the bounding box of the collection \param[in] iTraceManager the manager for the trace expl: mesh_manager \param[in] iCollectionManager the manager for the collection expl: track \param[in] iCollectionOfManager the manager for the collectioof expl: contour \param[in] track if the trace is track, track is set to true \tparam TTrace children of QGoDBTraceManager \tparam TCollection children of QGoDBTraceManager */ template< typename TTrace, typename TCollection, typename TCollectionOf > void DeleteCheckedTraces(TTrace *iTraceManager, TCollection *iCollectionManager, TCollectionOf *iCollectionOfManager, bool lineage = false) //bool track = false) { std::list< unsigned int > ListTracesToDelete = iTraceManager->GetListHighlightedIDs(); std::list ListCollectionsIDs = this->UpdateCollectionDataForTracesToBeDeleted (iTraceManager, iCollectionOfManager, ListTracesToDelete); this->OpenDBConnection(); iTraceManager->DeleteCheckedTraces(this->m_DatabaseConnector); if ( !ListCollectionsIDs.empty() || !lineage ) { this->OpenDBConnection(); //in some cases the DeleteCheckedTraces closes the connection iCollectionManager->UpdateBoundingBoxes(this->m_DatabaseConnector, ListCollectionsIDs); } this->CloseDBConnection(); } /** \brief delete the traces of iListTracesToDelete from the database,TW, visu container, udpate the collectionof collectionID in database and TW and update the bounding box of the collection \param[in] iTraceManager the manager for the trace expl: mesh_manager \param[in] iCollectionManager the manager for the collection expl: track \param[in] iCollectionOfManager the manager for the collectioof expl: contour \param[in] iListTracesToDelete list of the traceIDs to be deleted \param[in] track if the trace is track, track is set to true \tparam TTrace children of QGoDBTraceManager \tparam TCollection children of QGoDBTraceManager */ template< typename TTrace, typename TCollection, typename TCollectionOf > void DeleteListTraces(TTrace *iTraceManager, TCollection *iCollectionManager, TCollectionOf *iCollectionOfManager, std::list iListTracesToDelete, bool lineage = false) { std::list ListCollectionsIDs = this->UpdateCollectionDataForTracesToBeDeleted (iTraceManager, iCollectionOfManager, iListTracesToDelete); this->OpenDBConnection(); iTraceManager->DeleteListTraces(this->m_DatabaseConnector, iListTracesToDelete); if ( !ListCollectionsIDs.empty() || !lineage ) { iCollectionManager->UpdateBoundingBoxes(this->m_DatabaseConnector, ListCollectionsIDs); } this->CloseDBConnection(); } /** \brief udpate the collectionof collectionID in database and TW \param[in] iTraceManager the manager for the trace expl: mesh_manager \param[in] iCollectionOfManager the manager for the collectioof expl: contour \param[in] iListTracesToDelete list of the traceIDs to be deleted \tparam TTrace children of QGoDBTraceManager \tparam TCollectionOf children of QGoDBTraceManager */ template< typename TTrace, typename TCollectionOf > std::list UpdateCollectionDataForTracesToBeDeleted(TTrace *iTraceManager, TCollectionOf *iCollectionOfManager, std::list iListTracesToDelete) { this->OpenDBConnection(); //need to get all the needed data from the traces before deleting them: std::list< unsigned int > ListCollectionsIDs = iTraceManager->GetListCollectionIDs(this->m_DatabaseConnector, iListTracesToDelete); std::list< unsigned int > ListTracesAsCollectionOf = iTraceManager->GetListTracesIDsFromThisCollectionOf(this->m_DatabaseConnector, iListTracesToDelete); if ( !ListTracesAsCollectionOf.empty() ) { iCollectionOfManager->UpdateCollectionID(this->m_DatabaseConnector, ListTracesAsCollectionOf, 0); } this->CloseDBConnection(); return ListCollectionsIDs; } /** \brief change the collectionIDs to iCollectionID for the traces in iListCheckedTraces, and update the bounding boxes of the previous collection the traces were part of and of iCollectionID in the database, the TW and the container for visu \param[in] iTraceManager the manager for the trace expl: mesh_manager \param[in] iCollectionManager the manager for the collection expl: track \param[in] iCollectionID the ID of the collection the checked traces will be part of \param[in] iListCheckedTraces List of the tracesIDs checked in the TW \tparam TTrace children of QGoDBTraceManager \tparam TCollection children of QGoDBTraceManager */ template< typename TTrace, typename TCollection > void AddCheckedTracesToCollection( TTrace *iTraceManager, TCollection *iCollectionManager, unsigned int iCollectionID, std::list< unsigned int > iListCheckedTraces) { this->OpenDBConnection(); //get the list of CollectionIDs that will be updated: std::list< unsigned int > ListCollectionIDsToUpdate = iTraceManager->GetListCollectionIDs(this->m_DatabaseConnector, iListCheckedTraces); iTraceManager->UpdateCollectionID(this->m_DatabaseConnector, iListCheckedTraces, iCollectionID); if (iCollectionID != 0) { ListCollectionIDsToUpdate.push_back(iCollectionID); } iCollectionManager->UpdateBoundingBoxes(this->m_DatabaseConnector, ListCollectionIDsToUpdate); this->CloseDBConnection(); } void UpdateSelectedCollectionForTableWidget(std::string iTableName); //------------------------------------------------------------------------- //------------------------------------------------------------------------- protected slots: void CreateContextMenu(const QPoint & iPos); /** \brief show/hide the Trace Settings widget depending on the checkstate of the action in the context menu of the dockwidget */ void ShowHideTraceSettingsFromContextMenu(bool isVisible); /** \brief slot connected to the combobox for the trace in the trace settings widget */ void TheTraceHasChanged(int iIndex); /** \brief get a list of the IDs with their colors for the collection corresponding to the tracename, for the given timepoint if the collection is a mesh or for all timepoints for tracks and lineages, update the Trace Settings colorcombobox and select the corresponding ID in the combobox if the string is not empty */ void SetTSListCollectionID(); /** \brief open the connection to the database and pass it to the ContoursManager */ void PassDBConnectionToContoursManager(); /** \brief open the connection to the database and pass it to the MeshesManager */ void PassDBConnectionToMeshesManager(); /** \brief open the connection to the database and pass it to the TracksManager */ void PassDBConnectionToTracksManager(); /** \brief open the connection to the database and pass it to the LineagesManager */ void PassDBConnectionToLineagesManager(); void CloseDBConnection(); /** \brief slot connected to the TraceColorToChange() emitted by the m_MeshesManager */ void ChangeMeshColor(); /** \brief slot connected to the TraceColorToChange() emitted by the m_MeshesManager */ void ChangeTrackColor(); /** \brief slot connected to the TraceColorToChange() emitted by the m_MeshesManager */ void ChangeLineageColor(); /** \brief slot connected to the signal TracesToDelete() emitted by the m_ContoursManager */ void DeleteCheckedContours(); /** \brief slot connected to the signal Traces TracesToDelete() emitted by the m_MeshesManager */ void DeleteCheckedMeshes(); /** \brief slot connected to the signal TracesToDelete() emitted by the m_TracksManager */ void DeleteCheckedTracks(); /** \brief slot connected to the signal TracesToDelete() emitted by the m_LineagesManager */ void DeleteCheckedLineages(); /** \brief create a new track and call the AddCheckedTracesToCollection template method to add the meshes from the list to this new track \param[in] iListMeshes list of the meshIDs to belong to the new track */ void CreateNewTrackFromListMeshes(std::list< unsigned int > iListMeshes); /** \overload */ void CreateNewTrackFromListMeshes( std::list > iListsCheckedMeshes); /** \brief slot connected to the signal NewCollectionFromCheckedTraces() emitted by the m_ContoursManager, emit the signal NewMeshToGenerate for the visu after creating a new mesh and calling the AddCheckedTracesToCollection template method. \param[in] iListCheckedContours list of the meshIDs of the checked meshes in the TW */ void CreateNewMeshFromCheckedContours(std::list< unsigned int > iListCheckedContours); /** \brief slot connected to the signal NewLineageToCreateFromTracks() emitted by the m_TracksManager \param[in] iListTracks list of the tracksIDs to be part of the new lineage \param[in] iTrackIDRoot ID of the track to be the root of the new lineage to be created \param[in] iLineagesToDelete */ void CreateNewLineageFromTracks(std::list< unsigned int > iListCheckedTracks, unsigned int iTrackIDRoot, std::list iLineagesToDelete); /** \brief slot connected to the the signal CheckedTracesToAddToSelectedCollection emitted by m_ContoursManager, which call the AddCheckedTracesToCollection template \param[in] iListCheckedContours list of the checked contours to be part of the selected meshID */ void AddCheckedContoursToSelectedMesh(std::list< unsigned int > iListCheckedContours); /** \brief slot connected to the the signal CheckedTracesToAddToSelectedCollection emitted by m_MeshesManager, which call the AddCheckedTracesToCollection template \param[in] iListCheckedMeshes list of the checked meshes to be part of the selected trackID */ void AddCheckedMeshesToSelectedTrack(std::list< unsigned int > iListCheckedMeshes); /** \brief call the AddCheckedTracesToCollection template and give the info to the lineages manager to create the division in the visu \param[in] iLineageID \param[in] iListDaughters ID of the tracks to be updated with lineageID \param[in] iListLineagesToDelete list of lineageID that need to be deleted as they don't have any tracks belonging to them anymore */ void AddCheckedTracksToSelectedLineage( std::list iListDaughters, unsigned int iLineageID, std::list iListLineagesToDelete); /** \brief emit a signal TraceToReedit and set m_ReeditMode to true \param[in] iTraceID ID of the trace to reedit */ void ReEditTrace(unsigned int iTraceID); /** \brief get the info needed for track from the meshcontainer, and update the points of the track container (for imported tracks) \param[in] iTrackID track ID for which the points will be recalculated */ void PassMeshesInfoForImportedTrack(unsigned int iTrackID); /** \brief split the checked track: a new track is created with the checked mesh and the meshes with timepoint sup and the checked track is updated. \param[in] iTrackID ID for the checked track \param[in] iListMeshIDs meshes belonging to the iTrackID before the split */ void SplitTheTrack(unsigned int iTrackID, std::list iListMeshIDs); /** \brief slot called after signal TrackIDToBeModifiedWithWidget sent by tracksManager, display the checked tracks in a widget allowing the user to split and merge them and save the results in the database if the user clicks the OK button \param[in] iTrackIDs checked tracks */ void SplitMergeTracksWithWidget(std::list iTrackIDs); /** \brief add the meshes to the iTrackID after checking that there are no meshes at the same timepoint in the same track, if so, won't change the trackid of these meshes \param[in] iListMeshes list of the meshes to be part of the itrackID \param[in] iTrackID new track to be assigned to these meshes */ void AddListMeshesToATrack(std::list< unsigned int > iListMeshes, unsigned int iTrackID); /** \overload */ void AddListMeshesToATrack( std::map > iListMeshesWithTracks); //*********************Slots for // TraceManualEditingWidget:************************** /** \brief Add the new collection in the database,add a row in TW and update the colorcombobox */ void SaveNewCollectionFromTraceWidgetInDBAndTW(); /** \brief call the m_CellTypeManager to add a new celltype (ask the user to enter name+description and save it in the database) and call the setListCelltype to update the list in the TraceManualEditingWidget */ void AddNewCellType(); /** \brief call the m_SubCellTypeManager to add a new subcelltype (ask the user to enter name+description and save it in the database) and call the setListSubCelltype to update the list in the TraceManualEditingWidget */ void AddNewSubCellType(); /** \brief call the m_ColorManager to add a new color (ask the user to choose the color +enter name+description and save it in the database) and call the SetColorComboBoxInfofromDB to update the list in the TraceManualEditingWidget */ void AddNewColor(); /** \brief call the m_CellTypeManager to delete celltypes (display all the celltypes for the user to select the ones he wants to delete and delete them from the database) and call the setListCelltype to update the list in the TraceManualEditingWidget */ void DeleteCellType(); /** \brief call the m_SubCellTypeManager to delete subcelltypes (display all the subcelltypes for the user to select the ones he wants to delete and delete them from the database) and call the setListSubCelltype to update the list in the TraceManualEditingWidget */ void DeleteSubCellType(); /** \brief call the m_ColorManager to delete colors (display all the colors for the user to select the ones he wants to delete and delete them from the database) and call the SetColorComboBoxInfofromDB to update the list in the TraceManualEditingWidget */ void DeleteColor(); //**********************End TraceSettingsWidget slots // related**************** private: std::list m_VisibleTimePoints; Q_DISABLE_COPY(QGoPrintDatabase); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoDockWidgetStatus.cxx0000644000175000017500000001132611667757442022026 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDockWidgetStatus.h" #include QGoDockWidgetStatus::QGoDockWidgetStatus(QGoDockWidget *iW) : QObject(iW), m_DockWidget(iW), m_Area(Qt::LeftDockWidgetArea), m_DefaultArea(Qt::LeftDockWidgetArea), m_Visibility(true), m_Attached(true) { this->SetConnections(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoDockWidgetStatus::QGoDockWidgetStatus(const QGoDockWidgetStatus & iS) : QObject(iS.m_DockWidget), m_Area(iS.m_Area), m_DefaultArea(iS.m_Area), m_Visibility(iS.m_Visibility), m_Attached(iS.m_Attached), m_MainWindow(iS.m_MainWindow) { this->SetConnections(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoDockWidgetStatus::QGoDockWidgetStatus(QGoDockWidget *iW, Qt::DockWidgetArea iArea, const bool & iVisibility, const bool & iAttached, QMainWindow* iMainWindow) : QObject(iW), m_DockWidget(iW), m_Area(iArea), m_DefaultArea(iArea), m_Visibility(iVisibility), m_Attached(iAttached), m_MainWindow(iMainWindow) { this->SetConnections(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoDockWidgetStatus:: ~QGoDockWidgetStatus() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoDockWidgetStatus::SetConnections() { QObject::connect( m_DockWidget, SIGNAL( dockLocationChanged(Qt::DockWidgetArea) ), this, SLOT( SetArea(Qt::DockWidgetArea) ) ); //QObject::connect( m_DockWidget, SIGNAL( visibilityChanged(bool) ), // this, SLOT( SetVisibility(bool) ) ); QObject::connect(m_DockWidget->toggleViewAction(), SIGNAL(toggled(bool) ), this, SLOT(SetVisibility(bool) ) ); QObject::connect(m_DockWidget, SIGNAL(topLevelChanged (bool) ), this, SLOT( SetAttached(bool) ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoDockWidgetStatus::SetArea(Qt::DockWidgetArea iArea) { m_Area = iArea; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoDockWidgetStatus::SetVisibility(bool iVisibility) { m_Visibility = iVisibility; this->m_DockWidget->setVisible(iVisibility); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoDockWidgetStatus::SetAttached(bool iAttached) { m_Attached = iAttached; } GoFigure2-v0.9.0/Code/GUI/lib/QGoLineageViewDockWidget.h0000755000175000017500000000471511667757442022376 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoLineageViewDockWidget_h #define __QGoLineageViewDockWidget_h #include #include #include "QGoDockWidget.h" #include "QGoGUILibConfigure.h" //#include "ui_LineageViewDockWidget.h" class QGOGUILIB_EXPORT QGoLineageViewDockWidget: public QGoDockWidget//, //protected Ui::LineageViewDockWidget { Q_OBJECT public: explicit QGoLineageViewDockWidget(QWidget *iParent = 0); ~QGoLineageViewDockWidget(); public slots: void ColorCodeLineagesByDepth(bool); void ColorCodeLineagesByOriginalColor(bool); signals: void ChangeDivisionsColorCode(const QString &); protected: void SetUpUi(); QRadioButton* m_depthLineage; QRadioButton* m_real; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoTabImageView3DwT.cxx0000644000175000017500000036235411667757442021616 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTabImageView3DwT.h" #include "QShortcut" #include "QDebug" #include "QShortcut" #include "QGoImageView3D.h" //#include "QGoLUTDialog.h" #include "QGoNavigationDockWidget.h" #include "QGoTransferFunctionDockWidget.h" #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) #include "QGoVideoRecorder.h" #endif /* ENABLEVIDEORECORD */ #include "SnapshotHelper.h" #include "GoDBContourRow.h" #include "GoDBCoordinateRow.h" #include "GoDBMeshRow.h" #include "vtkLSMReader.h" #include "vtkImageData.h" #include "vtkActor.h" #include "vtkLookupTable.h" #include "vtkImageAppendComponents.h" #include "vtkOrientedGlyphContourRepresentation.h" #include "vtkContourWidget.h" #include "vtkProperty.h" #include "vtkPolyData.h" #include "vtkImageActorPointPlacer.h" #include "SelectQueryDatabaseHelper.h" #include "ConvertToStringHelper.h" #include "vtkViewImage2D.h" #include "vtkCellArray.h" #include "vtkMath.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkOutlineFilter.h" //VTK FILTERS #include "vtkImageExport.h" //ITK FILTERS #include "itkvtkPolyDataToGoFigureMeshAttributes.h" #include "ContourToMeshFilter.h" #include "GoFigureMeshAttributes.h" #include #include #include #include #include #include #include #include "vtkBox.h" #include "vtkClipPolyData.h" #include // base segmentation dock widgets #include "QGoMeshEditingWidgetManager.h" #include "QGoContourEditingWidgetManager.h" // track dockwidget #include "QGoTrackViewDockWidget.h" // lineage dockwidget #include "QGoLineageViewDockWidget.h" // lineage viwer #include "QGoLineageViewerWidget.h" // image processors #include "GoMegaImageProcessor.h" #include "GoLSMImageProcessor.h" // transfer function editor #include "GoTransferFunctionEditorWidget.h" //------------------------------------------------------------------------- QGoTabImageView3DwT::QGoTabImageView3DwT(QWidget *iParent) : QGoTabElementBase(iParent), m_ImageProcessor(NULL), m_BackgroundColor(Qt::black), m_TraceSettingsToolBar(NULL), m_IntersectionLineWidth(2.), m_PCoord(0), m_RCoord(0), m_CCoord(0), m_XTileCoord(0), m_YTileCoord(0), m_ZTileCoord(0), m_TCoord(-1), m_MeshEditingWidget(NULL), m_Seeds( 3 ) { m_Seeds[0] = vtkPoints::New(); m_Seeds[1] = vtkPoints::New(); m_Seeds[2] = vtkPoints::New(); m_VolumeRenderingEnabled = false; m_HighlightedContoursProperty = vtkProperty::New(); m_HighlightedContoursProperty->SetColor(1., 0., 0.); m_HighlightedContoursProperty->SetOpacity(1.); m_HighlightedContoursProperty->SetLineWidth(3.); m_HighlightedMeshesProperty = vtkProperty::New(); m_HighlightedMeshesProperty->SetColor(1., 0., 0.); m_HighlightedMeshesProperty->SetOpacity(1.); m_HighlightedMeshesProperty->SetSpecular(0.6); m_HighlightedMeshesProperty->SetLineWidth(3.); m_HighlightedMeshesProperty->SetInterpolationToPhong(); m_IntersectionLineWidth = 2.; setupUi(this); m_MegaCaptureReader = itk::MegaCaptureReader::New(); m_ContourContainer = new ContourContainer(this, this->m_ImageView); m_ContourContainer->SetHighlightedProperty(m_HighlightedContoursProperty); m_ContourContainer->SetIntersectionLineWidth(m_IntersectionLineWidth); m_MeshContainer = new MeshContainer(this, this->m_ImageView); m_MeshContainer->SetHighlightedProperty(m_HighlightedMeshesProperty); m_MeshContainer->SetIntersectionLineWidth(m_IntersectionLineWidth); m_TrackContainer = new TrackContainer(this, this->m_ImageView); m_TrackContainer->SetHighlightedProperty(m_HighlightedMeshesProperty); m_TrackContainer->SetIntersectionLineWidth(m_IntersectionLineWidth); m_LineageContainer = new LineageContainer(this, this->m_ImageView); CreateVisuDockWidget(); // create TF dockwidget m_TransferFunctionDockWidget = new QGoTransferFunctionDockWidget(this); // track dock widget m_TrackViewDockWidget = new QGoTrackViewDockWidget(this); this->m_TrackViewDockWidget->setObjectName("TrackViewDockWidget"); QObject::connect( m_TrackViewDockWidget, SIGNAL( ChangeColorCode(const QString&) ), m_TrackContainer, SLOT( ChangeColorCode(const QString&) ) ); QObject::connect( m_TrackViewDockWidget, SIGNAL( UpdateTracksRepresentation(const double&, const double&, const double&) ), m_TrackContainer, SLOT( UpdateTracksRepresentation(const double&, const double&, const double&) ) ); // lineage dock widget m_LineageViewDockWidget = new QGoLineageViewDockWidget(this); this->m_LineageViewDockWidget->setObjectName("LineageViewDockWidget"); QObject::connect( m_LineageViewDockWidget, SIGNAL( ChangeDivisionsColorCode(const QString&) ), m_TrackContainer, SLOT( ChangeDivisionsColorCode(const QString&) ) ); // lineage viewer m_QGoLineageViewerWidget = new QGoLineageViewerWidget(NULL); m_QGoLineageViewerWidget->setObjectName("QGoLineageViewerWidget"); CreateDataBaseTablesConnection(); #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) CreateVideoRecorderWidget(); #endif CreateAllViewActions(); CreateToolsActions(); CreateBookmarkActions(); ReadSettings(); m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus( m_NavigationDockWidget, Qt::RightDockWidgetArea, false, true, this), m_NavigationDockWidget) ); m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus( m_TransferFunctionDockWidget, Qt::RightDockWidgetArea, false, true, this), m_TransferFunctionDockWidget) ); m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus(this->m_TrackViewDockWidget, Qt::LeftDockWidgetArea, false, true, this), this->m_TrackViewDockWidget) ); m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus(this->m_LineageViewDockWidget, Qt::LeftDockWidgetArea, false, true, this), this->m_LineageViewDockWidget) ); m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus(this->m_DataBaseTables, Qt::TopDockWidgetArea, false, true, this), this->m_DataBaseTables) ); #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus(m_VideoRecorderWidget, Qt::LeftDockWidgetArea, false, true, this), m_VideoRecorderWidget) ); #endif SetUpShortcuts(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoTabImageView3DwT:: ~QGoTabImageView3DwT() { m_HighlightedContoursProperty->Delete(); m_HighlightedMeshesProperty->Delete(); m_Seeds[0]->Delete(); m_Seeds[1]->Delete(); m_Seeds[2]->Delete(); unsigned int minch = m_MegaCaptureReader->GetMinChannel(); unsigned int maxch = m_MegaCaptureReader->GetMaxChannel(); for( unsigned int i = minch; i < maxch + 1; i++ ) { vtkImageData *temp = m_MegaCaptureReader->GetOutput(i); if ( temp ) { temp->Delete(); temp = NULL; } } if ( m_ContourContainer ) { delete m_ContourContainer; } if ( m_MeshContainer ) { delete m_MeshContainer; } if ( m_TrackContainer ) { delete m_TrackContainer; } if ( m_LineageContainer) { delete m_LineageContainer; } if(m_ImageProcessor) { delete m_ImageProcessor; } if( m_QGoLineageViewerWidget) { delete m_QGoLineageViewerWidget; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::UpdateSeeds() { for( size_t id = 0; id < m_Seeds.size(); id++ ) { m_Seeds[id]->Initialize(); } m_ImageView->GetSeeds( m_Seeds ); } //------------------------------------------------------------------------- std::vector< QString > QGoTabImageView3DwT::GetChannelNames() { // build channel vector unsigned int numberOfChannels = m_ImageProcessor->getNumberOfChannels(); std::vector< QString > channelNames; channelNames.resize( numberOfChannels ); for(unsigned int i =0; igetChannelName(i)); } return channelNames; } //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateContourEditingDockWidget( int iTimeMin, int iTimeMax) { //---------------------------------------------------------------- // Create base contour segmentation dock widget: // basic interactor connections //---------------------------------------------------------------- std::vector< QString > channelNames = this->GetChannelNames(); this->m_ContourEditingWidget = new QGoContourEditingWidgetManager( channelNames, iTimeMin, iTimeMax, &m_Seeds, m_ImageProcessor, &m_TCoord, this); this->CreateConnectionsTraceEditingWidget( iTimeMin, iTimeMax, this->m_ContourEditingWidget); // signals from the manual segmentation QObject::connect( m_ContourEditingWidget, SIGNAL( ManualSegmentationActivated(bool) ), this, SLOT( ManualInteractorBehavior(bool) ) ); QObject::connect( this->m_ContourEditingWidget, SIGNAL( ContourValidated(int) ), this, SLOT( ValidateContour(int) ) ); QObject::connect( this->m_ContourEditingWidget, SIGNAL( reinitializeContour() ), m_ImageView, SLOT( ReinitializeContourWidget() ) ); QObject::connect( this->m_ContourEditingWidget, SIGNAL( changeContourRepresentationProperty(float, QColor, QColor, QColor) ), m_ImageView, SLOT( UpdateContourRepresentationProperties(float, QColor, QColor, QColor) ) ); QObject::connect( this->m_ContourEditingWidget, SIGNAL(TracesCreatedFromAlgo(std::vector, int) ), this, SLOT( SaveInDBAndRenderContourForVisu(std::vector, int) ) ); this->m_ContourEditingWidget->InitializeSettingsForManualMode(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateMeshEditingDockWidget(int iTimeMin, int iTimeMax) { //---------------------------------------------------------------- // Create base contour segmentation dock widget: // basic interactor connections //---------------------------------------------------------------- // build channel vector std::vector< QString > channelNames = this->GetChannelNames(); this->m_MeshEditingWidget = new QGoMeshEditingWidgetManager( channelNames, iTimeMin, iTimeMax, &m_Seeds, m_ImageProcessor, &m_TCoord, this); this->CreateConnectionsTraceEditingWidget( iTimeMin, iTimeMax, this->m_MeshEditingWidget); QObject::connect( this->m_MeshEditingWidget, SIGNAL(TracesCreatedFromAlgo(std::vector, int) ), this, SLOT( SaveInDBAndRenderMeshForVisu(std::vector, int) ) ); QObject::connect( this->m_MeshEditingWidget, SIGNAL(TracesSplittedFromAlgo(std::vector) ), this, SLOT( SplitInDBAndRenderMeshForVisu(std::vector) ) ); QObject::connect( this->m_MeshEditingWidget, SIGNAL(TracesMergedFromAlgo(vtkPolyData *)), this, SLOT( MergeInDBAndRenderMeshForVisu(vtkPolyData * ) )); /** \todo connect the signal, reimplement the slot*/ QObject::connect( this->m_MeshEditingWidget, SIGNAL(SetOfContoursFromAlgo(std::vector >, int) ), this, SLOT(SaveInDBAndRenderSetOfContoursForVisu(std::vector >, int))); QObject::connect( this, SIGNAL( TimePointChanged(int) ), this, SLOT(UpdateTracesEditingWidget() ) ); QObject::connect( this->m_MeshEditingWidget, SIGNAL(RequestPolydatas() ), this, SLOT( PolydatasRequested() ) ); QObject::connect( this, SIGNAL( RequestedPolydatas(std::list< vtkPolyData* >) ), this->m_MeshEditingWidget, SLOT( RequestedPolydatas(std::list< vtkPolyData* >) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::ManualInteractorBehavior(bool iVisible) { DefaultInteractorBehavior(iVisible); this->m_ImageView->EnableContourWidget(iVisible); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SeedInteractorBehavior(bool iVisible) { DefaultInteractorBehavior(iVisible); this->m_ImageView->EnableSeedWidget(iVisible); } //------------------------------------------------------------------------- void QGoTabImageView3DwT::DefaultInteractorBehavior(bool iVisible) { if ( iVisible ) { this->m_ImageView->DefaultMode(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::ZoomInteractorBehavior(bool iVisible) { if ( iVisible ) { this->m_ImageView->ZoomMode(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::TranslateInteractorBehavior(bool iVisible) { if ( iVisible ) { // pan is translate now, for consistency with the shortcuts this->m_ImageView->PanMode(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::ActorPickingInteractorBehavior(bool iVisible) { if ( iVisible ) { this->m_ImageView->ActorPickingMode(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::DistanceWidgetInteractorBehavior(bool iActive) { this->m_ImageView->EnableDistanceWidget(iActive); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::AngleWidgetInteractorBehavior(bool iActive) { this->m_ImageView->EnableAngleWidget(iActive); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::Box3DPicking(bool iActive) { this->m_ImageView->EnableBoxWidget(iActive); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::PlaneWidgetInteractorBehavior(bool iActive) { this->m_ImageView->EnablePlaneWidget(iActive); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateVisuDockWidget() { /** * \todo update annotation on current slice (i.e. slice x/23) when moving through * x via this dockwidget */ m_NavigationDockWidget = new QGoNavigationDockWidget(this, GoFigure::THREE_D_WITH_T); QObject::connect( m_NavigationDockWidget, SIGNAL( XSliceChanged(int) ), this, SLOT( SetSliceViewYZ(int) ) ); QObject::connect( this, SIGNAL( SliceViewYZChanged(int) ), m_NavigationDockWidget, SLOT( SetXSlice(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( YSliceChanged(int) ), this, SLOT( SetSliceViewXZ(int) ) ); QObject::connect( this, SIGNAL( SliceViewXZChanged(int) ), m_NavigationDockWidget, SLOT( SetYSlice(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( ZSliceChanged(int) ), this, SLOT( SetSliceViewXY(int) ) ); QObject::connect( this, SIGNAL( SliceViewXYChanged(int) ), m_NavigationDockWidget, SLOT( SetZSlice(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( TSliceChanged(int) ), this, SLOT( SetTimePoint(int) ) ); QObject::connect( this, SIGNAL( TimePointChanged(int) ), m_NavigationDockWidget, SLOT( SetTSlice(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( ModeChanged(int) ), this, SLOT( ModeChanged(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( StepChanged(int) ), this, SLOT( StepChanged(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( DopplerSizeChanged(int) ), this, SLOT( DopplerSizeChanged(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( visibilityChanged(QString, bool) ), this, SLOT( visibilityChanged(QString, bool) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateDataBaseTablesConnection() { QObject::connect ( this->m_DataBaseTables, SIGNAL( DBVariablesSet() ), this, SLOT( SetDatabaseContainersAndDelayedConnections() ) ); //in order also, to update the list of meshes in the collectionIDs when //the trace is contour and to update the show/hide contours and meshes QObject::connect( this, SIGNAL( TimePointChanged(int) ), this->m_DataBaseTables, SLOT( UpdateSelectedTimePoint(int) ) ); QObject::connect( this->m_DataBaseTables, SIGNAL( TraceToReEdit(unsigned int) ), this, SLOT( ReEditContour(unsigned int) ) ); QObject::connect( this->m_DataBaseTables, SIGNAL( NewMeshToGenerate(std::list< unsigned int >, int) ), this, SLOT( CreateMeshFromSelectedContours(std::list< unsigned int >, int) ) ); QObject::connect( this->m_DataBaseTables, SIGNAL( NeedToGoToTheLocation(int, int, int, int) ), this, SLOT( GoToLocation(int, int, int, int) ) ); QObject::connect( this->m_DataBaseTables, SIGNAL( NeedToGoToTheRealLocation(double, double, double, int) ), this, SLOT( GoToRealLocation(double, double, double, int) ) ); QObject::connect( this->m_DataBaseTables->toggleViewAction(), SIGNAL (toggled(bool) ), this, SLOT(SetTraceSettingsToolBarVisible(bool) ) ); this->m_TraceSettingsWidget = this->m_DataBaseTables->GetTraceSettingsWidget(); //this->m_TraceSettingsWidgetForToolBar = this->m_DataBaseTables->GetTraceSettingsWidgetForToolBar(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetDatabaseContainersAndDelayedConnections() { this->SetTheContainersForDB(); QObject::connect( this->m_DataBaseTables, SIGNAL( PrintMessage(QString, int) ), this->m_StatusBar, SLOT( showMessage(QString, int) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetTheContainersForDB() { m_DataBaseTables->SetContoursContainer(m_ContourContainer); m_DataBaseTables->SetMeshesContainer(m_MeshContainer); m_DataBaseTables->SetTracksContainer(m_TrackContainer); m_DataBaseTables->SetLineagesContainers(m_LineageContainer, m_TrackContainer); } //------------------------------------------------------------------------- #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateVideoRecorderWidget() { m_VideoRecorderWidget = new QGoVideoRecorder(this); QObject::connect( this, SIGNAL( FullScreenViewChanged(int) ), this, SLOT( SetRendererWindow(int) ) ); QObject::connect( m_VideoRecorderWidget, SIGNAL( XSliceChanged(int) ), this, SLOT( SetSliceViewYZ(int) ) ); QObject::connect( m_VideoRecorderWidget, SIGNAL( YSliceChanged(int) ), this, SLOT( SetSliceViewXZ(int) ) ); QObject::connect( m_VideoRecorderWidget, SIGNAL( ZSliceChanged(int) ), this, SLOT( SetSliceViewXY(int) ) ); QObject::connect( m_VideoRecorderWidget, SIGNAL( TSliceChanged(int) ), this, SLOT( SetTimePoint(int) ) ); QObject::connect( m_VideoRecorderWidget, SIGNAL( GetSliceView() ), this, SLOT( SetSliceView() ) ); } //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetRendererWindow(int iValue) { if ( iValue >= 1 ) { m_VideoRecorderWidget->SetRenderingWindow( m_ImageView->GetInteractor(iValue - 1)->GetRenderWindow() ); } else { m_VideoRecorderWidget->SetRenderingWindow(NULL); } } #endif /* ENABLEVIDEORECORD */ //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateAllViewActions() { QAction *separator1 = new QAction(this); separator1->setSeparator(true); this->m_ViewNoToolBarActions.push_back(separator1); QActionGroup *group = new QActionGroup(this); QAction *QuadViewAction = new QAction(tr("Quad-View"), this); QuadViewAction->setCheckable(true); QuadViewAction->setChecked(true); QIcon quadviewicon; quadviewicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/4views.png") ), QIcon::Normal, QIcon::Off); QuadViewAction->setIcon(quadviewicon); group->addAction(QuadViewAction); this->m_ViewActions.push_back(QuadViewAction); QObject::connect( QuadViewAction, SIGNAL( triggered() ), this, SLOT( Quadview() ) ); QAction *FullScreenXYAction = new QAction(tr("Full-Screen XY"), this); FullScreenXYAction->setCheckable(true); QIcon xyicon; xyicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/xy.png") ), QIcon::Normal, QIcon::Off); FullScreenXYAction->setIcon(xyicon); group->addAction(FullScreenXYAction); this->m_ViewActions.push_back(FullScreenXYAction); QObject::connect( FullScreenXYAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewXY() ) ); QAction *FullScreenXZAction = new QAction(tr("Full-Screen XZ"), this); FullScreenXZAction->setCheckable(true); QIcon xzicon; xzicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/zx.png") ), QIcon::Normal, QIcon::Off); FullScreenXZAction->setIcon(xzicon); group->addAction(FullScreenXZAction); this->m_ViewActions.push_back(FullScreenXZAction); QObject::connect( FullScreenXZAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewXZ() ) ); QAction *FullScreenYZAction = new QAction(tr("Full-Screen YZ"), this); FullScreenYZAction->setCheckable(true); QIcon yzicon; yzicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/yz.png") ), QIcon::Normal, QIcon::Off); FullScreenYZAction->setIcon(yzicon); group->addAction(FullScreenYZAction); this->m_ViewActions.push_back(FullScreenYZAction); QObject::connect( FullScreenYZAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewYZ() ) ); QAction *FullScreenXYZAction = new QAction(tr("Full-Screen XYZ"), this); FullScreenXYZAction->setCheckable(true); QIcon xyzicon; xyzicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/xyz.png") ), QIcon::Normal, QIcon::Off); FullScreenXYZAction->setIcon(xyzicon); group->addAction(FullScreenXYZAction); this->m_ViewActions.push_back(FullScreenXYZAction); QObject::connect( FullScreenXYZAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewXYZ() ) ); QAction *separator2 = new QAction(this); separator2->setSeparator(true); this->m_ViewActions.push_back(separator2); QAction *ActionDisplayAnnotations = new QAction(tr("Display annotations"), this); ActionDisplayAnnotations->setCheckable(true); ActionDisplayAnnotations->setChecked(true); ActionDisplayAnnotations->setStatusTip( tr(" Display annotations in each 2d view") ); QIcon displayannotationsicon; displayannotationsicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/2D_VIEWS_INFOS.png") ), QIcon::Normal, QIcon::Off); ActionDisplayAnnotations->setIcon(displayannotationsicon); QObject::connect( ActionDisplayAnnotations, SIGNAL( triggered() ), this->m_ImageView, SLOT( ShowAnnotations() ) ); this->m_ViewNoToolBarActions.push_back(ActionDisplayAnnotations); QAction *ActionDisplaySplinePlanes = new QAction(tr("Display spline planes"), this); ActionDisplaySplinePlanes->setCheckable(true); ActionDisplaySplinePlanes->setChecked(true); ActionDisplaySplinePlanes->setStatusTip( tr(" Display spline planes on each view") ); QIcon displaysplineplaneicon; displaysplineplaneicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/C_M_L_Border.png") ), QIcon::Normal, QIcon::Off); ActionDisplaySplinePlanes->setIcon(displaysplineplaneicon); this->m_ViewNoToolBarActions.push_back(ActionDisplaySplinePlanes); QObject::connect( ActionDisplaySplinePlanes, SIGNAL( triggered() ), this->m_ImageView, SLOT( ShowSplinePlane() ) ); QAction *DisplayCube3D = new QAction(tr("Display 3D cube"), this); DisplayCube3D->setCheckable(true); DisplayCube3D->setChecked(true); DisplayCube3D->setStatusTip( tr(" Display or not cube in 3d") ); QIcon cube3dicon; cube3dicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/cube.png") ), QIcon::Normal, QIcon::Off); DisplayCube3D->setIcon(cube3dicon); QObject::connect( DisplayCube3D, SIGNAL( triggered() ), this->m_ImageView, SLOT( ShowCube3D() ) ); this->m_ViewNoToolBarActions.push_back(DisplayCube3D); QAction *LookupTableAction = new QAction(tr("Lookup Table"), this); LookupTableAction->setObjectName("LUT"); LookupTableAction->setEnabled(false); LookupTableAction->setStatusTip( tr(" Change the associated lookup table") ); //take /*QIcon luticon; luticon.addPixmap(QPixmap( QString::fromUtf8(":/fig/LookupTable.png") ), QIcon::Normal, QIcon::Off); LookupTableAction->setIcon(luticon); // Here write the connection QObject::connect( LookupTableAction, SIGNAL( triggered() ), this, SLOT( ChangeLookupTable() ) ); this->m_ViewActions.push_back(LookupTableAction);*/ QAction *ScalarBarAction = new QAction(tr("Display Scalar Bar"), this); ScalarBarAction->setEnabled(false); ScalarBarAction->setCheckable(true); ScalarBarAction->setObjectName("ScalarBar"); QIcon scalarbaricon; scalarbaricon.addPixmap(QPixmap( QString::fromUtf8(":/fig/scalarbar.png") ), QIcon::Normal, QIcon::Off); ScalarBarAction->setIcon(scalarbaricon); this->m_ViewActions.push_back(ScalarBarAction); QObject::connect( ScalarBarAction, SIGNAL( toggled(bool) ), m_ImageView, SLOT( ShowScalarBar(bool) ) ); QPixmap Pix(16, 16); Pix.fill(Qt::black); m_BackgroundColorAction = new QAction(Pix, tr("Set Background Color"), this); this->m_ViewActions.push_back(m_BackgroundColorAction); QObject::connect( m_BackgroundColorAction, SIGNAL( triggered() ), this, SLOT( ChangeBackgroundColor() ) ); QAction *separator4 = new QAction(this); separator4->setSeparator(true); this->m_ViewActions.push_back(separator4); this->m_ViewActions.push_back( m_NavigationDockWidget->toggleViewAction() ); this->m_ViewActions.push_back( m_TransferFunctionDockWidget->toggleViewAction() ); this->m_ViewActions.push_back( m_DataBaseTables->toggleViewAction() ); /// \todo create group actions for views changing QAction *Change3DPerspectiveToAxialAction = new QAction(tr("Change 3D view to Posterior "), this); QIcon axialicon; axialicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/PosteriorView.png") ), QIcon::Normal, QIcon::Off); Change3DPerspectiveToAxialAction->setIcon(axialicon); this->m_ViewNoToolBarActions.push_back(Change3DPerspectiveToAxialAction); QObject::connect( Change3DPerspectiveToAxialAction, SIGNAL( triggered() ), this, SLOT( Change3DPerspectiveToAxial() ) ); QAction *Change3DPerspectiveToCoronalAction = new QAction(tr("Change 3D view to Dorsal "), this); QIcon coronalicon; coronalicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/DorsalView.png") ), QIcon::Normal, QIcon::Off); Change3DPerspectiveToCoronalAction->setIcon(coronalicon); this->m_ViewNoToolBarActions.push_back(Change3DPerspectiveToCoronalAction); QObject::connect( Change3DPerspectiveToCoronalAction, SIGNAL( triggered() ), this, SLOT( Change3DPerspectiveToCoronal() ) ); QAction *Change3DPerspectiveToSagittalAction = new QAction(tr("Change 3D view to Left "), this); QIcon sagittalicon; sagittalicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/LeftView.png") ), QIcon::Normal, QIcon::Off); Change3DPerspectiveToSagittalAction->setIcon(sagittalicon); this->m_ViewNoToolBarActions.push_back(Change3DPerspectiveToSagittalAction); QObject::connect( Change3DPerspectiveToSagittalAction, SIGNAL( triggered() ), this, SLOT( Change3DPerspectiveToSagittal() ) ); QAction *separator7 = new QAction(this); separator7->setSeparator(true); this->m_ViewActions.push_back(separator7); // Enable volume rendering QAction *VolumeRenderingAction = new QAction(tr("Enable the volume rendering for the current channel(s)"), this); VolumeRenderingAction->setCheckable(true); VolumeRenderingAction->setChecked(false); this->m_ViewActions.push_back(VolumeRenderingAction); QIcon volumerenderingicon; volumerenderingicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/VolumeRendering1.png") ), QIcon::Normal, QIcon::Off); VolumeRenderingAction->setIcon(volumerenderingicon); QObject::connect( VolumeRenderingAction, SIGNAL( toggled(bool) ), this, SLOT( EnableVolumeRendering(bool) ) ); // Enable synchronization QAction *SynchronizeViewsAction = new QAction(tr("synchronize the different views"), this); SynchronizeViewsAction->setCheckable(true); SynchronizeViewsAction->setChecked(true); this->m_ViewActions.push_back(SynchronizeViewsAction); QIcon synchronizeicon; synchronizeicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/synchronize.png") ), QIcon::Normal, QIcon::Off); SynchronizeViewsAction->setIcon(synchronizeicon); QObject::connect( SynchronizeViewsAction, SIGNAL( toggled(bool) ), this->m_ImageView, SLOT( SynchronizeViews(bool) ) ); // Show/hide the planes QAction *PlaneVisibilityAction = new QAction(tr("show planes in the 3d view"), this); PlaneVisibilityAction->setCheckable(true); PlaneVisibilityAction->setChecked(true); this->m_ViewActions.push_back(PlaneVisibilityAction); QIcon PlaneVisibilityicon; PlaneVisibilityicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/C_M_L.png") ), QIcon::Normal, QIcon::Off); PlaneVisibilityAction->setIcon(PlaneVisibilityicon); QObject::connect( PlaneVisibilityAction, SIGNAL( toggled(bool) ), this->m_ImageView, SLOT( ShowPlanes(bool) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateTracesActions() { // Track Color Coding // this->m_TracesActions->m_VectorAction.push_back( m_TrackViewDockWidget->toggleViewAction() ); // Lineage Color Coding // this->m_TracesActions->m_VectorAction.push_back( m_LineageViewDockWidget->toggleViewAction() ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::StartDopplerView() { bool ok; QStringList channel; unsigned int* boundChannel = m_ImageProcessor->getBoundsChannel(); for( unsigned int i = boundChannel[0]; i < boundChannel[1]+1; ++i ) { channel << QString::number(i, 10); } QString item = QInputDialog::getItem(this, tr("Channel selection"), tr("Please select the channel you want to track"), channel, 0, false, &ok); if ( ok ) { m_ImageProcessor->setDopplerMode(ok, // bool: true/false item.toInt(&ok, 10)); // selected channel ID // update image m_ImageProcessor->setDoppler(m_TCoord, 0); // 0 is for optimization later on... // update widget // hide channels this->m_NavigationDockWidget->VisibilityListChannels(false); //update values - show requiered widgets std::vector time = m_ImageProcessor->getDopplerTime(m_TCoord); // get number of items in container // requiereds to call this method since the number of items varies for(unsigned int i=0; igetDopplerSize(); ++i) { if(time[i]>=0) { std::string name = m_ImageProcessor->getChannelName(time[i]); // channel color std::vector color = m_ImageProcessor->getColor(name); // update navigation dockwidget m_NavigationDockWidget->AddDoppler( QString::fromStdString(name), QColor(color[0], color[1], color[2], color[3]), time[i], true); // all checkboxes are check edwhen we start } } // set channel name this->m_NavigationDockWidget->setChannelName( QString("Channel %1").arg(m_ImageProcessor->getDopplerChannel())); } } //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateToolsActions() { #if defined( ENABLEFFMPEG ) || defined( ENABLEAVI ) this->m_ToolsActions.push_back( m_VideoRecorderWidget->toggleViewAction() ); this->m_VideoRecorderWidget->toggleViewAction()->setEnabled(false); #endif m_TakeSnapshotAction = new QAction(tr("Take Snapshot"), this); QIcon snapshoticon; snapshoticon.addPixmap(QPixmap( QString::fromUtf8(":/fig/camera-photo.png") ), QIcon::Normal, QIcon::Off); m_TakeSnapshotAction->setIcon(snapshoticon); m_TakeSnapshotAction->setStatusTip( tr("You have to be in full screen view to use the snapshot") ); m_TakeSnapshotAction->setEnabled(false); QObject::connect( m_TakeSnapshotAction, SIGNAL( triggered() ), this, SLOT( TakeSnapshot() ) ); this->m_ToolsActions.push_back(m_TakeSnapshotAction); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateBookmarkActions() { QAction *AddBookmarkAction = new QAction(tr("Add a bookmark"), this); this->m_BookmarkActions.push_back(AddBookmarkAction); QObject::connect( AddBookmarkAction, SIGNAL ( triggered() ), this, SLOT ( AddBookmark() ) ); QAction *DeleteBookmarkAction = new QAction(tr("Delete a bookmark"), this); this->m_BookmarkActions.push_back(DeleteBookmarkAction); QObject::connect( DeleteBookmarkAction, SIGNAL ( triggered() ), this->m_DataBaseTables, SLOT( DeleteBookmarks() ) ); QObject::connect( this->m_DataBaseTables, SIGNAL ( PrintDBReady() ), this, SLOT( GetTheRelatedToDBActions() ) ); QObject::connect( this->m_DataBaseTables, SIGNAL( OpenBookmarksToUpdate() ), this, SLOT( GetTheOpenBookmarksActions() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::GetTheRelatedToDBActions() { this->GetTheOpenBookmarksActions(); QMenu * ImportMenu = new QMenu(tr("Import"), this); QAction *ImportContoursAction = new QAction(tr("Contours"), this); ImportContoursAction->setStatusTip( tr("Import the data of the contours from the text file into the GoFigure database" ) ); QAction *ImportMeshesAction = new QAction(tr("3DMeshes"), this); ImportMeshesAction->setStatusTip( tr("Import the data of the meshes from the text file into the GoFigure database" ) ); QAction *ImportTracksAction = new QAction(tr("Tracks"), this); ImportTracksAction->setStatusTip( tr("Import the data of the tracks from the text file into the GoFigure database" ) ); ImportMenu->addAction(ImportContoursAction); ImportMenu->addAction(ImportMeshesAction); ImportMenu->addAction(ImportTracksAction); QMenu * ExportMenu = new QMenu(tr("Export"), this); QAction *ExportContoursAction = new QAction(tr("Contours"), this); ExportContoursAction->setStatusTip( tr("Export all the data related to all contours of the imagingsession from the database into a .txt file") ); QAction *ExportMeshesAction = new QAction(tr("3DMeshes"), this); ExportMeshesAction->setStatusTip( tr("Export all the data related to all meshes of the imagingsession from the database into a .txt file") ); QAction *ExportLineagesAction = new QAction(tr("Lineages For Lineage Viewer"), this); ExportLineagesAction->setStatusTip( tr("Export each lineage into a vtkFile in order to be visualized separately into the lineage viewer outside of Gofigure") ); ExportMenu->addAction(ExportContoursAction); ExportMenu->addAction(ExportMeshesAction); ExportMenu->addAction(ExportLineagesAction); this->m_ToolsActions.push_back( ImportMenu->menuAction() ); this->m_ToolsActions.push_back( ExportMenu->menuAction() ); QObject::connect( ExportContoursAction, SIGNAL( triggered() ), this->m_DataBaseTables, SLOT( ExportContours () ) ); QObject::connect( ImportContoursAction, SIGNAL( triggered() ), this, SLOT( ImportContours() ) ); QObject::connect( ExportMeshesAction, SIGNAL( triggered() ), this->m_DataBaseTables, SLOT( ExportMeshes() ) ); QObject::connect( ImportMeshesAction, SIGNAL ( triggered() ), this, SLOT ( ImportMeshes() ) ); QObject::connect( ImportTracksAction, SIGNAL ( triggered() ), this, SLOT ( ImportTracks() ) ); QObject::connect( ExportLineagesAction, SIGNAL ( triggered() ), m_LineageContainer, SIGNAL( ExportLineages() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::GetTheOpenBookmarksActions() { bool UpdateOpenBookmarks = false; if ( this->m_BookmarkActions.size() > 2 ) { this->m_BookmarkActions.erase( this->m_BookmarkActions.begin() + this->m_BookmarkActions.size() - 1 ); UpdateOpenBookmarks = true; } NamesDescrContainerType ListBookmarks = this->m_DataBaseTables->GetListBookmarks(); size_t NumberBookmarks = ListBookmarks.size(); QMenu *OpenBookmarkMenu = new QMenu(tr("Open a bookmark"), this); for ( size_t i = 0; i < NumberBookmarks; i++ ) { QAction *OpenBookmarkAction = new QAction(ListBookmarks[i].first.c_str(), this); std::string TextStatusTip = "Description of the bookmark: "; TextStatusTip += ListBookmarks[i].second; OpenBookmarkAction->setStatusTip( TextStatusTip.c_str() ); OpenBookmarkMenu->addAction(OpenBookmarkAction); QObject::connect( OpenBookmarkAction, SIGNAL( triggered() ), this, SLOT( OpenExistingBookmark() ) ); } this->m_BookmarkActions.push_back( OpenBookmarkMenu->menuAction() ); if ( UpdateOpenBookmarks ) { emit UpdateBookmarkOpenActions(this->m_BookmarkActions); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::OpenExistingBookmark() { QAction * taction = qobject_cast< QAction * >( sender() ); std::string BookmarkName = taction->text().toStdString(); GoDBCoordinateRow Coord = this->m_DataBaseTables->GetCoordinateForBookmark(BookmarkName); int tt = Coord.GetMapValue("TCoord"); int tz = Coord.GetMapValue("ZCoord"); int ty = Coord.GetMapValue("YCoord"); int tx = Coord.GetMapValue("XCoord"); this->SetTimePoint(tt); this->SetSliceViewXY(tz); this->SetSliceViewXZ(ty); this->SetSliceViewYZ(tx); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::TakeSnapshot() { // Get the current view displayed in full screen int FullScreenView = m_ImageView->GetFullScreenView(); QString filename = QDir::toNativeSeparators( QDir::homePath() ); filename.append( QString("%1").arg("/") ); switch ( FullScreenView ) { case 1: filename.append("snapshot-xy-"); m_ImageView->SnapshotViewXY(GoFigure::PNG, filename); break; case 2: filename.append("snapshot-xz-"); m_ImageView->SnapshotViewXZ(GoFigure::PNG, filename); break; case 3: filename.append("snapshot-yz-"); m_ImageView->SnapshotViewYZ(GoFigure::PNG, filename); break; default: filename.append("snapshot-xyz-"); m_ImageView->SnapshotViewXYZ(GoFigure::PNG, filename); break; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::setupUi(QWidget *iParent) { if ( iParent->objectName().isEmpty() ) { iParent->resize(800, 800); } m_ImageView = new QGoImageView3D( this ); this->setCentralWidget(m_ImageView); m_DataBaseTables = new QGoPrintDatabase( this ); this->addDockWidget(Qt::TopDockWidgetArea, m_DataBaseTables); m_DataBaseTables->hide(); m_ImageView->SetIntersectionLineWidth(this->m_IntersectionLineWidth); m_ImageView->SetBackgroundColor(m_BackgroundColor); QObject::connect( m_ImageView, SIGNAL( SliceViewXYChanged(int) ), this, SIGNAL( SliceViewXYChanged(int) ) ); QObject::connect( m_ImageView, SIGNAL( SliceViewXZChanged(int) ), this, SIGNAL( SliceViewXZChanged(int) ) ); QObject::connect( m_ImageView, SIGNAL( SliceViewYZChanged(int) ), this, SIGNAL( SliceViewYZChanged(int) ) ); QObject::connect( m_ImageView, SIGNAL( FullScreenViewChanged(int) ), this, SIGNAL( FullScreenViewChanged(int) ) ); // connect the contours selection connection QObject::connect( m_ImageView, SIGNAL( SelectionChanged() ), this, SLOT( HighlightPickedActor() ) ); // connect the contours selection connection QObject::connect( m_ImageView, SIGNAL( VisibilityChanged() ), this, SLOT( VisibilityPickedActor() ) ); retranslateUi(iParent); QMetaObject::connectSlotsByName(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::retranslateUi(QWidget *iParent) { iParent->setWindowTitle( tr("QGoTabImageView3DwT") ); Q_UNUSED(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigure::TabDimensionType QGoTabImageView3DwT::GetTabDimensionType() const { return GoFigure::THREE_D_WITH_T; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetLSMReader(vtkLSMReader *iReader, const int & iTimePoint) { GoLSMImageProcessor* processor = new GoLSMImageProcessor; processor->setReader(iReader); m_ImageProcessor = processor; m_TCoord = iTimePoint; // update image processor m_ImageProcessor->initTimePoint(m_TCoord); //update images UpdateImage(); // update actors this->ShowTraces(m_TCoord); // update widgets on image loading InitializeImageRelatedWidget(); // render m_ImageView->Update(); // for the trace widget, navigation widget and table widget // should not be requiered since we just initialize it before emit TimePointChanged(m_TCoord); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetMegaCaptureFile( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const GoFigure::FileType & iFileType, const std::string & iHeader, const unsigned int & iTimePoint) { m_FileList = iContainer; m_FileType = iFileType; // setup megacapture reader m_MegaCaptureReader->SetInput(m_FileList); m_MegaCaptureReader->SetMegaCaptureHeader(iHeader); m_MegaCaptureReader->SetFileType(m_FileType); m_MegaCaptureReader->SetTimeBased(true); m_MegaCaptureReader->SetTimePoint(iTimePoint); m_MegaCaptureReader->Update(); GoMegaImageProcessor* processor = new GoMegaImageProcessor; processor->setReader(m_MegaCaptureReader); m_ImageProcessor = processor; m_TCoord = iTimePoint; // update image processor m_ImageProcessor->initTimePoint(m_TCoord); //update images UpdateImage(); // update widgets on image loading InitializeImageRelatedWidget(); // render m_ImageView->Update(); // for the trace widget, navigation widget and table widget // should not be requiered since we just initialize it before emit TimePointChanged(m_TCoord); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: InitializeImageRelatedWidget() { unsigned int* boundTime = m_ImageProcessor->getBoundsTime(); unsigned int NumberOfChannels = m_ImageProcessor->getNumberOfChannels(); int* extent = m_ImageProcessor->getExtent(); assert( extent ); // Initialize the widgets with the good number of channels // it will update the size of the related combobox m_NavigationDockWidget->blockSignals(true); for( unsigned int i = 0; i < NumberOfChannels; i++ ) { std::string name = m_ImageProcessor->getChannelName(i); // channel color std::vector color = m_ImageProcessor->getColor(name); QString channelname = QString::fromStdString(name); // update navigation dockwidget m_NavigationDockWidget->AddChannel( channelname, QColor(color[0], color[1], color[2], color[3]), i, true); // all checkboxes are check edwhen we start // create TF editor // add it in the vector this->createTransferFunctionEditor( channelname ); } m_NavigationDockWidget->SetXMinimumAndMaximum(extent[0], extent[1]); m_NavigationDockWidget->SetXSlice( ( extent[0] + extent[1] ) / 2 ); m_NavigationDockWidget->SetYMinimumAndMaximum(extent[2], extent[3]); m_NavigationDockWidget->SetYSlice( ( extent[2] + extent[3] ) / 2 ); m_NavigationDockWidget->SetZMinimumAndMaximum(extent[4], extent[5]); m_NavigationDockWidget->SetZSlice( ( extent[4] + extent[5] ) / 2 ); m_NavigationDockWidget->SetTMinimumAndMaximum(boundTime[0], boundTime[1]); m_NavigationDockWidget->SetTSlice(boundTime[0]); m_NavigationDockWidget->blockSignals(false); CreateContourEditingDockWidget(boundTime[0], boundTime[1]); CreateMeshEditingDockWidget(boundTime[0], boundTime[1]); m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus( this->m_ContourEditingWidget->GetDockWidget(), Qt::LeftDockWidgetArea, false, true, this), this->m_ContourEditingWidget->GetDockWidget()) ); m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus( this->m_MeshEditingWidget->GetDockWidget(), Qt::LeftDockWidgetArea, false, true, this), this->m_MeshEditingWidget->GetDockWidget()) ); // Set up QSpinBox in m_VideoRecorderWidget #if defined( ENABLEFFMPEG ) || defined( ENABLEAVI ) m_VideoRecorderWidget->SetXMinAndMax(extent[0], extent[1]); m_VideoRecorderWidget->SetYMinAndMax(extent[2], extent[3]); m_VideoRecorderWidget->SetZMinAndMax(extent[4], extent[5]); m_VideoRecorderWidget->SetTMinAndMax(boundTime[0], boundTime[1]); #endif /* ENABLEVIDEORECORD */ } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::UpdateImage() { // get number of visible channels instead unsigned int NumberOfVisibleChannels = m_ImageProcessor->getNumberOfVisibleChannels(); if ( NumberOfVisibleChannels>1 ) { m_ImageView->SetImage(m_ImageProcessor->getVisibleImages()); } else if( NumberOfVisibleChannels == 1) { //update Image m_ImageView->SetImage(m_ImageProcessor->getImageBW()); // update LUT m_ImageView->SetLookupTable(m_ImageProcessor->getLookuptable()); // CONFIGURE LUT this->findChild("LUT")->setEnabled(true); this->findChild("ScalarBar")->setEnabled(true); } else { // Start by creating a black lookup table. vtkSmartPointer bwLut = vtkSmartPointer::New(); bwLut->SetTableRange (0, 1); bwLut->SetSaturationRange (0, 0); bwLut->SetHueRange (0, 0); bwLut->SetValueRange (0, 0); bwLut->Build(); m_ImageView->SetLookupTable(bwLut); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::BuildDopplerWidget() { // update widget //update values - show requiered widgets std::vector time = m_ImageProcessor->getDopplerTime(m_TCoord); // get number of items in container // requiereds to call this method since the number of items varies for(unsigned int i=0; igetDopplerSize(); ++i) { if(time[i]>=0) { std::string name = m_ImageProcessor->getChannelName(time[i]); // channel color std::vector color = m_ImageProcessor->getColor(name); // update navigation dockwidget m_NavigationDockWidget->AddDoppler( QString::fromStdString(name), QColor(color[0], color[1], color[2], color[3]), time[i], true); // all checkboxes are check edwhen we start } } // set channel name this->m_NavigationDockWidget->setChannelName( QString("Channel %1").arg(m_ImageProcessor->getDopplerChannel())); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetTimePoint(const int & iTimePoint) { if ( iTimePoint == m_TCoord ) { return; } QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); m_TCoord = iTimePoint; if (!m_ImageProcessor->getDopplerMode()) { // update image processor m_ImageProcessor->setTimePoint(m_TCoord); } else { // delete previous doppler widget this->m_NavigationDockWidget->DeleteDopplerWidgets(); // update the image processor m_ImageProcessor->setDoppler(m_TCoord, 0); // 0 is for optimization later on... //rebuild navigation widget BuildDopplerWidget(); } // update image container UpdateImage(); // if go from t=0 to t=1 in doppler mode if (m_ImageProcessor->getDopplerMode()) { //clean TF Editor m_TransferFunctionDockWidget->DeleteTabs(); //createTransferFunctionEditor(channel name) CreateDopplerTFEditor(); } else { // update TF editor (histogram and max value) UpdateTFEditor(); } EnableVolumeRendering( this->m_VolumeRenderingEnabled ); // for the trace widget, navigation widget and table widget emit TimePointChanged(m_TCoord); //if we use the database, update table and traces! if(m_DataBaseTables->IsDatabaseUsed()) { // clean table widget and container // then load new traces in TW and put polydatas in container std::list timePoints = this->m_DataBaseTables-> UpdateTableWidgetAndContainersForGivenTimePoint( m_TCoord); // create actors if we use the database // function has to be splitted-> remove duplications this->CreateContoursActorsFromVisuContainer(timePoints); this->CreateMeshesActorsFromVisuContainer(timePoints); //show time specific actors this->ShowTraces(m_TCoord); } m_ImageView->Update(); QApplication::restoreOverrideCursor(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*void QGoTabImageView3DwT::ChangeLookupTable() { vtkImageData *image = m_ImageView->GetImage(); if ( image->GetNumberOfScalarComponents() == 1 ) { vtkLookupTable *lut = QGoLUTDialog::GetLookupTable( this, tr("Choose one look-up table") ); if ( lut ) { m_ImageView->SetLookupTable(lut); // free memory since it is not freed in the QGoLUTDialog lut->Delete(); } } }*/ //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoTabImageView3DwT::SnapshotViewXY( GoFigure::FileType iType, QString iBaseName) { return m_ImageView->SnapshotViewXY(iType, iBaseName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoTabImageView3DwT::SnapshotViewXZ( GoFigure::FileType iType, QString iBaseName) { return m_ImageView->SnapshotViewXZ(iType, iBaseName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoTabImageView3DwT::SnapshotViewYZ( GoFigure::FileType iType, QString iBaseName) { return m_ImageView->SnapshotViewYZ(iType, iBaseName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString QGoTabImageView3DwT::SnapshotViewXYZ( GoFigure::FileType iType, QString iBaseName) { return m_ImageView->SnapshotViewXYZ(iType, iBaseName); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetSliceViewXY(int iS) { m_ImageView->SetSliceViewXY(iS); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetSliceViewXZ(int iS) { m_ImageView->SetSliceViewXZ(iS); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetSliceViewYZ(int iS) { m_ImageView->SetSliceViewYZ(iS); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetFullScreenView(int iS) { m_ImageView->SetFullScreenView(iS); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::Quadview() { m_ImageView->SetFullScreenView(0); m_TakeSnapshotAction->setEnabled(false); #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) this->m_VideoRecorderWidget->toggleViewAction()->setEnabled(false); #endif } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::FullScreenViewXY() { m_ImageView->SetFullScreenView(1); m_TakeSnapshotAction->setEnabled(true); #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) this->m_VideoRecorderWidget->toggleViewAction()->setEnabled(true); #endif } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::FullScreenViewXZ() { m_ImageView->SetFullScreenView(2); m_TakeSnapshotAction->setEnabled(true); #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) this->m_VideoRecorderWidget->toggleViewAction()->setEnabled(true); #endif } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::FullScreenViewYZ() { m_ImageView->SetFullScreenView(3); m_TakeSnapshotAction->setEnabled(true); #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) this->m_VideoRecorderWidget->toggleViewAction()->setEnabled(true); #endif } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::FullScreenViewXYZ() { m_ImageView->SetFullScreenView(4); m_TakeSnapshotAction->setEnabled(true); #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) this->m_VideoRecorderWidget->toggleViewAction()->setEnabled(true); #endif } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::GetBackgroundColorFromImageViewer() { double r(0.), g(0.), b(0.); m_ImageView->GetBackgroundColor(r, g, b); m_BackgroundColor.setRgbF(r, g, b); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetBackgroundColorToImageViewer() { m_ImageView->SetBackgroundColor(m_BackgroundColor); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::ChangeBackgroundColor() { double r(0.), g(0.), b(0.); m_ImageView->GetBackgroundColor(r, g, b); m_BackgroundColor.setRgbF(r, g, b); QColor temp = QColorDialog::getColor( m_BackgroundColor, this, tr("Choose Background Color") ); if ( temp != m_BackgroundColor ) { m_BackgroundColor = temp; m_ImageView->SetBackgroundColor(m_BackgroundColor); QPixmap Pix(16, 16); Pix.fill(temp); m_BackgroundColorAction->setIcon(Pix); } } //------------------------------------------------------------------------- void QGoTabImageView3DwT::ModeChanged(int iChannel) { //clean TF Editor m_TransferFunctionDockWidget->DeleteTabs(); if ( iChannel == 1 ) { // set image processor and build navigation widget if we click on ok StartDopplerView(); //createTransferFunctionEditor(channel name) CreateDopplerTFEditor(); } else { this->m_NavigationDockWidget->DeleteDopplerWidgets(); m_ImageProcessor->setDopplerMode(false, 0); // update image processor m_ImageProcessor->initTimePoint(m_TCoord); // change visibility this->m_NavigationDockWidget->VisibilityListChannels(true); // create transfer function editor unsigned int NumberOfChannels = m_ImageProcessor->getNumberOfChannels(); for ( unsigned int i = 0; i < NumberOfChannels; i++ ) { std::string name = m_ImageProcessor->getChannelName(i); // create TF editor createTransferFunctionEditor(QString::fromStdString(name)); } } //update images UpdateImage(); // update visualization m_ImageView->Update(); //update the trace editing widget UpdateTracesEditingWidget(); // update the TF widget } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::StepChanged(int iStep) { // delete previous doppler widget this->m_NavigationDockWidget->DeleteDopplerWidgets(); // set the new doppler step m_ImageProcessor->setDopplerStep(iStep); // update the image processor m_ImageProcessor->setDoppler(m_TCoord, 0); // 0 is for optimization later on... //rebuild navigation widget BuildDopplerWidget(); // build new image UpdateImage(); //clean TF Editor m_TransferFunctionDockWidget->DeleteTabs(); // CreateDopplerTFEditor(); //update m_ImageView->Update(); //update the trace editing widget UpdateTracesEditingWidget(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SaveContour(vtkPolyData *contour, vtkPolyData *contour_nodes, int iTCoord) { if ( ( contour->GetNumberOfPoints() > 2 ) && ( iTCoord >= 0 ) ) { // Compute Bounding Box std::vector< int > bounds = GetBoundingBox(contour); // Save contour in database : this->m_DataBaseTables->SaveContoursFromVisuInDB(bounds[0], bounds[2], bounds[4], iTCoord, bounds[1], bounds[3], bounds[5], contour_nodes); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector< int > QGoTabImageView3DwT::GetBoundingBox(vtkPolyData *iElement) { std::vector< int > boundingBox(6, 0); if ( iElement ) { // Compute Bounding Box double bounds[6]; iElement->GetBounds(bounds); // Extract Min and Max from bounds double Min[3], Max[3]; int k = 0; unsigned int i; for( i = 0; i < 3; i++ ) { Min[i] = bounds[k++]; Max[i] = bounds[k++]; } int *min_idx = this->GetImageCoordinatesFromWorldCoordinates(Min); int *max_idx = this->GetImageCoordinatesFromWorldCoordinates(Max); int extent[6]; m_ImageProcessor->getImageBW()->GetExtent(extent); for( i = 0; i < 3; i++ ) { if ( min_idx[i] > extent[2 * i] ) { boundingBox[2 * i] = min_idx[i]; } else { boundingBox[2 * i] = extent[2 * i]; } if ( max_idx[i] < extent[2 * i + 1] ) { boundingBox[2 * i + 1] = max_idx[i]; } else { boundingBox[2 * i + 1] = extent[2 * i + 1]; } } delete[] min_idx; delete[] max_idx; } return boundingBox; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector< vtkActor * > QGoTabImageView3DwT::VisualizeTrace(vtkPolyData *iTrace, double *iRGBA) { std::vector< vtkActor * > oActors; if ( iTrace->GetNumberOfPoints() > 2 ) { vtkProperty *trace_property = vtkProperty::New(); trace_property->SetColor(iRGBA[0], iRGBA[1], iRGBA[2]); trace_property->SetOpacity(iRGBA[3]); vtkPolyData *trace_copy = vtkPolyData::New(); trace_copy->DeepCopy(iTrace); oActors = this->AddContour(trace_copy, trace_property); trace_copy->Delete(); trace_property->Delete(); } // add actor to renderer and to Prop3d m_ImageView->AddActor(3, oActors[3]); return oActors; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::ValidateContour(int iTCoord) { bool re_edit = this->m_ContourEditingWidget->GetReeditMode(); #ifdef HAS_OPENMP #pragma omp for #endif for( int i = 0; i < m_ImageView->GetNumberOfImageViewers(); i++ ) { vtkPolyData *nodes = m_ImageView->GetContourRepresentationNodePolydata(i); if ( nodes->GetNumberOfPoints() > 2 ) { /// \todo Nicolas - Fix leaks generated by // m_ImageView->GetContourRepresentationAsPolydata(i) vtkPolyData *contour = vtkPolyData::New(); contour->DeepCopy( m_ImageView->GetContourRepresentationAsPolydata(i) ); //polydata for bounding box, node for points SaveContour(contour, nodes, iTCoord); // polydata //ADD TRACE ID IN POLYDATA AddTraceIDIntoPolydata(contour, this->m_ContourContainer->m_CurrentElement.TraceID, "CONTOUR"); std::vector< vtkActor * > actors = VisualizeTrace(contour, this->m_ContourContainer->m_CurrentElement.rgba); contour->Delete(); //nodes m_ContourContainer->UpdateCurrentElementFromVisu(actors, nodes, // m_TCoord, iTCoord, re_edit, //highlighted true); //visible m_ContourContainer->InsertCurrentElement(); } } m_ImageView->UpdateRenderWindows(); if ( re_edit ) //need to set the widgets to a normal mode { this->m_TraceSettingsToolBar->setEnabled(true); this->m_TraceSettingsWidget->setEnabled(true); this->m_ContourEditingWidget->SetReeditMode(false); m_ImageView->ReinitializeContourWidget(); this->m_ContourEditingWidget->GetDockWidget()->hide(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int * QGoTabImageView3DwT::GetImageCoordinatesFromWorldCoordinates(double iPos[3]) { return m_ImageView->GetImageCoordinatesFromWorldCoordinates(iPos); } //------------------------------------------------------------------------- // std::vector< vtkQuadricLODActor* > std::vector< vtkActor * > QGoTabImageView3DwT::AddContour(vtkPolyData *dataset, vtkProperty *iProperty) { return this->m_ImageView->AddContour(dataset, iProperty); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::ReEditContour(const unsigned int & iId) { vtkPolyData *nodes = NULL; if ( this->m_ContourContainer ->RemoveElementFromVisualizationWithGivenTraceID(iId) ) { nodes = this->m_ContourContainer->m_CurrentElement.Nodes; std::vector< int > bounds = this->GetBoundingBox(nodes); int dir = ContourMeshContainer::ComputeDirectionFromBounds< int >(bounds); if ( dir != -1 ) { int idx[3]; idx[0] = ( bounds[0] + bounds[1] ) / 2; idx[1] = ( bounds[2] + bounds[3] ) / 2; idx[2] = ( bounds[4] + bounds[5] ) / 2; this->GoToLocation(idx[0], idx[1], idx[2], m_TCoord); //this->m_ModeActions[0]->setChecked(true); QAction* action = this->findChild< QAction* >("ContourEditingMode");//->setChecked(true); action->setChecked(true); m_ImageView->InitializeContourWidgetNodes(dir, nodes); this->m_TraceSettingsToolBar->setEnabled(false); this->m_TraceSettingsWidget->setEnabled(false); this->m_ContourEditingWidget->SetReeditMode(true); // go to manual segmentation this->m_ContourEditingWidget->GetDockWidget()->show(); } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::HighlightPickedActor() { vtkActor *temp_actor = m_ImageView->GetCurrentActor(); // mesh ID first - higher probability? if( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("MESH") ) { m_MeshContainer->UpdateElementHighlighting( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("MESH")->GetTuple1(0)); return; } if( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("TRACK") ) { m_TrackContainer->UpdateElementHighlighting( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("TRACK")->GetTuple1(0)); return; } if( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("DIVISION") ) { m_TrackContainer->UpdateCollectionHighlighting( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("DIVISION")->GetTuple1(0)); return; } if( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("CONTOUR") ) { m_ContourContainer->UpdateElementHighlighting( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("CONTOUR")->GetTuple1(0)); return; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::VisibilityPickedActor() { vtkActor *temp_actor = m_ImageView->GetCurrentActor(); if( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("MESH") ) { m_MeshContainer->UpdateElementVisibility( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("MESH")->GetTuple1(0), m_ImageView->GetCurrentState() ); return; } if( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("TRACK") ) { m_TrackContainer->UpdateElementVisibility( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("TRACK")->GetTuple1(0), m_ImageView->GetCurrentState() ); return; } if( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("CONTOUR") ) { m_ContourContainer->UpdateElementVisibility( temp_actor->GetMapper()->GetInput()->GetFieldData()->GetArray("CONTOUR")->GetTuple1(0), m_ImageView->GetCurrentState() ); return; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoTabImageView3DwT::GetSliceViewXY() const { return m_ImageView->GetSliceViewXY(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoTabImageView3DwT::GetSliceViewXZ() const { return m_ImageView->GetSliceViewXZ(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoTabImageView3DwT::GetSliceViewYZ() const { return m_ImageView->GetSliceViewYZ(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoTabImageView3DwT::GetTimePoint() const { return m_TCoord; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoTabImageView3DwT::GetTimeInterval() const { return m_ImageProcessor->getTimeInterval(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::AddBookmark() { this->m_DataBaseTables->AddBookmark( this->GetSliceViewYZ(), this->GetSliceViewXZ(), this->GetSliceViewXY(), this->GetTimePoint() ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::Change3DPerspectiveToAxial() { m_ImageView->SetCamera(1); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::Change3DPerspectiveToCoronal() { m_ImageView->SetCamera(2); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::Change3DPerspectiveToSagittal() { m_ImageView->SetCamera(3); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetSliceView() { #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) m_VideoRecorderWidget->SetCurrentX( this->GetSliceViewYZ() ); m_VideoRecorderWidget->SetCurrentY( this->GetSliceViewXZ() ); m_VideoRecorderWidget->SetCurrentZ( this->GetSliceViewXY() ); m_VideoRecorderWidget->SetCurrentT( this->GetTimePoint() ); #endif } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoTabImageView3DwT::SaveAndVisuContour(int iTCoord, vtkPolyData *iView) { if ( !m_DataBaseTables->IsDatabaseUsed() ) { std::cerr << "Problem with DB" << std::endl; return -1; } // if no data, we are using the contour widget if ( !iView ) { std::cerr << "Input contour is NULL" << std::endl; return -1; } // if there are no points in the polydata if ( iView->GetNumberOfPoints() == 0 ) { std::cerr << "No points in the contour you want to save" << std::endl; return 0; } vtkPolyData *contour_nodes = vtkPolyData::New(); CreateContour(contour_nodes, iView); // polydata for bounding box, nodes for db SaveContour(iView, contour_nodes, iTCoord); AddTraceIDIntoPolydata(iView, this->m_ContourContainer->m_CurrentElement.TraceID, "CONTOUR"); // should be polydata std::vector< vtkActor * > actors = VisualizeTrace(iView, this->m_ContourContainer->m_CurrentElement.rgba); iView->Delete(); // should be nodes // update the container m_ContourContainer->UpdateCurrentElementFromVisu(actors, contour_nodes, iTCoord, false, //highlighted true); //visible m_ContourContainer->InsertCurrentElement(); return 0; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateContour(vtkPolyData *contour_nodes, vtkPolyData *iView) { //generate contour vtkOrientedGlyphContourRepresentation *contourRep = vtkOrientedGlyphContourRepresentation::New(); vtkContourWidget *contourWidget = vtkContourWidget::New(); contourWidget->SetInteractor( this->m_ImageView->GetImageViewer(0) ->GetInteractor() ); contourWidget->SetRepresentation(contourRep); contourWidget->On(); contourWidget->Initialize(iView); contourWidget->CloseLoop(); contourRep->GetNodePolyData(contour_nodes); contourWidget->Delete(); contourRep->Delete(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SaveMesh(vtkPolyData *iView, int iTCoord, int iCollectionID) { // Compute Bounding Box std::vector< int > bounds = this->GetBoundingBox(iView); // Save mesh in database GoFigureMeshAttributes MeshAttributes = ComputeMeshAttributes( iView, true, static_cast< unsigned int >( iTCoord ) ); this->m_DataBaseTables->SaveMeshFromVisuInDB(bounds[0], bounds[2], bounds[4], bounds[1], bounds[3], bounds[5], iTCoord, iView, &MeshAttributes, iCollectionID); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SaveInDBAndRenderMeshForVisu( std::vector iVectPolydata, int iTCoord) { std::vector::iterator iter = iVectPolydata.begin(); while(iter != iVectPolydata.end()) { SaveAndVisuMesh(*iter, iTCoord); ++iter; } m_ImageView->UpdateRenderWindows(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SplitInDBAndRenderMeshForVisu( std::vector iVectPolydata) { int N = static_cast< int >( iVectPolydata.size() ); if( N == 0 ) { return; } // get mesh trace ID std::list< unsigned int > traceID = this->m_MeshContainer-> GetHighlightedElementsTraceID(); // get mesh track ID std::list< unsigned int > collectionID = this->m_MeshContainer-> GetHighlightedElementsCollectionID(); // get mesh time point std::list< unsigned int > tCoord = this->m_MeshContainer-> GetHighlightedElementsTCoord(); // uncheck this element // need it so when we split next mesh, time point and track ID will be accurate m_MeshContainer->UpdateElementHighlighting(traceID.front()); unsigned int timePoint = tCoord.front(); // Save mesh first mesh, provide track ID SaveAndVisuMesh(iVectPolydata[0], timePoint, collectionID.front()); if( N > 1) { #ifdef HAS_OPENMP #pragma omp for #endif for( int i = 1; i < N; ++i ) { SaveAndVisuMesh( iVectPolydata[i], timePoint, 0 ); } } m_ImageView->UpdateRenderWindows(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::MergeInDBAndRenderMeshForVisu( vtkPolyData * iVectPolydata) { if( iVectPolydata == NULL ) return; // get mesh trace ID std::list< unsigned int > traceID = this->m_MeshContainer-> GetHighlightedElementsTraceID(); // get mesh track ID std::list< unsigned int > collectionID = this->m_MeshContainer-> GetHighlightedElementsCollectionID(); // get mesh time point std::list< unsigned int > tCoord = this->m_MeshContainer-> GetHighlightedElementsTCoord(); // uncheck all std::list< unsigned int >::iterator iterator = traceID.begin(); while(iterator != traceID.end()) { m_MeshContainer->UpdateElementHighlighting(*iterator); ++iterator; } // Save mesh first mesh, provide track ID SaveAndVisuMesh(iVectPolydata, tCoord.front(), collectionID.front()); m_ImageView->UpdateRenderWindows(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: SaveInDBAndRenderSetOfContoursForVisu( std::vector > iVectorSetOfContours, int iTCoord) { // just add to visu as of now std::vector >::iterator it1 = iVectorSetOfContours.begin(); while(it1!=iVectorSetOfContours.end()) { std::vector::iterator it2 = (*it1).begin(); while(it2!=(*it1).end()) { vtkPolyData* data = vtkPolyData::New(); data->DeepCopy(*it2); this->AddContour(data); ++it2; } ++it1; } } //------------------------------------------------------------------------- void QGoTabImageView3DwT::SaveInDBAndRenderContourForVisu( std::vector iVectPolydata, int iTCoord) { std::vector::iterator iter = iVectPolydata.begin(); while(iter != iVectPolydata.end()) { SaveAndVisuContour(iTCoord, *iter); ++iter; } m_ImageView->UpdateRenderWindows(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SaveAndVisuMesh(vtkPolyData *iView, unsigned int iTCoord, int iCollectionID) { if ( !iView ) { std::cerr << "Input Mesh is NULL" << std::endl; return; } SaveMesh(iView, iTCoord, iCollectionID); // should be done in the mesh manager, from goprintdatabase //ADD TRACE ID IN POLYDATA AddTraceIDIntoPolydata(iView, this->m_MeshContainer->m_CurrentElement.TraceID, "MESH"); std::vector< vtkActor * > actors = VisualizeTrace(iView, this->m_MeshContainer->m_CurrentElement.rgba); // update container since a new mesh is created m_MeshContainer->UpdateCurrentElementFromVisu(actors, iView, iTCoord, false, // highlighted true); // visible m_MeshContainer->InsertCurrentElement(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::AddContourForMeshToContours(vtkPolyData *iInput) { if ( !m_DataBaseTables->IsDatabaseUsed() ) { std::cerr << "Problem with DB" << std::endl; return; } vtkPolyData *contour_nodes = vtkPolyData::New(); CreateContour(contour_nodes, iInput); //std::list ListContourIDs; if ( ( iInput->GetNumberOfPoints() > 2 ) && ( m_TCoord >= 0 ) ) { // Compute Bounding Box std::vector< int > bounds = GetBoundingBox(iInput); // Save contour in database : //ListContourIDs.push_back( this->m_DataBaseTables->SaveNewContourForMeshToContours (bounds[0], bounds[2], bounds[4], bounds[1], bounds[3], bounds[5], contour_nodes); //); // AND VISU!!! AddTraceIDIntoPolydata(iInput, this->m_ContourContainer->m_CurrentElement.TraceID, "MESH"); std::vector< vtkActor * > actors = VisualizeTrace(iInput, this->m_ContourContainer->m_CurrentElement.rgba); m_ImageView->UpdateRenderWindows(); iInput->Delete(); // update the container m_ContourContainer->UpdateCurrentElementFromVisu(actors, contour_nodes, m_TCoord, false, //highlighted true); //visible m_ContourContainer->InsertCurrentElement(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::GoToDefaultMenu(bool iEnable) { if ( iEnable ) { //this->m_ModeActions.at(0)->setChecked(true); this->findChild< QAction* >("DefaultMode")->setChecked(true); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigureMeshAttributes QGoTabImageView3DwT:: ComputeMeshAttributes(vtkPolyData *iMesh, const bool & iIntensity, const unsigned int& iTCoord ) { typedef unsigned char PixelType; const unsigned int Dimension = 3; typedef itk::Image< PixelType, Dimension > ImageType; itk::vtkPolyDataToGoFigureMeshAttributes< ImageType >::Pointer calculator = itk::vtkPolyDataToGoFigureMeshAttributes< ImageType >::New(); calculator->SetPolyData(iMesh); calculator->SetIntensityBasedComputation(iIntensity); GoFigureMeshAttributes oAttributes; if(!m_ImageProcessor->getDopplerMode()) { int NumberOfChannels = static_cast< int >( m_ImageProcessor->getNumberOfChannels() ); if( iIntensity ) { #ifdef HAS_OPENMP #pragma omp for #endif for( int i = 0; i < NumberOfChannels; i++ ) { vtkSmartPointer< vtkImageExport > vtk_exporter = vtkSmartPointer< vtkImageExport >::New(); itk::VTKImageImport< ImageType >::Pointer itk_importer = itk::VTKImageImport< ImageType >::New(); vtk_exporter->SetInput(m_ImageProcessor->getImageBW(i)); ConnectPipelines< vtkImageExport, itk::VTKImageImport< ImageType >::Pointer >( vtk_exporter, itk_importer); calculator->SetImage( itk_importer->GetOutput() ); calculator->Update(); oAttributes.m_Volume = calculator->GetPhysicalSize(); oAttributes.m_Area = calculator->GetArea(); oAttributes.m_Size = calculator->GetSize(); std::string channelname = m_ImageProcessor->getChannelName(i); oAttributes.m_TotalIntensityMap[channelname] = static_cast< int >( calculator->GetSumIntensity() ); oAttributes.m_MeanIntensityMap[channelname] = calculator->GetMeanIntensity(); } } else { vtkSmartPointer< vtkImageExport > vtk_exporter = vtkSmartPointer< vtkImageExport >::New(); itk::VTKImageImport< ImageType >::Pointer itk_importer = itk::VTKImageImport< ImageType >::New(); vtk_exporter->SetInput( m_ImageProcessor->getImageBW( 0 ) ); ConnectPipelines< vtkImageExport, itk::VTKImageImport< ImageType >::Pointer >( vtk_exporter, itk_importer); calculator->SetImage( itk_importer->GetOutput() ); calculator->Update(); oAttributes.m_Volume = calculator->GetPhysicalSize(); oAttributes.m_Area = calculator->GetArea(); oAttributes.m_Size = calculator->GetSize(); } } else { unsigned int* boundChannel = m_ImageProcessor->getBoundsChannel(); unsigned int NumberOfChannels = m_ImageProcessor->getNumberOfChannels(); std::vector< vtkSmartPointer< vtkImageData > > temp_image( NumberOfChannels ); // load real image m_ImageProcessor->initTimePoint(iTCoord); if( iIntensity ) { #ifdef HAS_OPENMP #pragma omp parallel for #endif for( int i = static_cast< int >( boundChannel[0] ); i <= static_cast< int >( boundChannel[1] ); i++ ) { temp_image[i] = m_ImageProcessor->getImageBW(i); vtkSmartPointer< vtkImageExport > vtk_exporter = vtkSmartPointer< vtkImageExport >::New(); itk::VTKImageImport< ImageType >::Pointer itk_importer = itk::VTKImageImport< ImageType >::New(); vtk_exporter->SetInput(temp_image[i]); ConnectPipelines< vtkImageExport, itk::VTKImageImport< ImageType >::Pointer >( vtk_exporter, itk_importer); calculator->SetImage( itk_importer->GetOutput() ); calculator->Update(); oAttributes.m_Volume = calculator->GetPhysicalSize(); oAttributes.m_Area = calculator->GetArea(); oAttributes.m_Size = calculator->GetSize(); std::string channelname = m_ImageProcessor->getChannelName(i); oAttributes.m_TotalIntensityMap[channelname] = static_cast< int >( calculator->GetSumIntensity() ); oAttributes.m_MeanIntensityMap[channelname] = calculator->GetMeanIntensity(); } } else { temp_image[0] = m_ImageProcessor->getImageBW(0); vtkSmartPointer< vtkImageExport > vtk_exporter = vtkSmartPointer< vtkImageExport >::New(); itk::VTKImageImport< ImageType >::Pointer itk_importer = itk::VTKImageImport< ImageType >::New(); vtk_exporter->SetInput(temp_image[0]); ConnectPipelines< vtkImageExport, itk::VTKImageImport< ImageType >::Pointer >( vtk_exporter, itk_importer); calculator->SetImage( itk_importer->GetOutput() ); calculator->Update(); oAttributes.m_Volume = calculator->GetPhysicalSize(); oAttributes.m_Area = calculator->GetArea(); oAttributes.m_Size = calculator->GetSize(); } // load doppler image // visibility should be updated... m_ImageProcessor->setDoppler(m_TCoord, 0); } return oAttributes; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::ImportContours() { if ( this->m_DataBaseTables->IsDatabaseUsed() ) { this->m_DataBaseTables->ImportContours(); this->GoToDefaultMenu(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateMeshFromSelectedContours( std::list< unsigned int > iListContourIDs, int iMeshID) { /// \todo Bug iMeshID is not the one it is supposed to be std::list< unsigned int >::const_iterator contourid_it = iListContourIDs.begin(); std::list< unsigned int >::const_iterator contourid_end = iListContourIDs.end(); std::vector< vtkPolyData * > list_contours; // get the time point unsigned int tcoord = std::numeric_limits< unsigned int >::max(); while ( contourid_it != contourid_end ) { ContourMeshContainer::MultiIndexContainerTraceIDIterator it0, it1; boost::tuples::tie(it0, it1) = m_ContourContainer->m_Container.get< TraceID >().equal_range(*contourid_it); if ( it0 != it1 ) { if ( tcoord == std::numeric_limits< unsigned int >::max() ) { tcoord = it0->TCoord; } else { if ( it0->TCoord != tcoord ) { QMessageBox::warning( NULL, tr("Generate Mesh From Checked Contours"), tr("Selected contours are at different time point: %1 != %2").arg(tcoord).arg( it0->TCoord) ); return; } } list_contours.push_back( vtkPolyData::SafeDownCast( it0->ActorXYZ->GetMapper()->GetInput() ) ); } ++contourid_it; } if ( !list_contours.empty() ) { // make the mesh from the list of contours typedef itk::ContourToMeshFilter< std::vector< vtkPolyData * > > FilterType; FilterType::Pointer filter = FilterType::New(); filter->ProcessContours(list_contours); vtkPolyData *mesh = filter->GetOutput(); vtkBox *implicitFunction = vtkBox::New(); // get bounds from the first visible image implicitFunction->SetBounds( m_ImageProcessor->getImageBW()->GetBounds() ); vtkClipPolyData *cutter = vtkClipPolyData::New(); cutter->SetInput(mesh); cutter->InsideOutOn(); cutter->SetClipFunction(implicitFunction); cutter->Update(); vtkPolyData *temp = vtkPolyData::New(); temp->DeepCopy( cutter->GetOutput() ); cutter->Delete(); implicitFunction->Delete(); mesh->Delete(); //as the element is already in the container we need to delete it in order //to update it in the SaveAndVisuMesh: this->m_MeshContainer->RemoveElementFromVisualizationWithGivenTraceID(iMeshID); SaveAndVisuMesh(temp, tcoord); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::ImportMeshes() { if ( this->m_DataBaseTables->IsDatabaseUsed() ) { m_DataBaseTables->ImportMeshes(); GoToDefaultMenu(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::ImportTracks() { if ( this->m_DataBaseTables->IsDatabaseUsed() ) { std::vector< int > NewTrackIDs = m_DataBaseTables->ImportTracks(); //call the method of the trackContainer to update the points :argument // NewTrackIDs this->m_TrackContainer->UpdateTracksStrings(NewTrackIDs); GoToDefaultMenu(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::GoToLocation(int iX, int iY, int iZ, int iT) { this->SetTimePoint(iT); this->SetSliceViewXY(iZ); this->SetSliceViewXZ(iY); this->SetSliceViewYZ(iX); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::GoToRealLocation(double iX, double iY, double iZ, int iT) { double p[3]; p[0] = iX; p[1] = iY; p[2] = iZ; int *index = this->GetImageCoordinatesFromWorldCoordinates( p ); this->GoToLocation( index[0], index[1], index[2], iT); delete[] index; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: AddTraceIDIntoPolydata( vtkPolyData* iPolydata, unsigned int iTraceID, const char* iTrace) { vtkSmartPointer trackIDArray = vtkSmartPointer::New(); trackIDArray->SetNumberOfComponents(1); trackIDArray->SetNumberOfValues(1); trackIDArray->SetName(iTrace); trackIDArray->SetValue(0, iTraceID); iPolydata->GetFieldData()->AddArray(trackIDArray); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetTraceSettingsToolBarVisible(bool IsVisible) { if (!IsVisible) { if (!this->m_ContourEditingWidget->GetToggleViewAction()->isChecked() && !this->m_MeshEditingWidget->GetToggleViewAction()->isChecked() && !this->m_DataBaseTables->toggleViewAction()->isChecked() ) { this->m_TraceSettingsToolBar->setVisible(IsVisible); } } else { if (this->m_ContourEditingWidget->GetToggleViewAction()->isChecked()) { this->m_DataBaseTables->SetTraceNameForTableWidget("contour"); } if (this->m_MeshEditingWidget->GetToggleViewAction()->isChecked() ) { this->m_DataBaseTables->SetTraceNameForTableWidget("mesh"); } if(this->m_DataBaseTables->NeedTraceSettingsToolBarVisible() ) // if the dockwidget is not on floating mode // or if the trace settings widget is not already visible in the dockwidget // or if the TW is not visible { this->m_TraceSettingsToolBar->setVisible(IsVisible); } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::InitializeToolsForTracesToolBar( QMenu* iMenu, QToolBar* iToolBar) { //iToolBar->clear(); QGoToolBarStatus* TracesToolBar = new QGoToolBarStatus(iToolBar, iMenu, Qt::TopToolBarArea, true, true, this); QActionGroup* group = this->findChild< QActionGroup* >("ModeGroup"); //Contour Editing QAction *ContourSegmentationAction = this->m_ContourEditingWidget->GetToggleViewAction(); ContourSegmentationAction->setShortcut(tr("2", "Contour Editing Mode")); ContourSegmentationAction->setParent(this); ContourSegmentationAction->setObjectName("ContourEditingMode"); group->addAction(ContourSegmentationAction); //group->addAction(this->m_ContourSegmentationDockWidget->GetActionForToggle() ); TracesToolBar->m_VectorAction.push_back(ContourSegmentationAction); //this->m_TracesActions.push_back(this->m_ContourSegmentationDockWidget->GetActionForToggle()); //Mesh Editing QAction *MeshSegmentationAction = this->m_MeshEditingWidget->GetToggleViewAction(); MeshSegmentationAction->setShortcut(tr("3", "Mesh Editing Mode")); group->addAction(MeshSegmentationAction); TracesToolBar->m_VectorAction.push_back(MeshSegmentationAction); // Track Color Coding TracesToolBar->m_VectorAction.push_back( m_TrackViewDockWidget->toggleViewAction() ); // Lineage Color Coding TracesToolBar->m_VectorAction.push_back( m_LineageViewDockWidget->toggleViewAction() ); // Lineage Viewer TracesToolBar->m_VectorAction.push_back( m_QGoLineageViewerWidget->toggleViewAction() ); QObject::connect( ContourSegmentationAction, SIGNAL( toggled(bool) ), m_ContourEditingWidget, SLOT( SetVisible(bool) ) ); QObject::connect( ContourSegmentationAction, SIGNAL( toggled(bool) ), this, SLOT( SetTraceSettingsToolBarVisible(bool) ) ); QObject::connect( MeshSegmentationAction, SIGNAL( toggled(bool) ), m_MeshEditingWidget, SLOT( SetVisible(bool) ) ); QObject::connect( MeshSegmentationAction, SIGNAL( toggled(bool) ), this, SLOT( SetTraceSettingsToolBarVisible(bool) ) ); this->m_ToolBarList.push_back(TracesToolBar); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::InitializeTraceSettingsToolBar(QToolBar* iToolBar) { m_TraceSettingsToolBar = iToolBar; QGoToolBarStatus* TraceSettingsToolBar = new QGoToolBarStatus( iToolBar, 0, Qt::TopToolBarArea,false,true,this, this->m_DataBaseTables->GetTraceSettingsWidgetForToolBar() ); this->m_ToolBarList.push_back(TraceSettingsToolBar); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::UpdateTracesEditingWidget() { if (this->m_MeshEditingWidget != NULL && this->m_ContourEditingWidget != NULL) { if (!this->m_ImageProcessor->getDopplerMode()) { this->m_MeshEditingWidget->SetTSliceForClassicView(); this->m_ContourEditingWidget->SetTSliceForClassicView(); } else { QHash ListTimePoints; std::vector dopplerT = this->m_ImageProcessor->getDopplerTime(this->m_TCoord); for(unsigned int i=0; im_ImageProcessor->getDopplerSize(); ++i) { if (dopplerT[i] >= 0 ) { double* rgb = vtkMath::HSVToRGB( static_cast(i) / static_cast( this->m_ImageProcessor->getDopplerSize()),1,1); QColor color(rgb[0]*255, rgb[1]*255, rgb[2]*255); ListTimePoints[tr("%1").arg(dopplerT[i])] = color; } } this->m_MeshEditingWidget->SetTSliceForDopplerView(ListTimePoints, m_ImageProcessor->getDopplerChannel()); this->m_ContourEditingWidget->SetTSliceForDopplerView(ListTimePoints, m_ImageProcessor->getDopplerChannel()); } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateModeToolBar(QMenu* iMenu, QToolBar* iToolBar) { QGoTabElementBase::CreateModeToolBar(iMenu, iToolBar); QActionGroup* group = this->findChild("ModeGroup"); QAction *separator1 = new QAction(this); separator1->setSeparator(true); this->m_ModeToolBar->m_VectorAction.push_back(separator1); //---------------------------------// // Actor picking mode // //---------------------------------// QAction *ActorPickingAction = new QAction(tr("Object Picking"), this); ActorPickingAction->setShortcut(tr("P", "Object Picking Mode")); ActorPickingAction->setCheckable(true); ActorPickingAction->setChecked(false); QIcon ActorPickingIcon; ActorPickingIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/ObjectPicking.png") ), QIcon::Normal, QIcon::Off); ActorPickingAction->setIcon(ActorPickingIcon); ActorPickingAction->setStatusTip( tr( "Select a contour or a mesh (left click when the bounding box of the object of interest is visible)") ); group->addAction(ActorPickingAction); this->m_ModeToolBar->m_VectorAction.push_back(ActorPickingAction); // it also updates the interactor behaviour QObject::connect( ActorPickingAction, SIGNAL( toggled(bool) ), this, SLOT( ActorPickingInteractorBehavior(bool) ) ); //---------------------------------// // Box 3D picking mode // //---------------------------------// QAction *Box3DPickingAction = new QAction(tr("Show/hide objects using Box"), this); Box3DPickingAction->setShortcut(tr("B", "Box Widget Mode")); Box3DPickingAction->setCheckable(true); Box3DPickingAction->setChecked(false); QIcon Box3DPickingIcon; Box3DPickingIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/Box3DPicking.png") ), QIcon::Normal, QIcon::Off); Box3DPickingAction->setIcon(Box3DPickingIcon); Box3DPickingAction->setStatusTip( tr("Show only the objects in the box") ); group->addAction(Box3DPickingAction); this->m_ModeToolBar->m_VectorAction.push_back(Box3DPickingAction); // it also updates the interactor behaviour QObject::connect( Box3DPickingAction, SIGNAL( toggled(bool) ), this, SLOT( Box3DPicking(bool) ) ); //---------------------------------// // Plane widget mode // //---------------------------------// QAction *PlaneWidgetAction = new QAction(tr("Show/hide objects using Plane"), this); PlaneWidgetAction->setCheckable(true); PlaneWidgetAction->setChecked(false); QIcon PlaneWidgetIcon; PlaneWidgetIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/PlaneSelection.png") ), QIcon::Normal, QIcon::Off); PlaneWidgetAction->setIcon(PlaneWidgetIcon); PlaneWidgetAction->setStatusTip( tr("Show only the objects located in front of the plane") ); group->addAction(PlaneWidgetAction); this->m_ModeToolBar->m_VectorAction.push_back(PlaneWidgetAction); // it also updates the interactor behaviour QObject::connect( PlaneWidgetAction, SIGNAL( toggled(bool) ), this, SLOT( PlaneWidgetInteractorBehavior(bool) ) ); // NOT A MODE: ANNOTATION QAction *separator3 = new QAction(this); separator3->setSeparator(true); this->m_ModeToolBar->m_VectorAction.push_back(separator3); //---------------------------------// // Distance mode // //---------------------------------// QAction *DistanceAction = new QAction(tr("Measure a Distance"), this); DistanceAction->setCheckable(true); DistanceAction->setChecked(false); QIcon DistanceIcon; DistanceIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/Distance.png") ), QIcon::Normal, QIcon::Off); DistanceAction->setIcon(DistanceIcon); DistanceAction->setStatusTip( tr("Measure a distance between 2 points (left click to place/drag the points)") ); group->addAction(DistanceAction); this->m_ModeToolBar->m_VectorAction.push_back(DistanceAction); QObject::connect( DistanceAction, SIGNAL( toggled(bool) ), this, SLOT( DistanceWidgetInteractorBehavior(bool) ) ); // NOT A MODE: ANNOTATION //---------------------------------// // Angle mode // //---------------------------------// QAction *AngleAction = new QAction(tr("Measure an Angle"), this); AngleAction->setCheckable(true); AngleAction->setChecked(false); QIcon AngleIcon; AngleIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/Angle.png") ), QIcon::Normal, QIcon::Off); AngleAction->setIcon(AngleIcon); AngleAction->setStatusTip( tr("Measure an angle between 3 points (left click to place/drag the points)") ); group->addAction(AngleAction); this->m_ModeToolBar->m_VectorAction.push_back(AngleAction); QObject::connect( AngleAction, SIGNAL( toggled(bool) ), this, SLOT( AngleWidgetInteractorBehavior(bool) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: visibilityChanged(QString iName, bool iVisibility) { m_ImageProcessor->visibilityChanged(iName.toStdString(), iVisibility); UpdateImage(); //if we are in volume rendering EnableVolumeRendering( this->m_VolumeRenderingEnabled ); // update visu m_ImageView->Update(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: DopplerSizeChanged(int iDopplerSize) { // delete previous doppler widget this->m_NavigationDockWidget->DeleteDopplerWidgets(); // set the new doppler step m_ImageProcessor->setDopplerSize(iDopplerSize); // update the image processor m_ImageProcessor->setDoppler(m_TCoord, 0); // 0 is for optimization later on... //rebuild navigation widget BuildDopplerWidget(); // build new image UpdateImage(); //clean TF Editor m_TransferFunctionDockWidget->DeleteTabs(); //createTransferFunctionEditor(channel name) CreateDopplerTFEditor(); //update m_ImageView->Update(); //update the trace editing widget UpdateTracesEditingWidget(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: createTransferFunctionEditor(QString iName) { std::string channelname = iName.toStdString(); // create editor // get LUT parameters (gamma, min, max) std::vector lutParameters = m_ImageProcessor->getLUTParameters( channelname ); GoTransferFunctionEditorWidget* editor = new GoTransferFunctionEditorWidget(iName, m_ImageProcessor->getColor( channelname ), lutParameters, m_ImageProcessor->getImageBW( channelname )->GetScalarRange()[1], this ); // connect signals QObject::connect( editor, SIGNAL( updateVisualization() ), this, SLOT( updateSlot()) ); QObject::connect( editor, SIGNAL( UpdateImageStructure(QString, std::map< unsigned int, unsigned int>, QColor, int, int, int) ), this, SLOT( updatePoints(QString, std::map< unsigned int, unsigned int>, QColor, int, int, int)) ); QObject::connect(this->m_ImageView, SIGNAL(NewWindowLevel(double, double)), this, SLOT(AdjustWindowLevel(double, double))); // show editor - to have consistent geomerty to add the points editor->show(); // add points editor->AddPoints(m_ImageProcessor->getAlpha( channelname )); // add LUT editor->AddLookupTable( m_ImageProcessor->getLookuptable( channelname ) ); // add Opacity TF editor->AddOpacityTransferFunction( m_ImageProcessor->getOpacityTransferFunction( channelname ) ); // add histogram - should not recalculate all the time... editor->AddHistogram(m_ImageProcessor->getHistogram( channelname ) ); // hide editor editor->hide(); //editor->setParent(m_TransferFunctionDockWidget); m_TransferFunctionDockWidget->AddTransferFunction(iName, editor); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- // color changed void QGoTabImageView3DwT::updateSlot() { UpdateImage(); EnableVolumeRendering( this->m_VolumeRenderingEnabled ); m_ImageView->Update(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: updatePoints(QString iName, std::map< unsigned int, unsigned int> iPoints, QColor iColor, int iMin, int iMax, int iGamma) { // update opacity TF points m_ImageProcessor->updatePoints(iName.toStdString(), iPoints); //color std::vector color; color.push_back(iColor.redF()*255); color.push_back(iColor.greenF()*255); color.push_back(iColor.blueF()*255); m_ImageProcessor->setColor(iName.toStdString(), color); //LUT parameters m_ImageProcessor->setLUTParameters(iName.toStdString(), iGamma, iMin, iMax); // color of button in navigation widget m_NavigationDockWidget->ModifyChannel(iName, iColor); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: EnableVolumeRendering(bool iEnable) { if(iEnable) { m_VolumeRenderingEnabled = true; m_ImageView->EnableVolumeRendering(m_ImageProcessor->getColoredImages(), m_ImageProcessor->getOpacityTransferFunctions()); } else { m_VolumeRenderingEnabled = false; m_ImageView->DisableVolumeRendering(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: CreateContoursActorsFromVisuContainer() { //check mode from print db std::list tp = m_DataBaseTables->GetVisibleTimePoints(); // load all tp if(tp.size() == 0) { unsigned int* time = m_ImageProcessor->getBoundsTime(); for(unsigned int i = time[0]; i iTPointToLoad) { typedef ContourContainer::MultiIndexContainerType::index< TCoord >::type::iterator ContourContainerTCoordIterator; if ( this->m_ContourContainer ) { // load everything if no list given if ( !iTPointToLoad.empty() ) { std::list::const_iterator it = iTPointToLoad.begin(); std::list::const_iterator end = iTPointToLoad.end(); while(it != end) { ContourContainerTCoordIterator it0, it1; // let's iterate on the container with increasing TraceID boost::tuples::tie(it0, it1) = this->m_ContourContainer->m_Container.get< TCoord >().equal_range(*it); // we don't need here to save this contour in the database, // since they have just been extracted from it! while ( it0 != it1 ) { this->AddContourFromNodes< TCoord >( it0 ); ++it0; } ++it; } } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: CreateMeshesActorsFromVisuContainer() { //check mode from print db std::list tp = m_DataBaseTables->GetVisibleTimePoints(); // load all tp if( tp.empty() ) { unsigned int* time = m_ImageProcessor->getBoundsTime(); for(unsigned int i = time[0]; i iTPointToLoad) { typedef MeshContainer::MultiIndexContainerType::index< TCoord >::type::iterator MeshContainerTCoordIterator; int lastTP = m_ImageProcessor->getBoundsTime()[1]; std::stringstream lastTimePoint; lastTimePoint << lastTP; if( this->m_MeshContainer) { // load everything if no list given if ( !iTPointToLoad.empty() ) { std::list::const_iterator it = iTPointToLoad.begin(); std::list::const_iterator end = iTPointToLoad.end(); while( it != end ) { MeshContainerTCoordIterator it0, it1; boost::tuples::tie(it0, it1) = this->m_MeshContainer->m_Container.get< TCoord >().equal_range(*it); // progress bar int size = this->m_DataBaseTables-> GetNumberOfElementForTraceAndTimePoint("mesh", *it); std::stringstream time; time << *it; QProgressDialog progress( QString::fromStdString("Loading Meshes from T=" + time.str() +"/" + lastTimePoint.str()), QString(), 0, size); size_t i = 0; progress.setValue( i ); std::vector< MeshContainerTCoordIterator > tempvector; while( it0 != it1 ) { tempvector.push_back(it0); ++it0; } int numberOfMeshes = static_cast< int >( tempvector.size() ); // we don't need here to save this mesh in the database, // since they have just been extracted from it! //while ( it0 != it1 ) #ifdef HAS_OPENMP #pragma omp for #endif for( int i = 0; i < numberOfMeshes; i++ ) { it0 = tempvector[i]; if ( it0->Nodes ) { // bug here, don't use TCoord GoFigureMeshAttributes attributes = this->ComputeMeshAttributes( it0->Nodes, // mesh false, // do not need to compute intensity based measure it0->TCoord ); this->m_DataBaseTables->PrintVolumeAreaForMesh( &attributes, it0->TraceID); } this->AddMeshFromNodes< TCoord >( it0 ); //++it0; //++i; progress.setValue( i ); } progress.setValue(size); ++it; } } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: ShowTraces(const unsigned int& iTimePoint) { // only contours and meshes will be modified since tracks and lineage contain // several time points this->m_ContourContainer->ShowActorsWithGivenTimePoint(iTimePoint); this->m_MeshContainer->ShowActorsWithGivenTimePoint(iTimePoint); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: AdjustWindowLevel(double iMin, double iMax) { int index = m_NavigationDockWidget->GetFirstVisibleChannel(); // if one channel is checked // (if no channel selected, index == -1, we don't do anything) if(index >= 0) { this->m_TransferFunctionDockWidget->SetCurrentWidget(index); GoTransferFunctionEditorWidget* widget = dynamic_cast( this->m_TransferFunctionDockWidget->GetWidget(index)); widget->AdjustWindowLevel(iMin, iMax); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void QGoTabImageView3DwT:: UpdateTFEditor() { int NumberOfChannels = static_cast< int >( m_ImageProcessor->getNumberOfChannels() ); int currentChannel = m_TransferFunctionDockWidget->GetCurrentWidget(); #ifdef HAS_OPENMP #pragma omp for #endif for( int i = 0; i < NumberOfChannels; i++ ) { std::string name = m_ImageProcessor->getChannelName(i); m_TransferFunctionDockWidget->SetCurrentWidget(i); GoTransferFunctionEditorWidget* widget = dynamic_cast( m_TransferFunctionDockWidget->GetWidget(i) ); // update histogram widget->AddHistogram(m_ImageProcessor->getHistogram(name) ); // update max value widget->SetMaximumValue( m_ImageProcessor->getImageBW(name)->GetScalarRange()[1]); } m_TransferFunctionDockWidget->SetCurrentWidget(currentChannel); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------- void QGoTabImageView3DwT:: PolydatasRequested() { std::list< vtkPolyData* > elements = this->m_MeshContainer-> GetHighlightedElements(); emit RequestedPolydatas(elements); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: SetUpShortcuts(){ // move to next time point (void)new QShortcut( QKeySequence( tr("Ctrl+C", "Next Time Point")), this, SLOT(MoveToNextTimePoint())); (void)new QShortcut( QKeySequence( tr("Right Arrow", "Next Time Point")), this, SLOT(MoveToNextTimePoint())); // move to previous time point (void)new QShortcut( QKeySequence( tr("Ctrl+Z", "Previous Time Point")), this, SLOT(MoveToPreviousTimePoint())); (void)new QShortcut( QKeySequence( tr("Left Arrow", "Next Time Point")), this, SLOT(MoveToPreviousTimePoint())); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: MoveToNextTimePoint() { m_NavigationDockWidget->MoveToNextTimePoint(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: MoveToPreviousTimePoint() { m_NavigationDockWidget->MoveToPreviousTimePoint(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT:: CreateDopplerTFEditor() { std::vector time = m_ImageProcessor->getDopplerTime(m_TCoord); int N = static_cast< int >( m_ImageProcessor->getDopplerSize() ); #ifdef HAS_OPENMP #pragma omp for #endif for(int i=0; i < N; ++i) { if(time[i]>=0) { std::string name = m_ImageProcessor->getChannelName(time[i]); createTransferFunctionEditor(QString::fromStdString(name)); } } } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/Video/0000755000175000017500000000000011667757442016506 5ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/lib/Video/vtkFFMPEGRenderWindowRecorder.cxx0000644000175000017500000000624311667757442024746 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkFFMPEGRenderWindowRecorder.h" #include "vtkFFMPEGWriter.h" #include "vtkObjectFactory.h" /** * \brief Constructor */ vtkFFMPEGRenderWindowRecorder::vtkFFMPEGRenderWindowRecorder() { m_ImageWriter = vtkFFMPEGWriter::New(); // initialise values in the writer vtkFFMPEGWriter *tempFFFFMPEG = vtkFFMPEGWriter::SafeDownCast(m_ImageWriter); tempFFFFMPEG->SetQuality(m_VideoQuality); #if defined ( VTKTRUNK ) tempFFFFMPEG->SetBitRate(m_BitRate); tempFFFFMPEG->SetBitRateTolerance(m_BitRate); #endif /* VTKTRUNK */ tempFFFFMPEG->SetRate(m_FrameRate); } /** * \brief Destructor */ vtkFFMPEGRenderWindowRecorder:: ~vtkFFMPEGRenderWindowRecorder() { m_ImageWriter->Delete(); } void vtkFFMPEGRenderWindowRecorder::SetSpecificParameters() { vtkFFMPEGWriter *tempFFFFMPEG = vtkFFMPEGWriter::SafeDownCast(m_ImageWriter); tempFFFFMPEG->SetQuality(m_VideoQuality); #if defined ( VTKTRUNK ) tempFFFFMPEG->SetBitRate(m_BitRate); tempFFFFMPEG->SetBitRateTolerance(m_BitRate); #endif /* VTKTRUNK */ tempFFFFMPEG->SetRate(m_FrameRate); } vtkFFMPEGRenderWindowRecorder * vtkFFMPEGRenderWindowRecorder::New() { // First try to create the object from the vtkObjectFactory vtkObject *ret = vtkObjectFactory::CreateInstance("vtkFFMPEGRenderWindowRecorder"); if ( ret ) { return static_cast< vtkFFMPEGRenderWindowRecorder * >( ret ); } return new vtkFFMPEGRenderWindowRecorder; }GoFigure2-v0.9.0/Code/GUI/lib/Video/vtkAVIRenderWindowRecorder.h0000644000175000017500000000460011667757442024041 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkAVIRenderWindowRecorder_h #define __vtkAVIRenderWindowRecorder_h #include #include #include "vtkRenderWindowMovieRecorder.h" #include "vtkObject.h" #include "QGoGUILibConfigure.h" class QGOGUILIB_EXPORT vtkAVIRenderWindowRecorder:public vtkRenderWindowMovieRecorder { public: static vtkAVIRenderWindowRecorder * New(); vtkTypeMacro(vtkAVIRenderWindowRecorder, vtkRenderWindowMovieRecorder); // set/get the quality of the video void SetSpecificParameters(); protected: vtkAVIRenderWindowRecorder(); ~vtkAVIRenderWindowRecorder(); }; #endif /*__VTKAVIRENDERWINDOWRECORDER_H*/ GoFigure2-v0.9.0/Code/GUI/lib/Video/vtkRenderWindowMovieRecorder.cxx0000644000175000017500000000744711667757442025070 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkRenderWindowMovieRecorder.h" #include "vtkRenderWindow.h" #include "vtkWindowToImageFilter.h" #include "vtkGenericMovieWriter.h" #include "vtkObjectFactory.h" /** * \brief Constructor */ vtkRenderWindowMovieRecorder::vtkRenderWindowMovieRecorder() : m_VideoQuality(1), m_FrameRate(10), m_BitRate(1024 * 1024 * 32) /*: m_FileName("goFigure2"), m_ControlIfVideoStarted (false)*/ { m_ImageFilter = vtkWindowToImageFilter::New(); } /** * \brief Destructor */ vtkRenderWindowMovieRecorder:: ~vtkRenderWindowMovieRecorder() { m_ImageFilter->Delete(); } /** * \brief Set the name of the video * \param[in] iFileName Name of the video */ void vtkRenderWindowMovieRecorder::SetFileName(const std::string & iFileName) { m_FileName = iFileName; } /** * \brief Set the rendering window to be observed * \param[in] iRenderWindow Rendering Window to be observed */ void vtkRenderWindowMovieRecorder::SetRenderingWindow(vtkRenderWindow *iRenderWindow) { m_RenderWindow = iRenderWindow; m_ImageFilter->SetInput(m_RenderWindow); m_ImageWriter->SetInput( m_ImageFilter->GetOutput() ); } /** * \brief Start the video acquisition */ void vtkRenderWindowMovieRecorder::StartCapture() { m_ImageWriter->SetFileName( m_FileName.c_str() ); if ( m_ImageWriter->GetInput() ) { m_ImageWriter->Start(); m_ControlIfVideoStarted = true; } } /** * \brief End the video acquisition */ void vtkRenderWindowMovieRecorder::EndCapture() { if ( m_ControlIfVideoStarted ) { m_ImageWriter->End(); m_ControlIfVideoStarted = false; } } /** * \brief Take a snapshot of the current rendering window */ void vtkRenderWindowMovieRecorder::TakeSnapshot() { if ( m_ControlIfVideoStarted ) { m_ImageFilter->Modified(); m_ImageWriter->Write(); } } void vtkRenderWindowMovieRecorder::SetVideoQuality(int value) { m_VideoQuality = value; } void vtkRenderWindowMovieRecorder::SetFrameRate(int value) { m_FrameRate = value; } void vtkRenderWindowMovieRecorder::SetBitRate(int value) { m_BitRate = value; }GoFigure2-v0.9.0/Code/GUI/lib/Video/vtkRenderWindowMovieRecorder.h0000644000175000017500000000626711667757442024514 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkRenderWindowMovieRecorder_h #define __vtkRenderWindowMovieRecorder_h #include #include #include "vtkProcessObject.h" #include "vtkGenericMovieWriter.h" #include "QGoGUILibConfigure.h" class vtkRenderWindow; class vtkWindowToImageFilter; class QGOGUILIB_EXPORT vtkRenderWindowMovieRecorder:public vtkProcessObject { public: //static vtkRenderWindowMovieRecorder *New(); vtkTypeMacro(vtkRenderWindowMovieRecorder, vtkProcessObject); // set the name of the video (can be a path) void SetFileName(const std::string &); // set the render window to be observed void SetRenderingWindow(vtkRenderWindow *); // start the video acquisition void StartCapture(); // end the video acquisition void EndCapture(); // take a snapshot of the current render window void TakeSnapshot(); virtual void SetSpecificParameters() = 0; virtual void SetVideoQuality(int); virtual void SetFrameRate(int); virtual void SetBitRate(int); protected: vtkRenderWindowMovieRecorder(); ~vtkRenderWindowMovieRecorder(); vtkRenderWindow * m_RenderWindow; vtkWindowToImageFilter *m_ImageFilter; vtkGenericMovieWriter * m_ImageWriter; std::string m_FileName; bool m_ControlIfVideoStarted; int m_VideoQuality; int m_FrameRate; int m_BitRate; }; #endif /* VTKRENDERWINDOWMOVIERECORDER_H_ */ GoFigure2-v0.9.0/Code/GUI/lib/Video/QGoVideoRecorder.cxx0000644000175000017500000005267711667757442022416 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoVideoRecorder.h" #include #include #include "QGoImageView3D.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowMovieRecorder.h" #ifdef ENABLEFFMPEG #include "vtkFFMPEGRenderWindowRecorder.h" #endif #ifdef ENABLEAVI #include "vtkAVIRenderWindowRecorder.h" #endif //------------------------------------------------------------------------- QGoVideoRecorder::QGoVideoRecorder(QWidget *iParent) : QGoDockWidget(iParent), m_VideoName2(""), m_FrameRate2(10), m_VideoQuality2(2), m_SliceFT(0), m_WindowSelected(0), m_XMinForVideo(0), m_XMaxForVideo(0), m_YMinForVideo(0), m_YMaxForVideo(0), m_ZMinForVideo(0), m_ZMaxForVideo(0), m_TMinForVideo(0), m_TMaxForVideo(0), m_FrameCounter(0), m_RenderWindowSelected(false) { this->setupUi(this); QObject::connect( this->startVideo, SIGNAL( clicked() ), this, SLOT( onStartVideoClicked() ) ); QObject::connect( this->startRecord, SIGNAL( clicked() ), this, SLOT( onStartRecordClicked() ) ); QObject::connect( this->endRecord, SIGNAL( clicked() ), this, SLOT( onEndRecordClicked() ) ); QIcon videoIcon( QPixmap( QString::fromUtf8(":/fig/video.png") ) ); this->m_ToggleAction->setIcon(videoIcon); this->m_ToggleAction ->setStatusTip( tr("You have to be in full screen view to use the video recording") ); this->warning_1->hide(); this->warning_2->hide(); // Tooltips to help the user QString ttoolTip = "Start recording the video"; this->startVideo->setToolTip(ttoolTip); ttoolTip = "First slice of the video"; this->tSpinMin_2->setToolTip(ttoolTip); ttoolTip = "Last slice of the video"; this->tSpinMax_2->setToolTip(ttoolTip); ttoolTip = "Location and name of the video"; this->createFile->setToolTip(ttoolTip); ttoolTip = "Create video along this axe"; this->SliceFT->setToolTip(ttoolTip); ttoolTip = "Continue creating video from selected time points"; this->pauseVideo->setToolTip(ttoolTip); ttoolTip = "End the video"; this->endVideo->setToolTip(ttoolTip); ttoolTip = "Create video without manual interaction (usefull in 2D)"; this->tabVideoMethod1->setToolTip(ttoolTip); ttoolTip = "Create video with manual interaction (usefull in 3D)"; this->tabVideoMethod2->setToolTip(ttoolTip); ttoolTip = "Quality of the output video (high=2, medium=1, low=0)"; this->videoQuality->setToolTip(ttoolTip); m_InternalTimer = new QTimer(this); QObject::connect( m_InternalTimer, SIGNAL( timeout() ), this, SLOT( timeout() ) ); //Initalize chrono with .00 (not 0) QString value = "0.00"; this->videoLenght->display(value); this->endRecord->setEnabled(false); this->tabVideoWidget->setEnabled(false); #ifdef ENABLEFFMPEG m_FFMPEGWriter = vtkFFMPEGRenderWindowRecorder::New(); this->SetMovieRecorder(m_FFMPEGWriter); #endif /* ENABLEFFMPEG */ #ifdef ENABLEAVI m_AVIWriter = vtkAVIRenderWindowRecorder::New(); this->SetMovieRecorder(m_AVIWriter); #endif /* ENABLEAVI */ QObject::connect( this, SIGNAL( FrameRateChanged(int) ), this, SLOT( SetSpecificParametersFrameRate(int) ) ); QObject::connect( this, SIGNAL( QualityChanged(int) ), this, SLOT( SetSpecificParametersQuality(int) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoVideoRecorder:: ~QGoVideoRecorder() { #ifdef ENABLEFFMPEG m_FFMPEGWriter->Delete(); #endif #ifdef ENABLEAVI m_AVIWriter->Delete(); #endif } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::SetXMinAndMax(const int & XMin, const int & XMax) { m_XMin = XMin; m_XMax = XMax; m_XMinForVideo = XMin; m_XMaxForVideo = XMax; //Initialization of the spinboxes this->tSpinMin_2->setMinimum(m_XMin); this->tSpinMin_2->setMaximum(m_XMax); this->tSpinMin_2->setValue(m_XMin); this->tSpinMax_2->setMinimum(m_XMin); this->tSpinMax_2->setMaximum(m_XMax); this->tSpinMax_2->setValue(m_XMax); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::SetYMinAndMax(const int & YMin, const int & YMax) { m_YMin = YMin; m_YMax = YMax; m_YMinForVideo = YMin; m_YMaxForVideo = YMax; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::SetZMinAndMax(const int & ZMin, const int & ZMax) { m_ZMin = ZMin; m_ZMax = ZMax; m_ZMinForVideo = ZMin; m_ZMaxForVideo = ZMax; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::SetTMinAndMax(const int & TMin, const int & TMax) { m_TMin = TMin; m_TMax = TMax; m_TMinForVideo = TMin; m_TMaxForVideo = TMax; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::SetCurrentX(const int & X) { m_CurrentX = X; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::SetCurrentY(const int & Y) { m_CurrentY = Y; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::SetCurrentZ(const int & Z) { m_CurrentZ = Z; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::SetCurrentT(const int & T) { m_CurrentT = T; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::UpdateQSpinBoxFT(int value) { switch ( value ) { case 0: { // X Slice this->tSpinMin_2->setMinimum(m_XMin); this->tSpinMin_2->setMaximum(m_XMax); this->tSpinMin_2->setValue(m_XMin); this->tSpinMax_2->setMinimum(m_XMin); this->tSpinMax_2->setMaximum(m_XMax); this->tSpinMax_2->setValue(m_XMax); m_SliceFT = 0; break; } case 1: { // Y Slice this->tSpinMin_2->setMinimum(m_YMin); this->tSpinMin_2->setMaximum(m_YMax); this->tSpinMin_2->setValue(m_YMin); this->tSpinMax_2->setMinimum(m_YMin); this->tSpinMax_2->setMaximum(m_YMax); this->tSpinMax_2->setValue(m_YMax); m_SliceFT = 1; break; } case 2: { // Z Slice this->tSpinMin_2->setMinimum(m_ZMin); this->tSpinMin_2->setMaximum(m_ZMax); this->tSpinMin_2->setValue(m_ZMin); this->tSpinMax_2->setMinimum(m_ZMin); this->tSpinMax_2->setMaximum(m_ZMax); this->tSpinMax_2->setValue(m_ZMax); m_SliceFT = 2; break; } default: case 3: { // Z Slice this->tSpinMin_2->setMinimum(m_TMin); this->tSpinMin_2->setMaximum(m_TMax); this->tSpinMin_2->setValue(m_TMin); this->tSpinMax_2->setMinimum(m_TMin); this->tSpinMax_2->setMaximum(m_TMax); this->tSpinMax_2->setValue(m_TMax); m_SliceFT = 3; break; } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::on_SliceFT_activated(int value) { UpdateQSpinBoxFT(value); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::on_tSpinMin_2_valueChanged(int value) { switch ( m_SliceFT ) { case 0: { // X Slice m_XMinForVideo = value; break; } case 1: { // Y Slice m_YMinForVideo = value; break; } case 2: { // Z Slice m_ZMinForVideo = value; break; } default: case 3: { // Z Slice m_TMinForVideo = value; break; } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::on_tSpinMax_2_valueChanged(int value) { switch ( m_SliceFT ) { case 0: { // X Slice m_XMaxForVideo = value; break; } case 1: { // Y Slice m_YMaxForVideo = value; break; } case 2: { // Y Slice m_ZMaxForVideo = value; break; } default: case 3: { // Y Slice m_TMaxForVideo = value; break; } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::on_createFile_clicked() { m_VideoName2 = QFileDialog::getSaveFileName(this, tr("Folder to Save Video"), "fileName", 0); this->createFile->setStyleSheet("background-color: rgb(0, 255, 0); color: rgb(0, 0, 0)"); this->createFile_2->setStyleSheet("background-color: rgb(255, 165, 0); color: rgb(0, 0, 0)"); QPalette plt; plt.setColor(QPalette::WindowText, Qt::black); this->label->setPalette(plt); this->label_2->setPalette(plt); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::on_frameRate_valueChanged(int value) { if ( m_FrameRate2 != static_cast< unsigned int >( value ) ) { m_FrameRate2 = static_cast< unsigned int >( value ); this->frameRate_2->setValue(value); emit FrameRateChanged(value); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::on_videoQuality_valueChanged(int value) { if ( m_VideoQuality2 != static_cast< unsigned int >( value ) ) { m_VideoQuality2 = static_cast< unsigned int >( value ); this->videoQuality_2->setValue(value); emit QualityChanged(value); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::on_createFile_2_clicked() { m_VideoName2 = QFileDialog::getSaveFileName(this, tr("Folder to Save Video"), "fileName", 0); this->createFile_2->setStyleSheet("background-color: rgb(0, 255, 0); color: rgb(0, 0, 0)"); this->createFile->setStyleSheet("background-color: rgb(255, 165, 0); color: rgb(0, 0, 0)"); QPalette plt; plt.setColor(QPalette::WindowText, Qt::black); this->label->setPalette(plt); this->label_2->setPalette(plt); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::on_frameRate_2_valueChanged(int value) { if ( m_FrameRate2 != static_cast< unsigned int >( value ) ) { m_FrameRate2 = static_cast< unsigned int >( value ); this->frameRate->setValue(value); emit FrameRateChanged(value); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::on_videoQuality_2_valueChanged(int value) { if ( m_VideoQuality2 != static_cast< unsigned int >( value ) ) { m_VideoQuality2 = static_cast< unsigned int >( value ); this->videoQuality->setValue(value); emit QualityChanged(value); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::onStartVideoClicked() { //something to record first view if ( m_VideoName2.isNull() || m_VideoName2.isEmpty() || ( !m_RenderWindowSelected ) ) { QPalette plt; plt.setColor(QPalette::WindowText, Qt::red); this->label->setPalette(plt); this->label_2->setPalette(plt); this->createFile->setStyleSheet("background-color: rgb(255, 0, 0); color: rgb(0, 0, 0)"); this->createFile_2->setStyleSheet("background-color: rgb(255, 0, 0)"); } else { QString fileName = m_VideoName2; QString fileName2 = m_VideoName2; if ( !fileName.endsWith(".avi") ) { fileName.insert( fileName.size(), QString(".avi") ); fileName2.insert( fileName.size(), QString(".txt") ); } else { fileName2.replace( QString(".avi"), QString(".txt") ); } m_VideoRecorder->SetFileName( fileName.toStdString() ); m_VideoRecorder->StartCapture(); this->startVideo->setEnabled(false); m_OutputVideoFile.open( fileName2.toStdString().c_str() ); m_OutputVideoFile << "FrameRate: "; m_OutputVideoFile << m_FrameRate2; m_OutputVideoFile << "\nVideoQuality: "; m_OutputVideoFile << m_VideoQuality2; m_OutputVideoFile << "\nX Y Z T "; AcquireWithPause(m_SliceFT); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::onStartRecordClicked() { if ( ( m_VideoName2 == NULL ) || ( !m_RenderWindowSelected ) ) { QPalette plt; plt.setColor(QPalette::WindowText, Qt::red); this->label->setPalette(plt); this->label_2->setPalette(plt); this->createFile->setStyleSheet("background-color: rgb(255, 0, 0)"); this->createFile_2->setStyleSheet("background-color: rgb(255, 0, 0); color: rgb(0, 0, 0)"); } else { this->createFile_2->setEnabled(false); this->frameRate_2->setEnabled(false); this->videoQuality_2->setEnabled(false); this->startRecord->setEnabled(false); this->tabVideoMethod1->setEnabled(false); this->endRecord->setEnabled(true); QString fileName = m_VideoName2; if ( !fileName.endsWith(".avi") ) { fileName.insert( fileName.size(), QString(".avi") ); } m_VideoRecorder->SetFileName( fileName.toStdString() ); m_VideoRecorder->StartCapture(); m_InternalTimer->start(1000 / m_FrameRate2); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::onEndRecordClicked() { m_OutputVideoFile.close(); m_VideoRecorder->EndCapture(); m_InternalTimer->stop(); m_FrameCounter = 0; this->createFile_2->setEnabled(true); this->frameRate_2->setEnabled(true); this->videoQuality_2->setEnabled(true); this->startRecord->setEnabled(true); this->tabVideoMethod1->setEnabled(true); this->endRecord->setEnabled(false); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::timeout() { m_VideoRecorder->TakeSnapshot(); ++m_FrameCounter; // for a better visualisation, always show 2 decimal double doubleCounter; doubleCounter = (double)m_FrameCounter / (double)m_FrameRate2; int test = 100 * doubleCounter; QString value = QString::number(test, 10); if ( test >= 10 ) { value.insert( value.size() - 2, QString(".") ); } else { value.insert( value.size() - 1, QString(".0") ); } if ( test < 100 ) { value.insert( value.size() - 3, QString("0") ); } this->videoLenght->display(value); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void QGoVideoRecorder::SetRenderingWindow(vtkRenderWindow *iRenderingWindow) { m_RenderWindowSelected = iRenderingWindow; this->tabVideoWidget->setEnabled(m_RenderWindowSelected); if ( m_RenderWindowSelected ) { m_VideoRecorder->SetRenderingWindow(iRenderingWindow); } //Tell the user to go in full screen mode /* if( iRenderingWindow ) { this->warning_1->hide(); this->warning_2->hide(); } else { this->warning_1->show(); this->warning_2->show(); }*/ /** * \todo Resize image with the first one if we want to change views during record */ } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::SetMovieRecorder(vtkRenderWindowMovieRecorder *Test) { m_VideoRecorder = Test; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::AcquireWithPause(int value) { unsigned int iMin; unsigned int iMax; switch ( value ) { case 0: { // X Slice iMin = m_XMinForVideo; iMax = m_XMaxForVideo; break; } case 1: { // Y Slice iMin = m_YMinForVideo; iMax = m_YMaxForVideo; break; } case 2: { // Z Slice iMin = m_ZMinForVideo; iMax = m_ZMaxForVideo; break; } default: case 3: { // T Slice iMin = m_TMinForVideo; iMax = m_TMaxForVideo; break; } } for ( unsigned int i = iMin; i < iMax + 1; i++ ) { //send signal to change slice emitChangeSliceSignal(value, i); //send signal to know our position in the 3D volume emit GetSliceView(); m_OutputVideoFile << "\n"; m_OutputVideoFile << m_CurrentX; m_OutputVideoFile << " "; m_OutputVideoFile << m_CurrentY; m_OutputVideoFile << " "; m_OutputVideoFile << m_CurrentZ; m_OutputVideoFile << " "; m_OutputVideoFile << m_CurrentT; //capture screen m_VideoRecorder->TakeSnapshot(); } this->pauseVideo->setEnabled(true); this->endVideo->setEnabled(true); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::on_pauseVideo_clicked() { AcquireWithPause(m_SliceFT); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::on_endVideo_clicked() { m_VideoRecorder->EndCapture(); this->endVideo->setEnabled(false); this->pauseVideo->setEnabled(false); this->startVideo->setEnabled(true); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoVideoRecorder::emitChangeSliceSignal(const int & iSlice, const int & iSlide) { switch ( iSlice ) { case 0: { // X Slice emit XSliceChanged(iSlide); break; } case 1: { // Y Slice emit YSliceChanged(iSlide); break; } case 2: { // Z Slice emit ZSliceChanged(iSlide); break; } default: case 3: { // Z Slice emit TSliceChanged(iSlide); break; } } } void QGoVideoRecorder::SetSpecificParametersFrameRate(int iValue) { m_VideoRecorder->SetFrameRate(iValue); m_VideoRecorder->SetSpecificParameters(); } void QGoVideoRecorder::SetSpecificParametersQuality(int iValue) { m_VideoRecorder->SetVideoQuality(iValue); m_VideoRecorder->SetBitRate(iValue * 1024 * 1024 * 32); m_VideoRecorder->SetSpecificParameters(); }GoFigure2-v0.9.0/Code/GUI/lib/Video/vtkAVIRenderWindowRecorder.cxx0000644000175000017500000000550611667757442024422 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkAVIRenderWindowRecorder.h" #include "vtkAVIWriter.h" #include "vtkObjectFactory.h" /** * \brief Constructor */ vtkAVIRenderWindowRecorder::vtkAVIRenderWindowRecorder() { m_ImageWriter = vtkAVIWriter::New(); // initialise values in the writer vtkAVIWriter *tempAVI = vtkAVIWriter::SafeDownCast(m_ImageWriter); tempAVI->SetQuality(m_VideoQuality); tempAVI->SetRate(m_FrameRate); } /** * \brief Destructor */ vtkAVIRenderWindowRecorder:: ~vtkAVIRenderWindowRecorder() { m_ImageWriter->Delete(); } void vtkAVIRenderWindowRecorder::SetSpecificParameters() { vtkAVIWriter *tempAVI = vtkAVIWriter::SafeDownCast(m_ImageWriter); tempAVI->SetQuality(m_VideoQuality); tempAVI->SetRate(m_FrameRate); } vtkAVIRenderWindowRecorder * vtkAVIRenderWindowRecorder::New() { // First try to create the object from the vtkObjectFactory vtkObject *ret = vtkObjectFactory::CreateInstance("vtkAVIRenderWindowRecorder"); if ( ret ) { return static_cast< vtkAVIRenderWindowRecorder * >( ret ); } return new vtkAVIRenderWindowRecorder; }GoFigure2-v0.9.0/Code/GUI/lib/Video/QGoVideoRecorder.h0000644000175000017500000001642511667757442022032 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGOVIDEORECORDER_H #define __QGOVIDEORECORDER_H #include "ui_NewVideoRecorderDockWidget.h" #include #include #include #include "QGoGUILibConfigure.h" #include "vtkSmartPointer.h" #include "QGoDockWidget.h" class vtkRenderWindow; class vtkRenderWindowMovieRecorder; #ifdef ENABLEFFMPEG class vtkFFMPEGRenderWindowRecorder; #endif #ifdef ENABLEAVI class vtkAVIRenderWindowRecorder; #endif /* * \brief QGoVideoRecorder to record videos to using AVI or FFMPEG */ class QGOGUILIB_EXPORT QGoVideoRecorder: public QGoDockWidget, private Ui::NewDockWidgetVideoRecorder { Q_OBJECT public: /** * \brief Constructor */ explicit QGoVideoRecorder(QWidget *parent = 0); /** * \brief Destructor */ ~QGoVideoRecorder(); /** * \brief Set value X Min and Max for a given image (useful for spin boxes) * when image is loaded, to know boundaries of the spin box to be used */ void SetXMinAndMax(const int &, const int &); /** * \brief Set value Y Min and Max for a given image (useful for spin boxes) * when image is loaded, to know boundaries of the spin box to be used */ void SetYMinAndMax(const int &, const int &); /** * \brief Set value Z Min and Max for a given image (useful for spin boxes) * when image is loaded, to know boundaries of the spin box to be used */ void SetZMinAndMax(const int &, const int &); /** * \brief Set value T Min and Max for a given image (useful for spin boxes) * when image is loaded, to know boundaries of the spin box to be used */ void SetTMinAndMax(const int &, const int &); /** * \brief Set current X value (useful for spin boxes) */ void SetCurrentX(const int &); /** * \brief Set current Y value (useful for spin boxes) */ void SetCurrentY(const int &); /** * \brief Set current Z value (useful for spin boxes) */ void SetCurrentZ(const int &); /** * \brief Set current T value (useful for spin boxes) */ void SetCurrentT(const int &); std::ofstream m_OutputVideoFile; QString m_VideoName2; unsigned int m_FrameRate2; unsigned int m_VideoQuality2; int m_SliceFT; // in tab "record video" unsigned int m_WindowSelected; unsigned int m_XMinForVideo; unsigned int m_XMaxForVideo; unsigned int m_YMinForVideo; unsigned int m_YMaxForVideo; unsigned int m_ZMinForVideo; unsigned int m_ZMaxForVideo; unsigned int m_TMinForVideo; unsigned int m_TMaxForVideo; QTimer * m_InternalTimer; unsigned int m_FrameCounter; bool m_RenderWindowSelected; void SetMovieRecorder(vtkRenderWindowMovieRecorder *); public slots: void SetSpecificParametersFrameRate(int iValue); void SetSpecificParametersQuality(int iValue); signals: void XSliceChanged(int); void YSliceChanged(int); void ZSliceChanged(int); void TSliceChanged(int); void QualityChanged(int); void FrameRateChanged(int); void GetSliceView(); protected: #ifdef ENABLEFFMPEG vtkFFMPEGRenderWindowRecorder * m_FFMPEGWriter; #else #ifdef ENABLEAVI vtkAVIRenderWindowRecorder * m_AVIWriter; #endif #endif private: // Video recorder vtkRenderWindowMovieRecorder *m_VideoRecorder; // Min/Max value of X/Y/ZSlice to set up spin box unsigned int m_XMin; unsigned int m_XMax; unsigned int m_YMin; unsigned int m_YMax; unsigned int m_ZMin; unsigned int m_ZMax; unsigned int m_TMin; unsigned int m_TMax; unsigned int m_CurrentX; unsigned int m_CurrentY; unsigned int m_CurrentZ; unsigned int m_CurrentT; /** * \brief Function to update spinbox extent according to selected slice **/ void UpdateQSpinBoxFT(int); /** * \brief Function to create the video with "pauses" **/ void AcquireWithPause(int); void emitChangeSliceSignal(const int &, const int &); private slots: // in tab "create video" //Choose a slice T Fixed /** * \brief Update starting slice for video (fixed time point) */ void on_tSpinMin_2_valueChanged(int); /** * \brief Update ending slice for video (fixed time point) */ void on_tSpinMax_2_valueChanged(int); //Video parameters /** * \brief Create the video from */ void on_createFile_clicked(); /** * \brief Function called when FrameRate changes */ void on_frameRate_valueChanged(int); /** * \brief Function called when VideoQuality changes */ void on_videoQuality_valueChanged(int); //Video parameters /** * \brief Function called to choose name/path of output file */ void on_createFile_2_clicked(); /** * \brief Update value of frame rate */ void on_frameRate_2_valueChanged(int); /** * \brief Update value of video quality */ void on_videoQuality_2_valueChanged(int); /** * \brief Update content of spin box depending of selected slice (X,Y,Z) */ void on_SliceFT_activated(int); /** * \brief Function called when "Create video" clicked in Create tab **/ void onStartVideoClicked(); /** * \brief Function called when "Create video" clicked in Record tab **/ void onStartRecordClicked(); /** * \brief Function called when "End video" clicked in Record tab **/ void onEndRecordClicked(); /** * \brief Function called with the timer to take snapshots **/ void timeout(); /** * \brief Function called when we want to restart video while it is in pause **/ void on_pauseVideo_clicked(); /** * \brief Function called when we want to stop video while it is in pause **/ void on_endVideo_clicked(); public slots: void SetRenderingWindow(vtkRenderWindow *); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/Video/vtkFFMPEGRenderWindowRecorder.h0000644000175000017500000000450111667757442024366 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkFFMPEGRenderWindowRecorder_h #define __vtkFFMPEGRenderWindowRecorder_h #include #include #include "vtkRenderWindowMovieRecorder.h" #include "vtkObject.h" class vtkFFMPEGRenderWindowRecorder:public vtkRenderWindowMovieRecorder { public: static vtkFFMPEGRenderWindowRecorder * New(); vtkTypeMacro(vtkFFMPEGRenderWindowRecorder, vtkRenderWindowMovieRecorder); // set/get the quality of the video void SetSpecificParameters(); protected: vtkFFMPEGRenderWindowRecorder(); ~vtkFFMPEGRenderWindowRecorder(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/0000755000175000017500000000000011667757442023306 5ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/ContourContainer.cxx0000644000175000017500000000542011667757442027327 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ContourContainer.h" #include ContourContainer::ContourContainer(QObject *iParent, QGoImageView3D *iView) : ContourMeshContainer(iParent, iView) { } ContourContainer:: ~ContourContainer() { } std::vector< vtkActor * > ContourContainer::AddTrace(vtkPolyData *iNode, vtkProperty *iProperty) { std::vector< vtkActor * > oActors; if ( m_ImageView ) { int dir = this->ComputeDirectionFromContour(iNode); if ( dir != -1 ) { m_ImageView->EnableContourWidget(true); m_ImageView->InitializeContourWidgetNodes(dir, iNode); vtkPolyData *trace = vtkPolyData::New(); trace->ShallowCopy( m_ImageView->GetContourRepresentationAsPolydata(dir) ); oActors = this->m_ImageView->AddContour(trace, iProperty); m_ImageView->ReinitializeContourWidget(); m_ImageView->EnableContourWidget(false); } else { qWarning() << "iNodes is not an axis-aligned contour"; } } return oActors; }GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/LineageContainer.cxx0000644000175000017500000002533711667757442027253 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "LineageContainer.h" #include "itkMacro.h" //------------------------------------------------------------------------- LineageContainer:: LineageContainer(QObject *iParent,QGoImageView3D *iView):Superclass(iParent, iView) {} //------------------------------------------------------------------------- //------------------------------------------------------------------------- LineageContainer:: ~LineageContainer() { MultiIndexContainerType::iterator it = m_Container.begin(); while ( it != m_Container.end() ) { it->ReleaseData(); ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void LineageContainer:: InsertNewLineage(const unsigned int& iLineageID, double irgba[4], const unsigned int& iTrackIDRoot, const bool& IsVisible) { MultiIndexContainerElementType NewElement; NewElement.TraceID = iLineageID; NewElement.rgba[0] = irgba[0]; NewElement.rgba[1] = irgba[1]; NewElement.rgba[2] = irgba[2]; NewElement.rgba[3] = irgba[3]; NewElement.TrackRootID = iTrackIDRoot; NewElement.Visible = IsVisible; this->Insert(NewElement); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool LineageContainer::DeleteElement(const unsigned int & iId) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iId); if( it != m_Container.get< TraceID >().end() ) { return DeleteElement(it); } return false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool LineageContainer::DeleteElement(MultiIndexContainerTraceIDIterator iIter) { assert(iIter != m_Container.get< TraceID >().end() ); m_Container.get< TraceID >().erase(iIter); return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > LineageContainer::DeleteAllHighlightedElements() { assert ( this->m_ImageView ); MultiIndexContainerHighlightedIterator it0, it1, it_t; boost::tuples::tie(it0, it1) = m_Container.get< Highlighted >().equal_range(true); std::list< unsigned int > oList; while ( it0 != it1 ) { oList.push_back(it0->TraceID); // to delete the divisions of the lineage in the track container // signals connected in the QGoDBLineageManager //emit DeleteLineage(it0->TrackRootID); it_t = it0; ++it0; m_Container.get< Highlighted >().erase(it_t); } m_ImageView->UpdateRenderWindows(); return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector< vtkActor* > LineageContainer::AddTrace( vtkPolyData* , vtkProperty* ) { return std::vector< vtkActor* >(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list LineageContainer::GetListOfTrackRootIDs() { std::list listOfTrackIDs; MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().begin(); while( it != m_Container.get< TraceID >().end() ) { listOfTrackIDs.push_back(it->TrackRootID); ++it; } return listOfTrackIDs; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list LineageContainer::GetListOfLineageIDs() { std::list listOfLineageIDs; MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().begin(); while( it != m_Container.get< TraceID >().end() ) { listOfLineageIDs.push_back(it->TraceID); ++it; } return listOfLineageIDs; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int LineageContainer::GetLineageTrackRootID( const unsigned int& iTraceID ) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find( iTraceID ); /* \todo Nicolas-shouldnt have to check it - sth has to be found here or bug somewhere */ if( it != m_Container.get< TraceID >().end() ) { return it->TrackRootID; } else { itkGenericExceptionMacro( <<"iTraceId is not in this container" ); return 0; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int LineageContainer::GetTraceIDFromTrackRootID( const unsigned int& iTraceID ) { MultiIndexContainerTrackRootIDIterator it = m_Container.get< TrackRootID >().find( iTraceID ); /* \todo Nicolas-shouldnt have to check it - sth has to be found here or bug somewhere */ if( it != m_Container.get< TrackRootID >().end() ) { return it->TraceID; } else { itkGenericExceptionMacro( <<"trackroot id is not in this container" ); return 0; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool LineageContainer::GetLineageVisibile( const unsigned int& iTraceID ) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find( iTraceID ); if( it != m_Container.get< TraceID >().end() ) { return it->Visible; } else { itkGenericExceptionMacro( <<"iTraceId is not in this container" ); return false; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool LineageContainer::GetLineageHighlighted( const unsigned int& iTraceID ) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find( iTraceID ); if( it != m_Container.get< TraceID >().end() ) { return it->Highlighted; } else { itkGenericExceptionMacro( <<"iTraceId is not in this container" ); return false; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- double* LineageContainer:: GetLineageColor( const unsigned int& iTraceID ) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find( iTraceID ); double* color = NULL; if( it != m_Container.get< TraceID >().end() ) { color = const_cast(it->rgba); } return color; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void LineageContainer:: UpdateElementHighlightingWithGivenTraceIDs( const QStringList & iList, const Qt::CheckState & iCheck) { // emit signal for each lineage to be highlighted // signal contains the trackIDroot and the state if ( !iList.empty() ) { MultiIndexContainerTraceIDIterator it; QStringList::const_iterator constIterator = iList.begin(); bool highlighted = iCheck; while ( constIterator != iList.end() ) { it = m_Container.get< TraceID >().find( ( *constIterator ).toUInt() ); if ( it != m_Container.get< TraceID >().end() ) { // modify the structure highlight m_Container.get< TraceID >(). modify( it , change_highlighted(highlighted) ); //send signal to track container emit HighlightLineage(it->TrackRootID, highlighted); } ++constIterator; } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void LineageContainer::UpdateElementVisibilityWithGivenTraceIDs(const QStringList & iList, const Qt::CheckState & iCheck) { // emit signal for each lineage to be shown/hidden // signal contains the trackIDroot and the state if ( !iList.empty() ) { MultiIndexContainerTraceIDIterator it; QStringList::const_iterator constIterator = iList.begin(); bool visible = iCheck; while ( constIterator != iList.end() ) { it = m_Container.get< TraceID >().find( ( *constIterator ).toUInt() ); if ( it != m_Container.get< TraceID >().end() ) { //modify the structure visibility m_Container.get< TraceID >(). modify( it , change_visible(visible) ); //send signal to track container emit ShowLineage(it->TrackRootID, visible); } ++constIterator; } } } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/TraceContainerBase.h0000644000175000017500000005307111667757442027161 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __TraceContainerBase_h #define __TraceContainerBase_h #include #include #include "QGoImageView3D.h" #include "vtkProperty.h" #include "StructureHelper.h" #include "QGoGUILibConfigure.h" #include "vtkIntArray.h" #include "vtkActor.h" #include "vtkMapper.h" #include "vtkDataSet.h" #include "vtkPointData.h" #include "TraceStructure.h" #include "boost/multi_index_container.hpp" #include "boost/multi_index/member.hpp" #include "boost/multi_index/hashed_index.hpp" #include "boost/multi_index/ordered_index.hpp" #include "boost/numeric/conversion/cast.hpp" #include "boost/lexical_cast.hpp" //----------------------------------------------------------------------------- template struct change_highlighted { change_highlighted(bool& iHighlight):highlighted(iHighlight){} void operator()(T& iStructure) { iStructure.Highlighted = highlighted; } private: bool highlighted; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template struct change_visible { change_visible(const bool& iVisibile):visible(iVisibile){} void operator()(T& iStructure) { iStructure.Visible = visible; } private: bool visible; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template struct change_actors { change_actors(std::vector& iActors):actor(iActors){} void operator()(T& iStructure) { iStructure.ActorXY = actor[0]; iStructure.ActorXZ = actor[1]; iStructure.ActorYZ = actor[2]; iStructure.ActorXYZ = actor[3]; } private: std::vector actor; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template struct change_color { change_color(QColor iColor):color(iColor){} void operator()(T& iStructure) { iStructure.rgba[0] = color.redF(); iStructure.rgba[1] = color.greenF(); iStructure.rgba[2] = color.blueF(); iStructure.rgba[3] = color.alphaF(); } private: QColor color; }; //----------------------------------------------------------------------------- /** * \class TraceContainerBase * \tparam TContainer boost::multi_index_container of a given TraceStructure * \brief Generic interface for trace container. * More specific container should inherit from this class and get specialized * depending on the kind of trace it contains. * */ template< class TContainer > class TraceContainerBase : public QObject { public: typedef TContainer MultiIndexContainerType; typedef typename MultiIndexContainerType::value_type MultiIndexContainerElementType; typedef typename MultiIndexContainerType::template index< TraceID >::type::iterator MultiIndexContainerTraceIDIterator; typedef typename MultiIndexContainerType::template index< CollectionID >::type::iterator MultiIndexContainerCollectionIDIterator; typedef typename MultiIndexContainerType::template index< Highlighted >::type::iterator MultiIndexContainerHighlightedIterator; typedef typename MultiIndexContainerType::template index< Visible >::type::iterator MultiIndexContainerVisibleIterator; /** \brief Constructor * \param[in] iParent Parent to provide ownership (Qt style) * \param[in] iView Visualization for trace * */ explicit TraceContainerBase( QObject* iParent, QGoImageView3D* iView ); /** \brief Destructor */ virtual ~TraceContainerBase(); /** \brief Trace Contaienr */ MultiIndexContainerType m_Container; /** \brief Link to the visualization. */ QGoImageView3D *m_ImageView; /** \brief Current Element of the trace type. */ MultiIndexContainerElementType m_CurrentElement; // ---------------------------------------------------------------------- /** \brief Print the container content in the application output. * \tparam TIterator Iterator on one index of boost::multi_index_container * or on the container itself. * */ template< class TIterator > void Print(TIterator iBegin, TIterator iEnd) { TIterator it = iBegin; while ( it != iEnd ) { std::cout << *it; std::cout << "***" << std::endl; std::cout << std::endl; ++it; } } /** \brief Print the container content in the application output according to the template parameter. \tparam TIndex */ template< class TIndex > void Print() { using boost::multi_index::get; this->Print( this->m_Container.get< TIndex >().begin(), this->m_Container.get< TIndex >().end() ); } /** \brief Print the container content in the application output. */ void Print(); // ---------------------------------------------------------------------- /** \brief Set property whenever the trace is highlighted \param[in] iProperty */ void SetHighlightedProperty(vtkProperty *iProperty); /** \brief Get property for highlighted traces */ vtkProperty * GetHighlightedProperty(); /** \brief Get the CollectionID given a TraceID */ unsigned int GetCollectionIDOfGivenTraceID( unsigned int iTraceID); /** \brief Update Visualization of the given TraceIDs \tparam TContainer Container of TraceIDs \param[in] iList input container of TraceIDs */ template< class TList > void UpdateVisualizationForGivenIDs(TList iList) { using boost::multi_index::get; typename TList::iterator it = iList.begin(); while ( it != iList.end() ) { MultiIndexContainerTraceIDIterator id_it = m_Container.get< TraceID >().find( static_cast< unsigned int >( *it ) ); if ( id_it != m_Container.get< TraceID >().end() ) { bool test = false; m_Container.get< TraceID >(). modify( id_it , change_visible(test) ); m_Container.get< TraceID >(). modify( id_it , change_highlighted(test) ); vtkProperty *tproperty = vtkProperty::New(); tproperty->SetColor(id_it->rgba[0], id_it->rgba[1], id_it->rgba[2]); tproperty->SetOpacity(id_it->rgba[3]); tproperty->SetLineWidth( this->m_IntersectionLineWidth ); if ( id_it->Nodes ) { bool test2 = id_it->Visible; m_Container.get< TraceID >(). modify( id_it , change_visible( test2 ) ); std::vector< vtkActor * > actor = this->m_ImageView->AddContour( id_it->Nodes, tproperty ); m_Container.get< TraceID >(). modify( id_it , change_actors( actor ) ); typedef void ( QGoImageView3D::*ImageViewMember )(const int &, vtkActor *); ImageViewMember f; if ( id_it->Visible ) { f = &QGoImageView3D::AddActor; } else { f = &QGoImageView3D::RemoveActor; } assert( m_ImageView ); for ( int i = 0; i < 4; i++ ) { ( m_ImageView->*f )(i, actor[i]); } } else { m_Container.get< TraceID >(). modify( id_it , change_visible(test) ); } } ++it; } } /** * \brief Update Actors, Highlighted, Visibility (properties) of given * a element * \tparam TIndex Index Type (referring to multi index container's indices) * \param[in] iIt element to update * \param[in] iActors its actors * \param[in] iHighlighted * \param[in] iVisible if false remove the element from the scene, else * add it */ template< class TIndex > void UpdateVisualizationForGivenElement( typename MultiIndexContainerType::template index< TIndex >::type::iterator& iIt, std::vector< vtkActor * > iActors, const bool & iHighlighted, const bool & iVisible) { using boost::multi_index::get; if ( iActors.size() == 4 ) { m_Container.get< TIndex >(). modify( iIt , change_actors(iActors) ); } bool highlighted = iHighlighted; bool visible = iVisible; m_Container.get< TIndex >(). modify( iIt , change_visible(visible) ); m_Container.get< TIndex >(). modify( iIt , change_highlighted(highlighted) ); typedef void ( QGoImageView3D::*ImageViewMember )(const int &, vtkActor *); ImageViewMember f; if ( iVisible ) { f = &QGoImageView3D::AddActor; } else { f = &QGoImageView3D::RemoveActor; } assert( m_ImageView ); for ( int i = 0; i < 4; i++ ) { ( m_ImageView->*f )(i, iActors[i]); } } /** \brief Insert one element in the container \param[in] iE element to be insert in the container */ void Insert(const MultiIndexContainerElementType & iE); /** \brief Insert Current Element in the container */ void InsertCurrentElement(); /** \brief Reset Current Element to a default state */ void ResetCurrentElement(); /** \brief Update Current Element from te database. \param[in] iTraceID \param[in] irgba \param[in] IsVisible */ void UpdateCurrentElementFromDB(unsigned int iTraceID, double irgba[4], bool IsVisible = false); void UpdateCurrentElementCollection(unsigned int iCollectionID); /** \brief Get the polydata representing the current element track \return Pointer to the current element track */ vtkPolyData* GetCurrentElementNodes(); /** \brief Get the color of the current element track \return Pointer to the current element color */ double* GetCurrentElementColor(); std::vector GetActorGivenTraceID( unsigned int iTraceID ); /** \brief put the information of the existing element into m_CurrentElement and remove the existing element from the container,the visu and the memory \param[in] iTraceID ID of the existing element \return true if the element was found in the container, false if not */ bool UpdateCurrentElementFromExistingOne(unsigned int iTraceID, bool iErase = true); /** \brief */ template< class TIndex > bool UpdateCurrentElementFromExistingOne( typename MultiIndexContainerType::template index< TIndex >::type::iterator iIt ) { using boost::multi_index::get; // update current element this->m_CurrentElement = *iIt; // clean the container but don't erase the pointers since we still have the // adresses in the m_CurrentElement m_Container.get< TIndex >().erase( iIt ); return true; } /** \brief Update element visibility given it TraceId \param[in] iId TraceID of the element to be modified \return true if the element was present in the container. \todo Nicolas-should return visibility instead?? */ bool UpdateElementVisibilityWithGivenTraceID(const unsigned int & iId); //------------------------------------------------------------------------- /** \brief Remove element from visualization \param[in] iId TraceID of the element to be removed \return true if the element was present in the container. */ bool RemoveElementFromVisualizationWithGivenTraceID( const unsigned int & iId); /** \brief Update element highlighting given it TraceId \param[in] iId TraceID of the element to be modified \return true if the element was present in the container. */ bool UpdateElementHighlightingWithGivenTraceID(const unsigned int & iId); //------------------------------------------------------------------------- /** \brief Get the list of highlighted elements TraceID. */ std::list< unsigned int > GetHighlightedElementsTraceID(); std::list< unsigned int > GetHighlightedElementsCollectionID(); /** \brief Get all highlighted elements by pair. */ std::list< vtkPolyData* > GetHighlightedElements(); /** \brief Remove the element which TraceId = iId
  • from the visualization
  • from the container
  • from memory (release memory)
\param[in] iId TraceID of the element to be deleted \return true if the element was present in the container. */ virtual bool DeleteElement(const unsigned int & iId) = 0; /** \overload DeleteElement(const unsigned int & iId) */ virtual bool DeleteElement(MultiIndexContainerTraceIDIterator iIter) = 0; /** \brief Delete all highlighted elements \return the list of TraceIDs of such elements */ virtual std::list< unsigned int > DeleteAllHighlightedElements() = 0; /** \brief Update all highlighted elements in the container with a given color. \note Elements remain highlighted as long as it is checked in the Table Widget. \param[in] iColor \return list of highlighted elements */ std::list< unsigned int > UpdateAllHighlightedElementsWithGivenColor( QColor iColor); /** \brief Color code contour / mesh according to values provided \param[in] iColumnName Name of data provided \param[in] iValues is a map where the key is the TraceID and the Value is a string that can be either converted to a double, or not \note if iColumnName and/or iValues are empty traces will be then rendered with their original colors. */ void SetColorCode( const std::string& iColumnName, const std::map< unsigned int, std::string >& iValues ); /** \brief Color code contour / mesh according to values provided \tparam TValue numerical type that can be converted into double \param[in] iColumnName Name of data provided \param[in] iValues is a map where the key is the TraceID and the Value is the actual data used to color. \note if iColumnName and/or iValues are empty traces will be then rendered with their original colors. */ template< typename TValue > void SetColorCode( const std::string& iColumnName, const std::map< unsigned int, TValue >& iValues ) { typedef TValue ValueType; typedef typename std::map< unsigned int, ValueType > MapType; typedef typename MapType::const_iterator MapConstIterator; using boost::multi_index::get; if( iColumnName.empty() || iValues.empty() ) { RenderAllElementsWithOriginalColors(); return; } MapConstIterator it = iValues.begin(); double temp = 0.; try { temp = boost::numeric_cast< double >( it->second ); } catch( boost::numeric::bad_numeric_cast& e ) { std::cout << e.what() <m_Container.get().find( it->first ); if( trace_it != this->m_Container.get().end() ) { if (trace_it->Nodes) //make sure the trace has points !!! { // Here let's make sure you are not passing crazy values! try { temp = boost::numeric_cast< double >( it->second ); } catch( boost::numeric::bad_numeric_cast& e ) { std::cout << e.what() < max_value ) { max_value = temp; } if( temp < min_value ) { min_value = temp; } trace_it->SetScalarData( iColumnName, temp ); } } //end make sure the trace has points !!! ++it; } SetScalarRangeForAllElements( min_value, max_value ); if( m_ImageView ) { this->m_ImageView->UpdateRenderWindows(); } } void SetRandomColor( const std::string& iColumnName, const std::map< unsigned int, unsigned int >& iIds ); void SetRandomColor( const std::string& iColumnName, const std::map< unsigned int, std::string >& iValues ); /** \brief Apply the given lookup table to all traces in the container \param[in] iLut lookup table */ void SetLookupTableForColorCoding( vtkLookupTable* iLut ); void SetIntersectionLineWidth( const float& iWidth ); protected: vtkProperty *m_HighlightedProperty; float m_IntersectionLineWidth; /** \brief Change elements highlighting property given a list of TraceIDs and the new status. \param[in] iList list of TraceIDs \param[in] iCheck */ virtual void UpdateElementHighlightingWithGivenTraceIDsBase( const QStringList& iList, const Qt::CheckState& iCheck ); /** \brief Change elements visibility property given a list of TraceIDs and the new status. \param[in] iList list of TraceIDs \param[in] iCheck */ virtual void UpdateElementVisibilityWithGivenTraceIDsBase( const QStringList& iList, const Qt::CheckState& iCheck ); /** \brief Render with original colors */ void RenderAllElementsWithOriginalColors(); /** \brief Set the scalar range */ void SetScalarRangeForAllElements(const double& iMin, const double& iMax ); void UpdateCurrentElementFromVisuBase( std::vector< vtkActor* >& iActors, vtkPolyData* iNodes, const bool& iHighlighted, const bool& iVisible ); /** \brief Update highlighting property of one element given one actor. \param[in] iActor Actor of the element to be modified \param[out] oTraceId TraceId of the element \param[out] oState Qt::Checked if the element is not highlighted else Qt::UnChecked \return true if the element exists \return false else */ void UpdateElementHighlightingWithTraceID( const unsigned int& oTraceId, Qt::CheckState& oState ) { using boost::multi_index::get; typedef typename MultiIndexContainerType::template index< TraceID >::type::iterator IteratorType; IteratorType it = m_Container.get< TraceID >().find(oTraceId); vtkProperty *temp_property = vtkProperty::New(); assert ( it != m_Container.get< TraceID >().end() ); if ( it->Highlighted ) { temp_property->SetColor(it->rgba[0], it->rgba[1], it->rgba[2]); temp_property->SetOpacity(it->rgba[3]); temp_property->SetLineWidth( this->m_IntersectionLineWidth ); } else { temp_property->DeepCopy(this->m_HighlightedProperty); } it->SetActorProperties( temp_property ); temp_property->Delete(); // Note: it->Highlighted is the status before picking the actor bool checked = false; if ( !it->Highlighted ) { oState = Qt::Checked; checked = true; } else { oState = Qt::Unchecked; } m_Container.get< TraceID >(). modify( it , change_highlighted(checked) ); assert( m_ImageView ); m_ImageView->UpdateRenderWindows(); } void UpdateElementVisibilityWithTraceID( const unsigned int& oTraceId, const bool& iState) { using boost::multi_index::get; typedef typename MultiIndexContainerType::template index< TraceID >::type::iterator IteratorType; IteratorType it = m_Container.get< TraceID >().find(oTraceId); assert ( it != m_Container.get< TraceID >().end() ); if ( it->Visible != iState ) { it->SetActorVisibility( iState ); m_Container.get< TraceID >(). modify( it , change_visible(iState) ); } } }; #include "TraceContainerBase.txx" #endif // __TraceContainerBase_h GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/MeshContainer.cxx0000644000175000017500000000433011667757442026571 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "MeshContainer.h" MeshContainer::MeshContainer(QObject *iParent, QGoImageView3D *iView) : ContourMeshContainer(iParent, iView) { } MeshContainer::~MeshContainer() { } std::vector< vtkActor * > MeshContainer::AddTrace(vtkPolyData *iNode, vtkProperty *iProperty) { if ( m_ImageView ) { return this->m_ImageView->AddContour(iNode, iProperty); } else { return std::vector< vtkActor * >(); } }GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/MeshContainer.h0000644000175000017500000000512211667757442026216 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __MeshContainer_h #define __MeshContainer_h #include "ContourMeshContainer.h" #include "QGoGUILibConfigure.h" /** * \class MeshContainer * \brief Wraps a boost::multi_index_container of ContourMeshStructure. * This class is specialized for the means of Mesh. * */ class QGOGUILIB_EXPORT MeshContainer : public ContourMeshContainer { Q_OBJECT public: /** \brief Constructor */ explicit MeshContainer(QObject* iParent, QGoImageView3D *iView); /** \brief Destructor */ ~MeshContainer(); protected: /** \brief Add a mesh in the visualization with its property. It returns a * vector of size 4, of each element represents one view in the Quad-View. */ std::vector< vtkActor* > AddTrace( vtkPolyData* iNode, vtkProperty* iProp ); private: Q_DISABLE_COPY( MeshContainer ); }; #endif // __MeshContainer_h GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/TrackContainer.h0000644000175000017500000007227511667757442026403 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __TrackContainer_h #define __TrackContainer_h #include #include "TrackStructure.h" #include "StructureHelper.h" #include "TraceContainerBase.h" #include "boost/multi_index_container.hpp" #include "boost/multi_index/member.hpp" #include "boost/multi_index/hashed_index.hpp" #include "boost/multi_index/ordered_index.hpp" #include "boost/numeric/conversion/cast.hpp" #include "boost/lexical_cast.hpp" #include "vtkProperty.h" #include "vtkPolyData.h" #include "vtkActor.h" #include "vtkMapper.h" #include "vtkPointData.h" #include "vtkDoubleArray.h" #include "QGoImageView3D.h" #include "vtkLookupTableManager.h" #include "QGoGUILibConfigure.h" #include #include "vtkMutableDirectedGraph.h" #include "GoFigureLineageAttributes.h" /** \struct change_visible_division \brief Change the visibility of a division with an unary function. \sa TrackStructure */ //----------------------------------------------------------------------------- struct change_visible_division { change_visible_division(const bool& iVisible):visible(iVisible){} void operator()(TrackStructure& iStructure) { iStructure.ModifyDivisionVisibility(visible); } private: bool visible; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /** \struct change_highlighted_division \brief Change the highlight of a division with an unary function. \sa TrackStructure */ struct change_highlighted_division { change_highlighted_division(vtkProperty* iProperty, bool iHighlight): property(iProperty),highlight(iHighlight){} void operator()(TrackStructure& iStructure) { iStructure.ModifyDivisionHighlight(property,highlight); } private: vtkProperty* property; bool highlight; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /** \struct change_color_division \brief Change the color of a division with an unary function. \sa TrackStructure */ struct change_data_color_division { change_data_color_division(const double* iColor):color(iColor){} void operator()(TrackStructure& iStructure) { iStructure.ModifyDivisionColorData(color); } private: const double* color; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /** \struct change_color_division \brief Change the color of a division with an unary function. \sa TrackStructure */ struct change_actor_color_division { change_actor_color_division(const double* iColor):color(iColor){} void operator()(TrackStructure& iStructure) { iStructure.ModifyDivisionColorActor(color); } private: const double* color; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /** \struct add_array_division \brief Add an array to a division with an unary function. Useful for the color coding. \sa TrackStructure */ struct add_array_division { add_array_division(vtkIntArray* iArray):array(iArray){} void operator()(TrackStructure& iStructure) { iStructure.AddDivisionArray(array); } private: vtkIntArray* array; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /** \struct create_node_division \brief Create a polydata for a division with an unary function. Useful for the color coding. \sa TrackStructure */ struct create_node_division { create_node_division(vtkPolyData* iNode):node(iNode){} void operator()(TrackStructure& iStructure) { iStructure.CreateDivisionNode(node); } private: vtkPolyData* node; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- /** \struct add_avg_volume \brief Create a polydata for a division with an unary function. Useful for the color coding. \sa TrackStructure */ struct add_volume { add_volume(const double& iVolume):volume(iVolume){} void operator()(TrackStructure& iStructure) { iStructure.AddVolume(volume); } private: double volume; }; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- namespace boost { typedef multi_index::multi_index_container< TrackStructure, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< TraceID >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, unsigned int, TraceID) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< CollectionID >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, unsigned int, CollectionID) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< Highlighted >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, bool, Highlighted) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< Visible >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, bool, Visible) > > > MultiIndexTrackContainer; } /** \class TrackContainer \brief Wraps a boost multi index container of TrackStructure. This class intends to synchronize Track representation in the Visualization and in the TableWidget \sa TrackStructure QGoTableWidget QGoImageView3D */ class QGOGUILIB_EXPORT TrackContainer: public TraceContainerBase< boost::MultiIndexTrackContainer > { Q_OBJECT public: typedef TraceContainerBase< boost::MultiIndexTrackContainer > Superclass; typedef Superclass::MultiIndexContainerType MultiIndexContainerType; typedef Superclass::MultiIndexContainerElementType TrackType; typedef TrackType::PointsMapType PointsMapType; typedef TrackType::PointsMapIterator PointsMapIterator; typedef TrackType::PointsMapConstIterator PointsMapConstIterator; //------------------------------------------------------------------------ /** \brief Constructor. */ explicit TrackContainer( QObject *iParent, QGoImageView3D *iView); /** \brief Destructor. */ virtual ~TrackContainer(); //------------------------------------------------------------------------- /** \brief Remove the element which TraceId = iId
  • from the visualization
  • from the container
  • from memory (release memory)
\param[in] iId TraceID of the element to be deleted \return true if the element was present in the container. */ bool DeleteElement(const unsigned int & iId); /** \overload DeleteElement(const unsigned int & iId) */ bool DeleteElement(MultiIndexContainerTraceIDIterator iIter); /** \brief Delete all highlighted elements \return the list of TraceIDs of such elements */ std::list< unsigned int > DeleteAllHighlightedElements(); /** \brief Update the TrackStructure polydata according to the current map. \param[in] iTrackStructure Structure to be updated \return true if the polydata has been updated \return false if it hasn't (i.e. mesh without point) */ bool UpdateTrackStructurePolyData(const TrackStructure& iTrackStructure); /** \brief Update the points strings of the tracks for each element of the list { 1 -Add trackID to current element 2- Remove old element 3- Get corresponding meshes centers 4- convert coordinates 5- fill map 6- generate new polydata 7- emit signal (to save in DB + insert element) 8- update the visu } \param[in] iTrackList List containing IDs of the track of interest */ template< class TList > void UpdateTracksStrings(const TList& iTrackList) { typename TList::const_iterator it = iTrackList.begin(); unsigned int temp = 0; while(it!=iTrackList.end()) { temp = static_cast< unsigned int >(*it); // update the current element UpdateCurrentElementFromExistingOne(temp); // emit signal to get the meshes informations emit NeedMeshesInfoForImportedTrack(temp); ++it; } } /** * \brief Update the current element map then polydata * \param[in] iMeshes meshes to be added in the map */ void ImportTrackInCurrentElement(std::map< unsigned int, double*>& iMeshes); /** * \brief Create new actors for the current polydata and update and visualize * the current actors * \param[in] iStructure Structure to be updated * \note input paramter not cont sine it is modified in the method */ void CreateTrackActors(TrackStructure& iStructure); /* * \brief Remove the actors from the visualization if the track has less than 2 points. * \param[in] iStructure Structure to be updated * \note input paramter not cont sine it is modified in the method */ void UpdateTrackActors(TrackStructure& iStructure); /** \brief get the element with iTrackID into the current element, remove it from the container, recalculate the points from the iListCenterBoundingBox and emit a signal for the current element to be saved into the database \param[in] iTrackID ID for the track to be updated \param[in] iListCenterBoundingBoxes list of the center of the bounding boxes for the meshes belonging to this track */ TrackStructure* UpdatePointsForATrack(const unsigned int& iTrackID, std::list< double*>& iListCenterBoundingBoxes); /** \brief Update highlighting property of one element given one actor. \param[in] iActor Actor of the element to be modified \return true if the element exists \return false else \note move to superclass */ void UpdateElementHighlighting(const unsigned int& TraceId) { Qt::CheckState state; Superclass::UpdateElementHighlightingWithTraceID(TraceId, state); emit TracePicked(TraceId, state); } /* * \brief Update the full lineage after picking a division * 1-Pick actor * 2-Get track ID * 3-Get root track ID * 4-Modify highlight * \param[in] iTraceId ID of the track which owns the picked division */ void UpdateCollectionHighlighting(const unsigned int& iTraceId); /* * \brief Convenience method to get an iterator to the root structure. * Useful for the division picking. */ void GetRootIterator( MultiIndexContainerTraceIDIterator& iMotherIterator); /** \brief Update highlighting property of one element given one actor. \param[in] iActor Actor of the element to be modified \return true if the element exists \return false else \note move to superclass*/ void UpdateElementVisibility(const unsigned int& iTraceID, const bool& iState) { Superclass::UpdateElementVisibilityWithTraceID(iTraceID, iState); if(iState) { emit TraceVisibilityChanged(iTraceID, Qt::Checked ); return; } emit TraceVisibilityChanged(iTraceID, Qt::Unchecked ); } /* * \brief Merge given tracks * \param[in] iId1 ID of the first track * \param[in] iId2 ID of the second track */ void MergeTrack(const unsigned int& iId1, const unsigned int& iId2); /* * \brief Set time interval between each image. * Useful to estimate the speed of a cell. * \param[in] iTimeInterval time interval between 2 time points */ void setTimeInterval(const int& iTimeInterval); /* * \brief Get time interval between each image. * Necessary to estimate the speed of a cell. * \return time interval between 2 time points */ int getTimeInterval(); /* * \brief Border type enum to define FIRST and LAST point for a better * lisibility */ enum BorderType { FIRST = 0, LAST = 1 }; /* * \brief Convenience to get the position (x,y,z) of a border of a track. * (first or last point). * Used to create the divisions actors. * \param[in] iTrackID track of interest * \param[in] iBorder FIRST or LAST * \return position of the first point (double* pointing to a double[3]) */ double* GetBorderOfTheTrack(const unsigned int& iTrackID, const BorderType& iBorder); /* * \brief Create divisions from a list of track ids. * the list has the following format: * motherID daughter1ID daughter2ID motherID daughter1ID ... * \param[in] iListOfDivisions list of the track ids to create the divisions */ void SetListOfDivisions(std::list& iListOfDivisions); /* * \brief Create a division between 3 tracks. * Assigns mother and child pointers. Create 4 actors (one for each view) * for this division. * \param[in] iMotherID ID of the mother of the division * \param[in] iDaughter1ID ID of the daughter1 of the division * \param[in] iDaughter2ID ID of the daughter2 of the division * \param[in] iVisible visible = true */ void AddDivision( const unsigned int& iMotherID, const unsigned int& iDaughter1ID, const unsigned int& iDaughter2ID, const bool& iVisible = true); /* * \brief Create 4 actors (one for each view) * for this division. * \param[in] iPolyData polydata representing the division * \param[in] iVisible visibility of the polydata (defaut = true) * \return vector of 4 actors (1 for each view) representing the division */ std::vector CreateDivisionActor(vtkPolyData* iPolyData, const bool& iVisible = true); /* * \brief Create Create a division from 3 track IDs. * Updates the node in the structure. * \param[in] iMother ID of the mother */ void CreateDivisionPolydata(const unsigned int& iMother); /* * \brief get the tree below a given division * \param[in] iTrackID division to start the search * \return list containing all the track IDs */ std::list GetSubLineage(const unsigned int& iTrackID); /* * \brief Convenience method to go through the tree and get a SubLineage * * \param[in] it iterator to go through the lineage * \param[in] iList list of tracks to be returned */ void UpdateSubLineage(MultiIndexContainerTraceIDIterator it, std::list& iList); /** \brief update the color and the divisions scalars of an all lineage which has iTrackIDRoot as track root */ GoFigureLineageAttributes UpdateDivisionsForALineage( unsigned int iTrackIDRoot, double* color); /* * \brief Update the lineage's divisions scalars given the track root ID * \param[in] iTrackID track root ID */ GoFigureLineageAttributes UpdateCollectionScalars(const unsigned int& iTrackID); /* * \brief Update the lineage's divisions scalars given the track root ID * \param[in] iMotherIterator iterator to go through the lineage * \param[in] iDepth depth or the structure referenced by the iterator */ void UpdateDivisionScalar( MultiIndexContainerTraceIDIterator& iMotherIterator, const unsigned int& iDepth); GoFigureLineageAttributes GetLineageAttributes(unsigned int iTrackRootID); /* * \brief Update the lineage's divisions color given the track root ID and * a color * \param[in] iTrackID track root ID * \param[in] color color of the divisions */ void UpdateCollectionColors(const unsigned int& iTrackID, const double* color); /* * \brief Update the lineage's divisions color given the track root ID and a color * \param[in] iMotherIterator iterator to go through the lineage * \param[in] color color of the divisions */ void UpdateDivisionColor( MultiIndexContainerTraceIDIterator& iMotherIterator, const double* iColor); /* * \brief Update the lineage's divisions data color given the track root ID and * a color * \param[in] iTrackID track root ID * \param[in] color color of the divisions */ void UpdateCollectionColorsData(const unsigned int& iTrackID, const double* color); /* * \brief Update the lineage's divisions data color given the track root ID and a color * \param[in] iMotherIterator iterator to go through the lineage * \param[in] color color of the divisions */ void UpdateDivisionColorData( MultiIndexContainerTraceIDIterator& iMotherIterator, const double* iColor); // compute statistics on the collection /* * \brief Get the max depth of the lineage * \param[in] iTrackRootID id of the track root * \return depth of the lineage */ unsigned int GetCollectionMaxDepth(const unsigned int& iTrackRootID); /* * \brief Update the collection max depth * \param[in] it iterator to go through the lineage * \param[in] iDivisionDepth depth of the division * \param[in] iLineageDepth depth of the lineage * \note iLineageDepth should not be const */ void UpdateCollectionMaxDepth(MultiIndexContainerTraceIDIterator& it, const unsigned int& iDivisionDepth, unsigned int& iLineageDepth); /* * \brief Get the min depth of the lineage * \param[in] iTrackRootID id of the track root * \return depth of the lineage */ unsigned int GetCollectionMinDepth(const unsigned int& iTrackRootID ); /* * \brief Update the collection min depth * \param[in] it iterator to go through the lineage * \param[in] iDivisionDepth depth of the division * \param[in] iLineageDepth depth of the lineage * \note iLineageDepth shouldnt be const */ void UpdateCollectionMinDepth( MultiIndexContainerTraceIDIterator& it, const unsigned int& iDivisionDepth, unsigned int& iLineageDepth); /* * \brief Get the number of divisions of the lineage * \param[in] iTrackRootID id of the track root * \return depth of the lineage */ unsigned int GetCollectionNumberOfDivisions( const unsigned int& iTrackRootID); /* * \brief Update the collection number of divisions * \param[in] it iterator to go through the lineage * \param[in] iNumberOfDivisions number of divisions of the lineage * \note iNumberOfDivisions shouldnt be const */ void UpdateCollectionNumberOfDivisions( MultiIndexContainerTraceIDIterator& it, unsigned int& iNumberOfDivisions); /* * \brief Get the number of leaves of the lineage * \param[in] iTrackRootID id of the track root * \return depth of the lineage */ unsigned int GetCollectionNumberOfLeaves(const unsigned int& iTrackRootID); /* * \brief Update the collection number of leaves * \param[in] it iterator to go through the lineage * \param[in] iNumberOfLeaves number of leaves of the lineage * \note iNumberOfLeaves shouldnt be const */ void UpdateCollectionNumberOfLeaves(MultiIndexContainerTraceIDIterator& it, unsigned int& iNumberOfLeaves); /* * \brief Export a vtkMutableDirectedGraph from a given trackID root. * \param[in] iTrackID track root ID for the lineage export. * \return pointer to vtkMutableDirectedGraph. IMPORTANT: has to be deleted. */ vtkMutableDirectedGraph* ExportLineage(const unsigned int& iTrackID); /* * \brief Color code lineages from the table widget * \param[in] iColumnName selected column name * \param[in] iValues pair track root id/value */ void SetCollectionColorCode(const std::string& iColumnName, const std::map< unsigned int, std::string >& iValues); /* * \brief Randomly color code lineages from the table widget * \param[in] iColumnName selected column name * \param[in] iValues pair track root id/value */ void SetDivisionRandomColor(const std::string & iColumnName, const std::map< unsigned int, std::string >& iValues); /* * \brief Update whole tree for table widget color coding * \param[in] it iterator to go through the lineage * \param[in] iColumnName selected column name * \param[in] iValue value of the current lineage * \param[in|out] iMin to adjust the lookup table after modifying polydata scalars * \param[in|out] iMax to adjust the lookup table after modifying polydata scalars * \note iMin and iMax should not be constant */ void UpdateDivisionScalarData(MultiIndexContainerTraceIDIterator& it, const std::string& iColumnName, const double& iValue, double& iMin, double& iMax); /* * \brief Set the scalar range for all the divisions * \param[in] iMin min scalar * \param[in] iMax max value */ void SetScalarRangeForAllDivisions(const double& iMin, const double& iMax); /* * \brief Set the LUT for all the divisions * \param[in] iLut the lookup table */ void SetLookupTableForAllDivisionsColorCoding(const vtkLookupTable *iLut); /* * \brief Render all the divisions of all the lineages with the original * lineage color */ void RenderAllDivisionsWithOriginalColors(); /* * \brief Go through the lineage and update the graph structure and * informations. * \param[in] it iterator to go through the lineage * \param[in] iGraph graph to be modified * \param[in] iPedrigree vertex ID - is unique * \param[in] mother vertex ID of the mother - to create edges * \param[in] iDepth depth of the node in the lineage - to compute stats * \param[in] iDepthArray array to be modified to add information to the graph * \param[in] iIDArray array to be modified to add information to the graph */ void UpdateLineage(MultiIndexContainerTraceIDIterator& it, vtkMutableDirectedGraph* iGraph, unsigned int iPedrigree, vtkIdType mother, unsigned int iDepth, vtkDoubleArray* iDepthArray, vtkDoubleArray* iIDArray); signals: /** \brief When one track has been picked (highlighted) from the visualization */ void TracePicked(unsigned int, Qt::CheckState); /** \brief When one track's visibility has been changed from the visualization */ void TraceVisibilityChanged(unsigned int, Qt::CheckState); /** \brief When we want to import meshes into a track */ void NeedMeshesInfoForImportedTrack(unsigned int); /* * \brief Send signal to tell to the lineage container which lineage to highlight */ void UpdateLineageHighlightingFromTrackRootID(unsigned int); public slots: /** \brief Change elements highlighting property given a list of TraceIDs and the new status. \param[in] iList list of TraceIDs \param[in] iCheck */ virtual void UpdateElementHighlightingWithGivenTraceIDs( const QStringList& iList, const Qt::CheckState& iCheck); /** \brief Change elements visibility property given a list of TraceIDs and the new status. \param[in] iList list of TraceIDs \param[in] iCheck */ virtual void UpdateElementVisibilityWithGivenTraceIDs( const QStringList& iList, const Qt::CheckState& iCheck); /** \brief Color code the track by an array \param[in] iColorCode name of the active array*/ void ChangeColorCode(const QString& iColorCode); /** \brief Color code the lineage by an array \param[in] iColorCode name of the active array */ void ChangeDivisionsColorCode(const QString& iColorCode); /* * \brief Update the representation of a track (adding glyphs, tubes or updating * the line width). If iRadius or iRadius2 are null then the line width gets updated. * \param[in] iRadius radius of the glyph * \param[in] iRadius2 radius of the tube * \param[in] iWidth line width */ void UpdateTracksRepresentation(const double& iRadius, const double& iRadius2, const double& iWidth); /* * \brief Highlight a collection given the track root ID * param[in] iRootTrackID trackID root * param[in] iHighlighted true (highlight) or false (real color) */ void HighlightCollection(const unsigned int& iRootTrackID, const bool& iHighlighted); /* * \brief Update the collection highlight * \param[in] it iterator to go through the lineage * \param[in] iHighlighted highlight (true) or real color (false) */ void UpdateCollectionHighlighted(MultiIndexContainerTraceIDIterator& it, const bool& iHighlighted); /* * \brief Change the highlight of the division belonging to the given structure. * Structure is modified through unary function. * \param[in] it iterator to the structure to be modified * \param[in] iHighlight highlight (true) or real color (false) */ int ModifyDivisionHighlight(MultiIndexContainerTraceIDIterator& it, const bool& iHighlight); /* * \brief Show/hide a collection given the track root ID * param[in] iRootTrackID trackID root * param[in] iVisibility true (show) or false (hide) */ void ShowCollection(const unsigned int&, const bool&); /* * \brief Update the collection visibility * \param[in] it iterator to go through the lineage * \param[in] iVisibility show (true) or hide (false) */ void UpdateCollectionVisibility(MultiIndexContainerTraceIDIterator& it, const bool& iVisibility); /* * \brief Delete a collection given the track root ID * param[in] iRootTrackID trackID root */ void DeleteCollection(unsigned int); /* * \brief Update the collection delete * \param[in] it iterator to go through the lineage */ void UpdateCollectionDelete( MultiIndexContainerTraceIDIterator& it); /* * \brief Change the visibility of the division belonging to the given structure. * Structure is modified through unary function. * \param[in] it iterator to the structure to be modified * \param[in] iVisibility show (true) or hide (false) */ int ModifyDivisionVisibility(MultiIndexContainerTraceIDIterator& it, const bool& iVisibility ); /* * \brief Delete the division belonging to the given track * \param[in] iMotherID ID of the track which owns the division */ void DeleteADivision(const unsigned int& iMotherID); void AddVolume(const unsigned int& iTrackID, const double& iVolume); protected: /* \todo Nicolas why protected?? */ /** \brief Recompute a polydata from a list of point (coordinates) for the current element. If the current element is a new track, then the polydata, actors are allocated and added in consequence. \param[in] iPoints list of points to generate the new polydata */ void RecomputeMap( TrackStructure* iStructure, std::list< double* >& iPoints); /** \brief Changes the scalars to be displayed and return the new range * \param[in] iArrayName Array to be displayed * \return Pointer to double[2] where [0] is the min scalar value and [1] is * the max scalar value. Pointer has to be deleted (delete[] pointer) */ double* setTrackNodeScalars(const QString& iArrayName); /** \brief Changes the divisions scalars to be displayed and return the new range * \param[in] iArrayName Array to be displayed * \return Pointer to double[2] where [0] is the min scalar value and [1] is * the max scalar value. Pointer has to be deleted (delete[] pointer) */ double* setDivisionNodeScalars(const QString& iArrayName); void ComputeSpeed(); private: int m_TimeInterval; QString m_ActiveTrackScalars; QString m_ActiveDivisionScalars; Q_DISABLE_COPY(TrackContainer); }; #endif // TrackCONTAINER_H GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/TraceContainerBase.txx0000644000175000017500000006727611667757442027571 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __TraceContainerBase_txx #define __TraceContainerBase_txx #include "TraceContainerBase.h" #include "vtkPointData.h" #include "vtkDoubleArray.h" #include "vtkLookupTableManager.h" template< class TContainer > TraceContainerBase< TContainer >::TraceContainerBase(QObject *iParent, QGoImageView3D *iView) : QObject(iParent), m_ImageView(iView), m_CurrentElement(), m_HighlightedProperty(NULL), m_IntersectionLineWidth(1.) { } template< class TContainer > TraceContainerBase< TContainer >:: ~TraceContainerBase() { } template< class TContainer > void TraceContainerBase< TContainer >::Print() { this->Print( m_Container.begin(), m_Container.end() ); } //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >:: SetHighlightedProperty(vtkProperty *iProperty) { using boost::multi_index:: get; this->m_HighlightedProperty = iProperty; MultiIndexContainerHighlightedIterator it0, it1; boost::tuples::tie(it0, it1) = m_Container.get< Highlighted >().equal_range(true); while ( it0 != it1 ) { if ( it0->Highlighted ) { it0->SetActorProperties(this->m_HighlightedProperty); } ++it0; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > vtkProperty * TraceContainerBase< TContainer >:: GetHighlightedProperty() { return m_HighlightedProperty; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > std::vector< vtkActor * > TraceContainerBase< TContainer >:: GetActorGivenTraceID(unsigned int iTraceID) { using boost::multi_index:: get; MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iTraceID); std::vector< vtkActor * > listActors; if ( it != m_Container.get< TraceID >().end() ) { listActors.push_back( ( *it ).ActorXY ); listActors.push_back( ( *it ).ActorYZ ); listActors.push_back( ( *it ).ActorXZ ); listActors.push_back( ( *it ).ActorXYZ ); //std::cout << "Actor found" << std::endl; } else { std::cout << "Actor not found" << std::endl; } return listActors; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > bool TraceContainerBase< TContainer >:: UpdateCurrentElementFromExistingOne(unsigned int iTraceID, bool iErase) { using boost::multi_index:: get; MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iTraceID); if ( it != m_Container.get< TraceID >().end() ) { // update current element this->m_CurrentElement = *it; // clean the container but don't erase the pointers since we still have the // adresses in the m_CurrentElement if(iErase) { m_Container.get< TraceID >().erase(it); } return true; } else { return false; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >:: Insert(const typename TraceContainerBase::MultiIndexContainerElementType & iE) { this->m_Container.insert(iE); } template< class TContainer > void TraceContainerBase< TContainer >:: InsertCurrentElement() { this->m_Container.insert(this->m_CurrentElement); } template< class TContainer > void TraceContainerBase< TContainer >:: ResetCurrentElement() { this->m_CurrentElement = MultiIndexContainerElementType(); } //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >::UpdateCurrentElementFromDB(unsigned int iTraceID, double irgba[4], bool IsVisible) { this->m_CurrentElement.TraceID = iTraceID; this->m_CurrentElement.rgba[0] = irgba[0]; this->m_CurrentElement.rgba[1] = irgba[1]; this->m_CurrentElement.rgba[2] = irgba[2]; this->m_CurrentElement.rgba[3] = irgba[3]; this->m_CurrentElement.Visible = IsVisible; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >::UpdateCurrentElementCollection( unsigned int iCollectionID) { this->m_CurrentElement.CollectionID = iCollectionID; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > vtkPolyData * TraceContainerBase< TContainer >::GetCurrentElementNodes() { return this->m_CurrentElement.Nodes; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > double * TraceContainerBase< TContainer >::GetCurrentElementColor() { return this->m_CurrentElement.rgba; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > bool TraceContainerBase< TContainer >:: RemoveElementFromVisualizationWithGivenTraceID(const unsigned int & iId) { using boost::multi_index:: get; MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iId); if ( it != m_Container.get< TraceID >().end() ) { if ( m_ImageView ) { if ( it->ActorXY ) { this->m_ImageView->RemoveActor(0, it->ActorXY); } if ( it->ActorXZ ) { this->m_ImageView->RemoveActor(1, it->ActorXZ); } if ( it->ActorYZ ) { this->m_ImageView->RemoveActor(2, it->ActorYZ); } if ( it->ActorXYZ ) { this->m_ImageView->RemoveActor(3, it->ActorXYZ); } } this->m_CurrentElement = *it; m_Container.get< TraceID >().erase(it); if ( m_ImageView ) { m_ImageView->UpdateRenderWindows(); } return true; } return false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > bool TraceContainerBase< TContainer >:: UpdateElementHighlightingWithGivenTraceID(const unsigned int & iId) { using boost::multi_index:: get; MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iId); if ( it != m_Container.get< TraceID >().end() ) { vtkProperty *temp_property = vtkProperty::New(); if ( it->Highlighted ) { temp_property->SetColor(it->rgba[0], it->rgba[1], it->rgba[2]); temp_property->SetOpacity(it->rgba[3]); temp_property->SetLineWidth(this->m_IntersectionLineWidth); } else { temp_property->DeepCopy(this->m_HighlightedProperty); } it->SetActorProperties(temp_property); temp_property->Delete(); bool highlighted = !it->Highlighted; m_Container.get< TraceID >(). modify( it , change_highlighted(highlighted) ); assert ( m_ImageView ); m_ImageView->UpdateRenderWindows(); return true; } return false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >:: UpdateElementHighlightingWithGivenTraceIDsBase(const QStringList & iList, const Qt::CheckState & iCheck) { using boost::multi_index:: get; if ( !iList.empty() ) { MultiIndexContainerTraceIDIterator it; QStringList::const_iterator constIterator = iList.begin(); while ( constIterator != iList.end() ) { it = m_Container.get< TraceID >().find( ( *constIterator ).toUInt() ); if ( it != m_Container.get< TraceID >().end() ) { vtkProperty *temp_property = vtkProperty::New(); if ( !iCheck ) { temp_property->SetColor(it->rgba[0], it->rgba[1], it->rgba[2]); temp_property->SetOpacity(it->rgba[3]); temp_property->SetLineWidth(this->m_IntersectionLineWidth); } else { temp_property->DeepCopy(this->m_HighlightedProperty); } it->SetActorProperties(temp_property); temp_property->Delete(); bool highlight = iCheck; m_Container.get< TraceID >(). modify( it , change_highlighted(highlight) ); } ++constIterator; } assert ( m_ImageView ); m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >:: UpdateElementVisibilityWithGivenTraceIDsBase(const QStringList & iList, const Qt::CheckState & iCheck) { using boost::multi_index:: get; if ( !iList.empty() ) { MultiIndexContainerTraceIDIterator it; typedef void ( QGoImageView3D::*ImageViewMember )(const int &, vtkActor *); ImageViewMember f; QStringList::const_iterator constIterator = iList.begin(); bool visible; while ( constIterator != iList.end() ) { it = m_Container.get< TraceID >().find( ( *constIterator ).toUInt() ); if ( it != m_Container.get< TraceID >().end() ) { if ( iCheck == Qt::Unchecked ) { f = &QGoImageView3D::RemoveActor; visible = false; } else { f = &QGoImageView3D::AddActor; visible = true; } if ( m_ImageView ) { if ( it->ActorXY ) { ( m_ImageView->*f )(0, it->ActorXY); } if ( it->ActorXZ ) { ( m_ImageView->*f )(1, it->ActorXZ); } if ( it->ActorYZ ) { ( m_ImageView->*f )(2, it->ActorYZ); } if ( it->ActorXYZ ) { ( m_ImageView->*f )(3, it->ActorXYZ); } } it->SetActorVisibility(visible); m_Container.get< TraceID >(). modify( it , change_visible(visible) ); } ++constIterator; } if ( m_ImageView ) { m_ImageView->UpdateRenderWindows(); } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > std::list< unsigned int > TraceContainerBase< TContainer >:: UpdateAllHighlightedElementsWithGivenColor(QColor iColor) { using boost::multi_index:: get; MultiIndexContainerHighlightedIterator it0, it1; boost::tuples::tie(it0, it1) = m_Container.get< Highlighted >().equal_range(true); std::list< unsigned int > oList; while ( it0 != it1 ) { m_Container.get< Highlighted >().modify(it0, change_color(iColor)); oList.push_back(it0->TraceID); ++it0; } return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > std::list< unsigned int > TraceContainerBase< TContainer >::GetHighlightedElementsTraceID() { MultiIndexContainerHighlightedIterator it0, it1; using boost::multi_index:: get; boost::tuples::tie(it0, it1) = m_Container.get< Highlighted >().equal_range(true); std::list< unsigned int > oList; while ( it0 != it1 ) { oList.push_back(it0->TraceID); ++it0; } return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > std::list< unsigned int > TraceContainerBase< TContainer >::GetHighlightedElementsCollectionID() { MultiIndexContainerHighlightedIterator it0, it1; using boost::multi_index:: get; boost::tuples::tie(it0, it1) = m_Container.get< Highlighted >().equal_range(true); std::list< unsigned int > oList; while ( it0 != it1 ) { oList.push_back(it0->CollectionID); ++it0; } return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > std::list< vtkPolyData* > TraceContainerBase< TContainer >:: GetHighlightedElements(){ std::list< vtkPolyData*> oList; MultiIndexContainerHighlightedIterator it0, it1; using boost::multi_index:: get; boost::tuples::tie(it0, it1) = m_Container.get< Highlighted >().equal_range(true); while ( it0 != it1) { oList.push_back(it0->Nodes); ++it0; } return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > bool TraceContainerBase< TContainer >:: UpdateElementVisibilityWithGivenTraceID(const unsigned int & iId) { using boost::multi_index:: get; MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iId); typedef void ( QGoImageView3D::*ImageViewMember )(const int &, vtkActor *); ImageViewMember f; /* * \todo Nicolas-should be an assert */ if ( it != m_Container.get< TraceID >().end() ) { if ( it->Visible ) { f = &QGoImageView3D::RemoveActor; } else { f = &QGoImageView3D::AddActor; } if ( m_ImageView ) { if ( it->ActorXY ) { ( m_ImageView->*f )(0, it->ActorXY); } if ( it->ActorXZ ) { ( m_ImageView->*f )(1, it->ActorXZ); } if ( it->ActorYZ ) { ( m_ImageView->*f )(2, it->ActorYZ); } if ( it->ActorXYZ ) { ( m_ImageView->*f )(3, it->ActorXYZ); } } it->SetActorVisibility(!it->Visible); bool visible = !it->Visible; m_Container.get< TraceID >(). modify( it , change_visible(visible) ); assert ( m_ImageView ); m_ImageView->UpdateRenderWindows(); return true; } return false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >::SetColorCode(const std::string & iColumnName, const std::map< unsigned int, std::string > & iValues) { typedef typename std::map< unsigned int, std::string > MapType; typedef typename MapType::const_iterator MapConstIterator; std::map< std::string, double > stringmap; using boost::multi_index:: get; if ( iColumnName.empty() || iValues.empty() ) { this->RenderAllElementsWithOriginalColors(); return; } MapConstIterator it = iValues.begin(); double temp = 0.; try { temp = boost::lexical_cast< double >(it->second); } catch(boost::bad_lexical_cast &) { if ( stringmap.empty() ) { stringmap[it->second] = 0.; } else { std::map< std::string, double >::iterator m_it = stringmap.find(it->second); if ( m_it != stringmap.end() ) { temp = m_it->second; } else { std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin(); temp = r_it->second; temp += 1.0; } } } double min_value = temp; double max_value = temp; while ( it != iValues.end() ) { MultiIndexContainerTraceIDIterator trace_it = this->m_Container.get< TraceID >().find(it->first); if ( trace_it != this->m_Container.get< TraceID >().end() ) { if ( trace_it->Nodes ) //make sure the trace has points !!! { // Here let's make sure you are not passing crazy values! try { temp = boost::lexical_cast< double >(it->second); } catch(boost::bad_lexical_cast &) { // stringmap is not empty and has at least one element std::map< std::string, double >::iterator m_it = stringmap.find(it->second); if ( m_it != stringmap.end() ) { temp = m_it->second; } else { std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin(); temp = r_it->second; temp += 1.0; } } if ( temp > max_value ) { max_value = temp; } if ( temp < min_value ) { min_value = temp; } trace_it->SetScalarData(iColumnName, temp); } } //end make sure the trace has points !!! ++it; } SetScalarRangeForAllElements(min_value, max_value); if ( m_ImageView ) { this->m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >::SetRandomColor(const std::string & iColumnName, const std::map< unsigned int, unsigned int > & iIds) { typedef typename std::map< unsigned int, unsigned int > MapType; typedef typename MapType::const_iterator MapConstIterator; using boost::multi_index:: get; if ( iColumnName.empty() || iIds.empty() ) { RenderAllElementsWithOriginalColors(); return; } MapConstIterator it = iIds.begin(); double temp = static_cast< double >(it->second % 30); double min_value = temp; double max_value = temp; while ( it != iIds.end() ) { MultiIndexContainerTraceIDIterator trace_it = this->m_Container.get< TraceID >().find(it->first); if ( trace_it != this->m_Container.get< TraceID >().end() ) { if ( trace_it->Nodes ) //make sure the trace has points !!! { // Here let's make sure you are not passing crazy values! temp = boost::numeric_cast< double >(it->second % 30); if ( temp > max_value ) { max_value = temp; } if ( temp < min_value ) { min_value = temp; } trace_it->SetScalarData(iColumnName, temp); } } //end make sure the trace has points !!! ++it; } this->SetScalarRangeForAllElements(min_value, max_value); this->SetLookupTableForColorCoding( vtkLookupTableManager::GetRandomLookupTable() ); if ( m_ImageView ) { this->m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >::RenderAllElementsWithOriginalColors() { typename MultiIndexContainerType::iterator t_it = m_Container.begin(); while ( t_it != m_Container.end() ) { t_it->RenderWithOriginalColors(); ++t_it; } if ( m_ImageView ) { this->m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >::SetScalarRangeForAllElements(const double & iMin, const double & iMax) { // Let's set the scalar range (in order to get nice colors) typename MultiIndexContainerType::iterator t_it = m_Container.begin(); while ( t_it != m_Container.end() ) { t_it->SetScalarRange(iMin, iMax); ++t_it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >::SetLookupTableForColorCoding(vtkLookupTable *iLut) { if ( iLut ) { typename MultiIndexContainerType::iterator it = m_Container.begin(); while ( it != m_Container.end() ) { it->SetLookupTable(iLut); ++it; } if ( m_ImageView ) { this->m_ImageView->UpdateRenderWindows(); } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >::SetRandomColor(const std::string & iColumnName, const std::map< unsigned int, std::string > & iValues) { typedef std::map< unsigned int, std::string > MapType; typedef MapType::const_iterator MapConstIterator; std::map< std::string, double > stringmap; if ( iColumnName.empty() || iValues.empty() ) { this->RenderAllElementsWithOriginalColors(); return; } MapConstIterator it = iValues.begin(); double temp = 0.; try { temp = boost::lexical_cast< double >(it->second); } catch(boost::bad_lexical_cast &) { if ( stringmap.empty() ) { stringmap[it->second] = 0.; } else { std::map< std::string, double >::iterator m_it = stringmap.find(it->second); if ( m_it != stringmap.end() ) { temp = m_it->second; } else { std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin(); temp = r_it->second; temp += 1.0; } } } unsigned int val = static_cast< unsigned int >(temp); unsigned int modulo = val % 30; temp = static_cast< double >(modulo); double min_value = temp; double max_value = temp; using boost::multi_index:: get; while ( it != iValues.end() ) { MultiIndexContainerTraceIDIterator trace_it = this->m_Container.get< TraceID >().find(it->first); if ( trace_it != this->m_Container.get< TraceID >().end() ) { if ( trace_it->Nodes ) //make sure the trace has points !!! { // Here let's make sure you are not passing crazy values! try { temp = boost::lexical_cast< double >(it->second); } catch(boost::bad_lexical_cast &) { // stringmap is not empty and has at least one element std::map< std::string, double >::iterator m_it = stringmap.find(it->second); if ( m_it != stringmap.end() ) { temp = m_it->second; } else { std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin(); temp = r_it->second; temp += 1.0; } } val = static_cast< unsigned int >(temp); modulo = val % 30; temp = static_cast< double >(modulo); if ( temp > max_value ) { max_value = temp; } if ( temp < min_value ) { min_value = temp; } trace_it->SetScalarData(iColumnName, temp); } } //end make sure the trace has points !!! ++it; } SetScalarRangeForAllElements(min_value, max_value); if ( m_ImageView ) { this->m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >::UpdateCurrentElementFromVisuBase(std::vector< vtkActor * >& iActors, vtkPolyData *iNodes, const bool & iHighlighted, const bool & iVisible) { if ( iActors.size() != 4 ) { std::cerr << "iActors.size() != 4" << std::endl; return; } else { this->m_CurrentElement.ActorXY = iActors[0]; this->m_CurrentElement.ActorXZ = iActors[1]; this->m_CurrentElement.ActorYZ = iActors[2]; this->m_CurrentElement.ActorXYZ = iActors[3]; } this->m_CurrentElement.Nodes = iNodes; this->m_CurrentElement.Highlighted = iHighlighted; this->m_CurrentElement.Visible = iVisible; if ( iHighlighted ) { this->m_CurrentElement.SetActorProperties(this->m_HighlightedProperty); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > void TraceContainerBase< TContainer >::SetIntersectionLineWidth(const float & iWidth) { m_IntersectionLineWidth = iWidth; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- template< class TContainer > unsigned int TraceContainerBase< TContainer >::GetCollectionIDOfGivenTraceID(unsigned int iTraceID) { using boost::multi_index:: get; MultiIndexContainerTraceIDIterator it0 = m_Container.get< TraceID >().find(iTraceID); if ( it0 != m_Container.get< TraceID >().end() ) { return it0->CollectionID; } else { std::cout << "booo" << std::endl; return std::numeric_limits< unsigned int >::max(); } } //------------------------------------------------------------------------- #endif GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/ContourContainer.h0000644000175000017500000000525111667757442026756 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __ContourContainer_h #define __ContourContainer_h #include "ContourMeshContainer.h" #include "QGoGUILibConfigure.h" /** * \class ContourContainer * \brief Wraps a boost::multi_index_container of ContourMeshStructure. * This class is specialized for the means of 2D Contour. * */ class QGOGUILIB_EXPORT ContourContainer : public ContourMeshContainer { Q_OBJECT public: /** \brief Constructor */ explicit ContourContainer( QObject* iParent, QGoImageView3D *iView); /** \brief Destructor */ ~ContourContainer(); protected: /** \brief Add a contour in the visualization given the spline nodes and the * property for the given contour. It returns a vector of size 4, of each * element represents one view in the Quad-View. */ std::vector< vtkActor* > AddTrace( vtkPolyData* iNode, vtkProperty* iProperty ); private: Q_DISABLE_COPY(ContourContainer); }; #endif // CONTOURCONTAINER_H GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/ContourMeshContainer.cxx0000644000175000017500000003152011667757442030144 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "ContourMeshContainer.h" #include "StructureHelper.h" #include "vtkActor.h" //------------------------------------------------------------------------- ContourMeshContainer::ContourMeshContainer(QObject *iParent, QGoImageView3D *iView) : Superclass(iParent, iView), m_TCoord( std::numeric_limits< unsigned int >::max() ) { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- ContourMeshContainer:: ~ContourMeshContainer() { MultiIndexContainerType::iterator it = m_Container.begin(); while ( it != m_Container.end() ) { if ( it->Nodes ) { it->Nodes->Delete(); } if ( it->ActorXY ) { it->ActorXY->Delete(); } if ( it->ActorXZ ) { it->ActorXZ->Delete(); } if ( it->ActorYZ ) { it->ActorYZ->Delete(); } if ( it->ActorXYZ ) { it->ActorXYZ->Delete(); } ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ContourMeshContainer::SetTimePoint(const unsigned int & iT) { this->m_TCoord = iT; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ContourMeshContainer::UpdateCurrentElementFromVisu(std::vector< vtkActor * >& iActors, vtkPolyData *iNodes, const unsigned int & iT, const bool & iHighlighted, const bool & iVisible) { this->m_CurrentElement.TCoord = iT; this->UpdateCurrentElementFromVisuBase(iActors, iNodes, iHighlighted, iVisible); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ContourMeshContainer::RemoveActorsWithGivenTimePoint(const unsigned int & iT) { MultiIndexContainerTCoordIterator it0, it1; boost::tuples::tie(it0, it1) = m_Container.get< TCoord >().equal_range(iT); ChangeActorsVisibility< TCoord >(it0, it1, false); if ( m_ImageView ) { m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ContourMeshContainer::ShowActorsWithGivenTimePoint(const unsigned int & iT) { if ( iT != m_TCoord ) { MultiIndexContainerTCoordIterator it, it0, it1; boost::tuples::tie(it0, it1) = m_Container.get< TCoord >().equal_range(iT); ChangeActorsVisibility< TCoord >(m_Container.get< TCoord >().begin(), it0, false); ChangeActorsVisibility< TCoord >(it0, it1, true); ChangeActorsVisibility< TCoord >(it1, m_Container.get< TCoord >().end(), false); m_TCoord = iT; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ContourMeshContainer::AddActorsWithGivenTimePoint(const unsigned int & iT) { MultiIndexContainerTCoordIterator it0, it1; boost::tuples::tie(it0, it1) = m_Container.get< TCoord >().equal_range(iT); ChangeActorsVisibility< TCoord >(it0, it1, true); if ( m_ImageView ) { m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ContourMeshContainer::UpdateElementHighlightingWithGivenTraceIDs(const QStringList & iList, const Qt::CheckState & iCheck) { Superclass::UpdateElementHighlightingWithGivenTraceIDsBase(iList, iCheck); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ContourMeshContainer::UpdateElementVisibilityWithGivenTraceIDs(const QStringList & iList, const Qt::CheckState & iCheck) { Superclass::UpdateElementVisibilityWithGivenTraceIDsBase(iList, iCheck); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool ContourMeshContainer::DeleteElement(const unsigned int & iId) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iId); return DeleteElement(it); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool ContourMeshContainer::DeleteElement(MultiIndexContainerTraceIDIterator iIter) { if ( iIter != m_Container.get< TraceID >().end() ) { if ( iIter->ActorXY ) { if ( m_ImageView ) { this->m_ImageView->RemoveActor(0, iIter->ActorXY); } iIter->ActorXY->Delete(); } if ( iIter->ActorXZ ) { if ( m_ImageView ) { this->m_ImageView->RemoveActor(1, iIter->ActorXZ); } iIter->ActorXZ->Delete(); } if ( iIter->ActorYZ ) { if ( m_ImageView ) { this->m_ImageView->RemoveActor(2, iIter->ActorYZ); } iIter->ActorYZ->Delete(); } if ( iIter->ActorXYZ ) { if ( m_ImageView ) { this->m_ImageView->RemoveActor(3, iIter->ActorXYZ); } iIter->ActorXYZ->Delete(); } if ( iIter->Nodes ) { iIter->Nodes->Delete(); } m_Container.get< TraceID >().erase(iIter); return true; } return false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > ContourMeshContainer::DeleteAllHighlightedElements() { MultiIndexContainerHighlightedIterator it0, it1, it_t; boost::tuples::tie(it0, it1) = m_Container.get< Highlighted >().equal_range(true); std::list< unsigned int > oList; while ( it0 != it1 ) { oList.push_back(it0->TraceID); if ( it0->ActorXY ) { if ( m_ImageView ) { this->m_ImageView->RemoveActor(0, it0->ActorXY); } it0->ActorXY->Delete(); } if ( it0->ActorXZ ) { if ( m_ImageView ) { this->m_ImageView->RemoveActor(1, it0->ActorXZ); } it0->ActorXZ->Delete(); } if ( it0->ActorYZ ) { if ( m_ImageView ) { this->m_ImageView->RemoveActor(2, it0->ActorYZ); } it0->ActorYZ->Delete(); } if ( it0->ActorXYZ ) { if ( m_ImageView ) { this->m_ImageView->RemoveActor(3, it0->ActorXYZ); } it0->ActorXYZ->Delete(); } if ( it0->Nodes ) { it0->Nodes->Delete(); } it_t = it0; ++it0; m_Container.get< Highlighted >().erase(it_t); } if ( m_ImageView ) { m_ImageView->UpdateRenderWindows(); } return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > ContourMeshContainer::GetElementsTraceIDForGivenTimePoint(unsigned int iTimePoint) { MultiIndexContainerTCoordIterator it0, it1; boost::tuples::tie(it0, it1) = m_Container.get< TCoord >().equal_range(iTimePoint); std::list< unsigned int > oList; while ( it0 != it1 ) { oList.push_back(it0->TraceID); ++it0; } return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::map< unsigned int, double * > ContourMeshContainer::GetMeshesPoints(std::list< unsigned int > iMeshID) { std::map< unsigned int, double * > meshPosition; std::list< unsigned int >::iterator listIt = iMeshID.begin(); MultiIndexContainerTraceIDIterator containerIt; while ( listIt != iMeshID.end() ) { containerIt = m_Container.get< TraceID >().find(*listIt); //if element found if ( containerIt != m_Container.get< TraceID >().end() ) { unsigned int time = containerIt->TCoord; double * point = new double[3]; double bounds[6]; containerIt->Nodes->GetBounds(bounds); for ( int i = 0; i < 3; ++i ) { point[i] = ( bounds[2 * i] + bounds[2 * i + 1] ) / 2; } meshPosition.insert( std::pair< unsigned int, double * >(time, point) ); } ++listIt; } return meshPosition; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ContourMeshContainer:: Clear() { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().begin(); while ( it != m_Container.get< TraceID >().end() ) { DeleteElement(it); ++it; } assert ( m_ImageView ); m_ImageView->UpdateRenderWindows(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void ContourMeshContainer:: Clear( const std::list& iTraceIDs) { std::list::const_iterator it = iTraceIDs.begin(); while(it!= iTraceIDs.end()) { DeleteElement(*it); ++it; } assert ( m_ImageView ); m_ImageView->UpdateRenderWindows(); } //------------------------------------------------------------------------- // move up //------------------------------------------------------------------------- void ContourMeshContainer:: AssignToGivenCollection(unsigned int iCollection, std::list< unsigned int > iToBeAssigned) { std::list< unsigned int >::iterator listIt = iToBeAssigned.begin(); MultiIndexContainerTraceIDIterator containerIt; while ( listIt != iToBeAssigned.end() ) { containerIt = m_Container.get< TraceID >().find(*listIt); //if element found if ( containerIt != m_Container.get< TraceID >().end() ) { m_Container.get< TraceID >().modify( containerIt, change_collectionID(iCollection)); } ++listIt; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > ContourMeshContainer::GetHighlightedElementsTCoord() { MultiIndexContainerHighlightedIterator it0, it1; using boost::multi_index:: get; boost::tuples::tie(it0, it1) = m_Container.get< Highlighted >().equal_range(true); std::list< unsigned int > oList; while ( it0 != it1 ) { oList.push_back(it0->TCoord); ++it0; } return oList; } //-------------------------------------------------------------------------GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/ContourMeshContainer.h0000644000175000017500000003176511667757442027604 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __ContourMeshContainer_h #define __ContourMeshContainer_h #include #include "ContourMeshStructure.h" #include "StructureHelper.h" #include "TraceContainerBase.h" #include "boost/multi_index_container.hpp" #include "boost/multi_index/member.hpp" #include "boost/multi_index/hashed_index.hpp" #include "boost/multi_index/ordered_index.hpp" #include "boost/numeric/conversion/cast.hpp" #include "boost/lexical_cast.hpp" #include "vtkProperty.h" #include "vtkPolyData.h" #include "vtkActor.h" #include "vtkMapper.h" #include "QGoImageView3D.h" #include "vtkLookupTableManager.h" #include "QGoGUILibConfigure.h" /** \struct change_Collection_ID \brief Change the collection ID of a trace \sa TraceStructure */ //----------------------------------------------------------------------------- struct change_collectionID { change_collectionID(const unsigned int& iCollectionID):collectionID(iCollectionID){} void operator()(ContourMeshStructure& iStructure) { iStructure.ModifyCollectionID(collectionID); } private: unsigned int collectionID; }; //----------------------------------------------------------------------------- namespace boost { typedef multi_index::multi_index_container< ContourMeshStructure, boost::multi_index::indexed_by< boost::multi_index::ordered_non_unique< boost::multi_index::tag< TCoord >, BOOST_MULTI_INDEX_MEMBER(ContourMeshStructure, unsigned int, TCoord) >, boost::multi_index::ordered_unique< boost::multi_index::tag< TraceID >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, unsigned int, TraceID) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< CollectionID >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, unsigned int, CollectionID) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< Highlighted >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, bool, Highlighted) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< Visible >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, bool, Visible) > > > MultiIndexContourMeshContainer; } /** \class ContourMeshContainer \brief Wraps a boost::multi_index_container of ContourMeshStructure. This class intends to synchronize Contour and Mesh representation in the Visualization and in the TableWidget \sa ContourMeshStructure QGoTableWidget QGoImageView3D */ class QGOGUILIB_EXPORT ContourMeshContainer: public TraceContainerBase< boost::MultiIndexContourMeshContainer > { Q_OBJECT public: typedef TraceContainerBase< boost::MultiIndexContourMeshContainer > Superclass; typedef Superclass::MultiIndexContainerType MultiIndexContainerType; typedef MultiIndexContainerType::index< TCoord >::type::iterator MultiIndexContainerTCoordIterator; //------------------------------------------------------------------------ /** \brief Constructor. */ explicit ContourMeshContainer(QObject *iParent, QGoImageView3D *iView); /** \brief Destructor. */ virtual ~ContourMeshContainer(); /** \brief Set the Current Time Point*/ void SetTimePoint(const unsigned int & iT); /** \brief Display all elements for a given time point * \param[in] iT time point */ void ShowActorsWithGivenTimePoint(const unsigned int & iT); /** * \brief Change elements (in between iBegin and iEnd ) visibility * \param[in] iBegin first element * \param[in] iEnd last element * \param[in] iVisibility */ void ChangeActorsVisibility( MultiIndexContainerTCoordIterator iBegin, MultiIndexContainerTCoordIterator iEnd, const bool & iVisibility); /** \brief Update Current Element by providing all required informations from the visualization. \param[in] iActors \param[in] iNodes \param[in] iT \param[in] iHighlighted \param[in] iVisible \see ContourMeshStructure */ void UpdateCurrentElementFromVisu(std::vector< vtkActor * >& iActors, vtkPolyData *iNodes, const unsigned int & iT, const bool & iHighlighted, const bool & iVisible); /** \brief Remove all actors (elements) from the scene for a given time point \param[in] iT */ void RemoveActorsWithGivenTimePoint(const unsigned int & iT); /** \brief Add all actors (elements) from the scene for a given time point */ void AddActorsWithGivenTimePoint(const unsigned int & iT); /** \brief Returns the direction of a given contour vtkPolyData. This static method is supposed to be used when dealing with contours. \param[in] iContour \return 0 if z coordinates are constant \return 1 if y coordinates are constant \return 2 if x coordinates are constant \return -1 else */ static int ComputeDirectionFromContour(vtkPolyData *iContour) { double bounds[6]; iContour->GetBounds(bounds); return ComputeDirectionFromBounds< double >(bounds); } /** \brief Returns the direction of a given element given its bounding box. This static method is supposed to be used when dealing with contours. \return 0 if z coordinates are constant \return 1 if y coordinates are constant \return 2 if x coordinates are constant \return -1 else */ template< typename T > static int ComputeDirectionFromBounds(T *iBounds) { int oDir = -1; for ( int i = 0; i < 3; i++ ) { if ( iBounds[2 * i] == iBounds[2 * i + 1] ) { oDir = 2 - i; } } return oDir; } template< typename T > static int ComputeDirectionFromBounds(const std::vector< T > & iBounds) { int oDir = -1; if ( iBounds.size() == 6 ) { for ( int i = 0; i < 3; ++i ) { if ( iBounds[2 * i] == iBounds[2 * i + 1] ) { oDir = 2 - i; } } } return oDir; } /** \brief Update highlighting property of one element given one actor. \param[in] iActor Actor of the element to be modified \return true if the element exists \return false else */ void UpdateElementHighlighting(unsigned int TraceId) { Qt::CheckState state; Superclass::UpdateElementHighlightingWithTraceID(TraceId, state ); emit TracePicked(TraceId, state); } /** \brief Update highlighting property of one element given one actor. \param[in] iActor Actor of the element to be modified \param[in] iState Visibility to applied to the element \return true if the element exists \return false else */ void UpdateElementVisibility(unsigned int iTraceID, bool iState) { Superclass::UpdateElementVisibilityWithTraceID(iTraceID, iState); if(iState) { emit TraceVisibilityChanged(iTraceID, Qt::Checked ); return; } emit TraceVisibilityChanged(iTraceID, Qt::Unchecked ); } //------------------------------------------------------------------------- /** \brief Remove the element which TraceId = iId
  • from the visualization
  • from the container
  • from memory (release memory)
\param[in] iId TraceID of the element to be deleted \return true if the element was present in the container. */ bool DeleteElement(const unsigned int & iId); /** \overload DeleteElement(const unsigned int & iId) */ bool DeleteElement(MultiIndexContainerTraceIDIterator iIter); /** \brief Delete all highlighted elements \return the list of TraceIDs of such elements */ std::list< unsigned int > DeleteAllHighlightedElements(); /** \brief Delete all elements from the container */ void Clear(); /** \brief Delete given elements from the container */ void Clear( const std::list& iTraceIDs); /** \return the traceIDs with TCoord = iTimePoint \param[in] iTimePoint timepoint for which the traceIDs are needed */ std::list< unsigned int > GetElementsTraceIDForGivenTimePoint(unsigned int iTimePoint); /* * \brief Returns the meshes positions * \param[in] iMeshID IDs of the meshes of interest * \return map containing the coordinates of the meshes of interest */ std::map< unsigned int, double* > GetMeshesPoints( std::list< unsigned int> iMeshID ); /** \brief Change element visibility in the scene \tparam TIndex refers to any index from the multi index container indices \param[in] iBegin first element \param[in] iEnd last element \param[in] iVisibility */ template< class TIndex > void ChangeActorsVisibility( typename MultiIndexContainerType::template index< TIndex >::type::iterator iBegin, typename MultiIndexContainerType::template index< TIndex >::type::iterator iEnd, const bool & iVisibility) { typename MultiIndexContainerType::template index< TIndex >::type::iterator it = iBegin; typedef void ( QGoImageView3D::*ImageViewMember )(const int &, vtkActor *); ImageViewMember f; if ( iVisibility ) { f = &QGoImageView3D::AddActor; } else { f = &QGoImageView3D::RemoveActor; } while ( it != iEnd ) { if ( it->Visible != iVisibility ) { it->SetActorVisibility( iVisibility ); if( m_ImageView ) { if ( it->ActorXY ) { ( m_ImageView->*f )(0, it->ActorXY); } if ( it->ActorXZ ) { ( m_ImageView->*f )(1, it->ActorXZ); } if ( it->ActorYZ ) { ( m_ImageView->*f )(2, it->ActorYZ); } if ( it->ActorXYZ ) { ( m_ImageView->*f )(3, it->ActorXYZ); } } bool visible = iVisibility; m_Container.get< TIndex >(). modify( it , change_visible(visible) ); Qt::CheckState State; if ( iVisibility ) { State = Qt::Checked; } else { State = Qt::Unchecked; } emit TraceVisibilityChanged( it->TraceID, State ); } ++it; } } void AssignToGivenCollection(unsigned int iCollection, std::list< unsigned int > iToBeAssigned); std::list< unsigned int > GetHighlightedElementsTCoord(); public slots: /** \brief Change elements highlighting property given a list of TraceIDs and the new status. \param[in] iList list of TraceIDs \param[in] iCheck */ void UpdateElementHighlightingWithGivenTraceIDs( const QStringList& iList, const Qt::CheckState& iCheck ); /** \brief Change elements visibility property given a list of TraceIDs and the new status. \param[in] iList list of TraceIDs \param[in] iCheck */ void UpdateElementVisibilityWithGivenTraceIDs( const QStringList& iList, const Qt::CheckState& iCheck ); signals: /** \brief When one contour / mesh has been picked (highlighted) from the visualization */ void TracePicked(unsigned int, Qt::CheckState); /** \brief When one contour / mesh's visibility has been changed from the visualization */ void TraceVisibilityChanged(unsigned int, Qt::CheckState); protected: unsigned int m_TCoord; private: Q_DISABLE_COPY(ContourMeshContainer); }; #endif // CONTOURMESHCONTAINER_H GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/TrackContainer.cxx0000644000175000017500000016274711667757442026762 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "TrackContainer.h" #include "vtkActor.h" // reconstruct the polydata #include "vtkPointData.h" #include "vtkPolyLine.h" #include "vtkCellArray.h" // tubes and glyph #include "vtkGlyph3D.h" #include "vtkSphereSource.h" #include "vtkTubeFilter.h" #include "vtkAppendPolyData.h" // division polydata #include "vtkLine.h" // to convert coordinates #include "vtkViewImage2D.h" #include "vtkLookupTable.h" #include "vtkStringArray.h" #include #include //------------------------------------------------------------------------- TrackContainer:: TrackContainer(QObject *iParent, QGoImageView3D *iView): Superclass(iParent, iView) { m_TimeInterval = 0; m_ActiveTrackScalars.append("Original"); m_ActiveDivisionScalars.append("Original"); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- TrackContainer:: ~TrackContainer() { MultiIndexContainerType::iterator it = m_Container.begin(); while ( it != m_Container.end() ) { it->ReleaseData(); ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool TrackContainer:: DeleteElement(const unsigned int & iId) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iId); return DeleteElement(it); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool TrackContainer:: DeleteElement(MultiIndexContainerTraceIDIterator iIter) { assert ( iIter != m_Container.get< TraceID >().end() ); assert ( this->m_ImageView ); if ( iIter->ActorXY ) { this->m_ImageView->RemoveActor(0, iIter->ActorXY); } if ( iIter->ActorXZ ) { this->m_ImageView->RemoveActor(1, iIter->ActorXZ); } if ( iIter->ActorYZ ) { this->m_ImageView->RemoveActor(2, iIter->ActorYZ); } if ( iIter->ActorXYZ ) { this->m_ImageView->RemoveActor(3, iIter->ActorXYZ); } iIter->ReleaseData(); m_Container.get< TraceID >().erase(iIter); m_ImageView->UpdateRenderWindows(); return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< unsigned int > TrackContainer:: DeleteAllHighlightedElements() { assert ( this->m_ImageView ); MultiIndexContainerHighlightedIterator it0, it1, it_t; boost::tuples::tie(it0, it1) = m_Container.get< Highlighted >().equal_range(true); std::list< unsigned int > oList; while ( it0 != it1 ) { oList.push_back(it0->TraceID); if ( it0->ActorXY ) { this->m_ImageView->RemoveActor(0, it0->ActorXY); } if ( it0->ActorXZ ) { this->m_ImageView->RemoveActor(1, it0->ActorXZ); } if ( it0->ActorYZ ) { this->m_ImageView->RemoveActor(2, it0->ActorYZ); } if ( it0->ActorXYZ ) { this->m_ImageView->RemoveActor(3, it0->ActorXYZ); } it0->ReleaseData(); it_t = it0; ++it0; m_Container.get< Highlighted >().erase(it_t); } m_ImageView->UpdateRenderWindows(); return oList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool TrackContainer:: UpdateTrackStructurePolyData(const TrackStructure & iTrackStructure) { if ( iTrackStructure.PointsMap.empty() ) { qDebug() << "No points in the map, reset nodes"; iTrackStructure.ResetNodes(); return false; } // read map and fill points vtkSmartPointer< vtkPoints > newPoints = vtkSmartPointer< vtkPoints >::New(); vtkSmartPointer< vtkIntArray > newArray = vtkSmartPointer< vtkIntArray >::New(); newArray->SetNumberOfComponents(1); newArray->SetName("TemporalInformation"); // Create a line from points vtkSmartPointer< vtkPolyLine > polyLine = vtkSmartPointer< vtkPolyLine >::New(); polyLine->GetPointIds()->SetNumberOfIds( iTrackStructure.PointsMap.size() ); std::map< unsigned int, double * >::const_iterator it = iTrackStructure.PointsMap.begin(); vtkIdType i = 0; while ( it != iTrackStructure.PointsMap.end() ) { newArray->InsertNextValue(it->first); newPoints->InsertNextPoint(it->second); polyLine->GetPointIds()->SetId(i, i); ++i; ++it; } //Create a cell array to store the lines in and add the lines to it vtkSmartPointer< vtkCellArray > cells = vtkSmartPointer< vtkCellArray >::New(); cells->InsertNextCell(polyLine); //Create a polydata to store everything in vtkSmartPointer< vtkPolyData > polyData = vtkSmartPointer< vtkPolyData >::New(); //add the points to the dataset polyData->SetPoints(newPoints); //add the lines to the dataset polyData->SetLines(cells); //add the temporal information polyData->GetPointData()->AddArray(newArray); vtkSmartPointer< vtkDoubleArray > speedArray = vtkSmartPointer< vtkDoubleArray >::New(); speedArray->SetNumberOfComponents(1); speedArray->SetName("SpeedInformation"); polyData->GetPointData()->AddArray(speedArray); vtkSmartPointer trackIDArray = vtkSmartPointer::New(); trackIDArray->SetNumberOfComponents(1); trackIDArray->SetNumberOfValues(1); trackIDArray->SetName("TRACK"); trackIDArray->SetValue(0,iTrackStructure.TraceID); polyData->GetFieldData()->AddArray(trackIDArray); iTrackStructure.Nodes->DeepCopy(polyData); //update speed information iTrackStructure.ComputeAttributes(); iTrackStructure.Nodes->GetPointData()->SetActiveScalars(NULL); return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: ImportTrackInCurrentElement(std::map& iMeshes) { std::map< unsigned int, double * >::iterator beginMesh = iMeshes.begin(); std::map< unsigned int, double * >::iterator endMesh = iMeshes.end(); while ( beginMesh != endMesh ) { this->m_CurrentElement.InsertElement(beginMesh->first, beginMesh->second); ++beginMesh; } this->m_CurrentElement.Visible = true; this->m_CurrentElement.Nodes = vtkPolyData::New(); UpdateTrackStructurePolyData(this->m_CurrentElement); CreateTrackActors(this->m_CurrentElement); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: CreateTrackActors(TrackStructure& iStructure) { assert( this->m_ImageView ); //Create new actors (new address) vtkProperty *trace_property = vtkProperty::New(); double r = iStructure.rgba[0]; double g = iStructure.rgba[1]; double b = iStructure.rgba[2]; double a = iStructure.rgba[3]; trace_property->SetColor(r, g, b); trace_property->SetOpacity(a); // Add contour std::vector< vtkActor * > trackActors = m_ImageView->AddContour(iStructure.Nodes, trace_property); //has actor being created? assert(trackActors[0]); // add actors address to structure iStructure.ActorXY = trackActors[0]; iStructure.ActorXZ = trackActors[1]; iStructure.ActorYZ = trackActors[2]; iStructure.ActorXYZ = trackActors[3]; this->m_ImageView->AddActor(3, trackActors[3]); trace_property->Delete(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateTrackActors(TrackStructure& iStructure ) { if(iStructure.Nodes->GetNumberOfPoints() < 2 ) { // clean actor this->m_ImageView->RemoveActor(0, iStructure.TreeNode.ActorXY); this->m_ImageView->RemoveActor(1, iStructure.TreeNode.ActorXZ); this->m_ImageView->RemoveActor(2, iStructure.TreeNode.ActorYZ); this->m_ImageView->RemoveActor(3, iStructure.TreeNode.ActorXYZ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- TrackStructure* TrackContainer:: UpdatePointsForATrack(const unsigned int& iTrackID, std::list< double * >& iListCenterBoundingBoxes) { assert( iTrackID != 0 ); assert ( this->m_ImageView ); // get pointer to the track MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackID); TrackStructure* mother; if ( motherIt != m_Container.get< TraceID >().end() ) { /* * \note Nicolas- const_cast is OK to modify polydata in the container since we don't sort on it but better avoid it */ mother = const_cast(&(*motherIt)); RecomputeMap(mother, iListCenterBoundingBoxes); // if the element has no polydata create a new address for the polydata if ( ! mother->Nodes ) { //Create new polydata (new address) mother->Nodes = vtkPolyData::New(); } // update the polydata (which represents the current track) UpdateTrackStructurePolyData( *mother ); // if element has no actors, create it if ( ! mother->ActorXY ) { // add actors in the visualization with given property CreateTrackActors( *mother ); return mother; } UpdateTrackActors( *mother ); } else { mother = new TrackStructure; } return mother; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: RecomputeMap(TrackStructure* iStructure, std::list< double * >& iPoints) { // empty current element map PointsMapConstIterator begin = iStructure->PointsMap.begin(); PointsMapConstIterator end = iStructure->PointsMap.end(); while ( begin != end ) { // free memory delete[] begin->second; ++begin; } iStructure->PointsMap.clear(); // add points to the map std::list< double * >::iterator beginList = iPoints.begin(); std::list< double * >::iterator endList = iPoints.end(); while ( beginList != endList ) { int xyzBB[3] = { static_cast< int >( ( *beginList )[0] ), static_cast< int >( ( *beginList )[1] ), static_cast< int >( ( *beginList )[2] ) }; unsigned int time = static_cast< unsigned int >( ( *beginList )[3] ); // convert xyz coordinates double *xyz = m_ImageView->GetImageViewer(0) ->GetWorldCoordinatesFromImageCoordinates(xyzBB); bool insertElement = iStructure->InsertElement(time, xyz); (void) insertElement; assert ( insertElement ); ++beginList; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateElementHighlightingWithGivenTraceIDs(const QStringList & iList, const Qt::CheckState & iCheck) { Superclass::UpdateElementHighlightingWithGivenTraceIDsBase(iList, iCheck); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateElementVisibilityWithGivenTraceIDs(const QStringList & iList, const Qt::CheckState & iCheck) { Superclass::UpdateElementVisibilityWithGivenTraceIDsBase(iList, iCheck); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: ChangeColorCode(const QString& iColorCode) { m_ActiveTrackScalars = iColorCode; if ( m_ActiveTrackScalars.compare("Original") ) { // get range for the tracks double *range = setTrackNodeScalars(iColorCode); // associated LUT vtkSmartPointer< vtkLookupTable > LUT = vtkSmartPointer< vtkLookupTable >::New(); LUT->SetTableRange(range); LUT->SetNumberOfTableValues(1024); LUT->SetHueRange(0, 0.7); LUT->SetSaturationRange(1, 1); LUT->SetValueRange(1, 1); LUT->Build(); SetScalarRangeForAllElements(range[0], range[1]); SetLookupTableForColorCoding(LUT); delete[] range; } else { this->RenderAllElementsWithOriginalColors(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: ChangeDivisionsColorCode(const QString& iColorCode) { m_ActiveDivisionScalars.clear(); m_ActiveDivisionScalars.append(iColorCode); if ( m_ActiveDivisionScalars.compare("Original") ) { // get range for the division double *range = setDivisionNodeScalars(iColorCode); // associated LUT vtkSmartPointer< vtkLookupTable > LUT = vtkSmartPointer< vtkLookupTable >::New(); LUT->SetTableRange(range); LUT->SetNumberOfTableValues(1024); LUT->SetHueRange(0, 0.7); LUT->SetSaturationRange(1, 1); LUT->SetValueRange(1, 1); LUT->Build(); SetScalarRangeForAllDivisions(range[0], range[1]); SetLookupTableForAllDivisionsColorCoding(LUT); } else { this->RenderAllDivisionsWithOriginalColors(); } assert ( m_ImageView ); this->m_ImageView->UpdateRenderWindows(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: SetScalarRangeForAllDivisions(const double& iMin, const double& iMax) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().begin(); while ( it != m_Container.get< TraceID >().end() ) { if ( !it->IsLeaf() ) { it->TreeNode.SetScalarRange(iMin, iMax); } ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: SetLookupTableForAllDivisionsColorCoding(const vtkLookupTable *iLut) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().begin(); while ( it != m_Container.get< TraceID >().end() ) { if ( !it->IsLeaf() ) { it->TreeNode.SetLookupTable(iLut); } ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: RenderAllDivisionsWithOriginalColors() { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().begin(); while ( it != m_Container.get< TraceID >().end() ) { if ( !it->IsLeaf() ) { it->TreeNode.RenderWithOriginalColors(); } ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- double * TrackContainer:: setTrackNodeScalars(const QString& iArrayName) { double *range = new double[2]; range[0] = std::numeric_limits< double >::max(); range[1] = std::numeric_limits< double >::min(); MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().begin(); while ( it != m_Container.get< TraceID >().end() ) { // does the track have a polydata if ( it->Nodes ) { // convert qstring to const char* double *realTime = it->Nodes->GetPointData()->GetArray( iArrayName.toLocal8Bit().data())->GetRange(); range[0] = std::min(range[0], realTime[0]); range[1] = std::max(range[1], realTime[1]); //set active scalar // convert qstring to const char* it->Nodes->GetPointData()->SetActiveScalars( iArrayName.toLocal8Bit().data()); } ++it; } return range; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- double * TrackContainer:: setDivisionNodeScalars(const QString& iArrayName) { double *range = new double[2]; range[0] = std::numeric_limits< double >::max(); range[1] = std::numeric_limits< double >::min(); MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().begin(); while ( it != m_Container.get< TraceID >().end() ) { // does the division have a polydata if ( !it->IsLeaf() ) { // convert qstring to const char* double *realTime = it->TreeNode.Nodes->GetPointData()->GetArray( iArrayName.toLocal8Bit().data())->GetRange(); range[0] = std::min(range[0], realTime[0]); range[1] = std::max(range[1], realTime[1]); //set active scalar // convert qstring to const char* it->TreeNode.Nodes->GetPointData()->SetActiveScalars( iArrayName.toLocal8Bit().data()); } ++it; } return range; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: setTimeInterval(const int& iTimeInterval) { m_TimeInterval = iTimeInterval; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int TrackContainer:: getTimeInterval() { return m_TimeInterval; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateTracksRepresentation(const double& iRadius, const double& iRadius2, const double& iWidth ) { MultiIndexContainerType::iterator it = m_Container.begin(); bool IsThereNonNullRadius = ( iRadius > 0 || iRadius2 > 0 ); while ( it != m_Container.end() ) { // restore original polydata bool pointsInPolydata = UpdateTrackStructurePolyData( ( *it ) ); // add glyphs if necessary if( pointsInPolydata ) { if ( IsThereNonNullRadius ) { it->UpdateTracksRepresentation(iRadius, iRadius2); } else { it->UpdateLineWidth( iWidth ); } } ++it; } // update color since active scalar is set to NULL in // UpdateTrackStructurePolyData ChangeColorCode(m_ActiveTrackScalars); assert ( this->m_ImageView ); this->m_ImageView->UpdateRenderWindows(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- double* TrackContainer::GetBorderOfTheTrack( const unsigned int& iTrackID, const BorderType& iBorder) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iTrackID); if( it != m_Container.get< TraceID >().end() ) { vtkPolyData* nodes = it->Nodes; if( nodes ) { vtkPoints* points = nodes->GetPoints(); if( points ) { if(!iBorder) { return points->GetPoint(0); } else { vtkIdType nbOfPoints = points->GetNumberOfPoints(); return points->GetPoint(nbOfPoints-1); } } } } return NULL; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: SetListOfDivisions( std::list& iListOfDivisions) { // Create list iterator std::list::iterator it = iListOfDivisions.begin(); while( it != iListOfDivisions.end() ) { // get ids unsigned int mother = *it; ++it; unsigned int daughter1 = *it; ++it; unsigned int daughter2 = *it; ++it; // create connections and actor for the division of interest AddDivision(mother, daughter1, daughter2, false); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: AddDivision( const unsigned int& iMotherID, const unsigned int& iDaughter1ID, const unsigned int& iDaughter2ID, const bool& iVisible) { // get address of the structures of interest //------------------------------ MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iMotherID); if( motherIt != m_Container.get< TraceID >().end() ) { MultiIndexContainerTraceIDIterator daughter1It = m_Container.get< TraceID >().find(iDaughter1ID); if( daughter1It != m_Container.get< TraceID >().end() ) { MultiIndexContainerTraceIDIterator daughter2It = m_Container.get< TraceID >().find(iDaughter2ID); if( daughter2It != m_Container.get< TraceID >().end() ) { // create connections //------------------------------ // motherID->D1 // ->D2 //------------------------------ TrackStructure* mother = const_cast(&(*motherIt)); mother->TreeNode.m_Child.push_back( const_cast(&(*daughter1It))); mother->TreeNode.m_Child.push_back( const_cast(&(*daughter2It))); // Create Polydata CreateDivisionPolydata(iMotherID); // Create Actor /* \todo Nicolas - should do it through a modify */ std::vector< vtkActor * > actors = CreateDivisionActor(mother->TreeNode.Nodes, iVisible); mother->TreeNode.ActorXY = actors[0]; mother->TreeNode.ActorXZ = actors[1]; mother->TreeNode.ActorYZ = actors[2]; mother->TreeNode.ActorXYZ = actors[3]; mother->TreeNode.Visible = iVisible; //------------------------------ // D1->motherID // D2->motherID //------------------------------ /* \todo Nicolas - should do it through a modify */ TrackStructure* d1 = const_cast(&(*daughter1It)); d1->TreeNode.m_Mother = const_cast(&(*motherIt)); TrackStructure* d2 = const_cast(&(*daughter2It)); d2->TreeNode.m_Mother = const_cast(&(*motherIt)); this->m_ImageView->UpdateRenderWindows(); } } } } //------------------------------------------------------------------------- void TrackContainer:: CreateDivisionPolydata(const unsigned int& iMother) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iMother); if( motherIt != m_Container.get< TraceID >().end() ) { // Arnaud: what about if any of the parameter is NULL? // Arnaud: what about if one daughter is in the field of view, // and not the other one? // Nicolas: dont deal with any of that yet // Get points of interest: // Mother: last point // D1 & D2: first point double* mother = this->GetBorderOfTheTrack(iMother, LAST); if( !mother ) { std::cout << "iMother : " << iMother << std::endl; return; } double* daughter1 = this->GetBorderOfTheTrack( motherIt->TreeNode.m_Child[0]->TraceID, FIRST); if( !daughter1 ) { std::cout << "iMother : " << iMother << std::endl; std::cout << "daughter1: " << motherIt->TreeNode.m_Child[0]->TraceID << std::endl; return; } double* daughter2 = this->GetBorderOfTheTrack( motherIt->TreeNode.m_Child[1]->TraceID, FIRST); if( !daughter2 ) { std::cout << "iMother : " << iMother << std::endl; std::cout << "daughter2: " << motherIt->TreeNode.m_Child[1]->TraceID << std::endl; return; } //setup points (geometry) vtkSmartPointer points = vtkSmartPointer::New(); points->InsertNextPoint ( daughter1[0], daughter1[1], daughter1[2] ); points->InsertNextPoint ( mother[0], mother[1], mother[2] ); points->InsertNextPoint ( daughter2[0], daughter2[1], daughter2[2] ); // create the lines vtkSmartPointer lines = vtkSmartPointer::New(); for(int i=0; i<2; ++i) { //Create the first line (between Origin and P0) vtkSmartPointer line = vtkSmartPointer::New(); line->GetPointIds()->SetId(0,i); line->GetPointIds()->SetId(1,i+1); lines->InsertNextCell(line); } // create polydata vtkSmartPointer division = vtkSmartPointer::New(); division->SetPoints(points); division->SetLines(lines); /* * \todo Nicolas: we might want to extend it to more parameters: color, ... * and to the meshes->efficiency of show/hide, picking, boxwidget, ...! */ // add track ID to the polydata so we can get it from the actor later on vtkSmartPointer trackIDArray = vtkSmartPointer::New(); trackIDArray->SetNumberOfComponents(1); trackIDArray->SetNumberOfValues(1); trackIDArray->SetName("DIVISION"); trackIDArray->SetValue(0,iMother); division->GetFieldData()->AddArray(trackIDArray); // update structure m_Container.get< TraceID >().modify( motherIt , create_node_division(division) ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector TrackContainer:: CreateDivisionActor(vtkPolyData* iPolyData, const bool& iVisible) { /* * \todo Nicolas: to be enhanced */ vtkSmartPointer trace_property = vtkSmartPointer::New(); double r = 1.0; double g = 1.0; double b = 1.0; double a = 1.0; trace_property->SetColor(r, g, b); trace_property->SetOpacity(a); std::vector< vtkActor * > divisionActors = this->m_ImageView->AddContour( iPolyData, trace_property ); /* \todo Nicolas- clear all that. Should be requiered or should be consistent at least */ // add it to visu?? if( iVisible ) { // add to 3d this->m_ImageView->AddActor(3, divisionActors[3]); } else { // remove from 2d this->m_ImageView->RemoveActor(0, divisionActors[0]); this->m_ImageView->RemoveActor(1, divisionActors[1]); this->m_ImageView->RemoveActor(2, divisionActors[2]); } return divisionActors; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: HighlightCollection(const unsigned int& iRootTrackID, const bool& iHilighted) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iRootTrackID); if( motherIt != m_Container.get< TraceID >().end() ) { UpdateCollectionHighlighted(motherIt, iHilighted); this->m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: ShowCollection(const unsigned int& iRootTrackID, const bool& iVisible) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iRootTrackID); if( motherIt != m_Container.get< TraceID >().end() ) { UpdateCollectionVisibility(motherIt, iVisible); this->m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateCollectionVisibility(MultiIndexContainerTraceIDIterator& it, const bool& iVisible) { if( !it->IsLeaf() ) { ModifyDivisionVisibility(it, iVisible); } std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateCollectionVisibility(childIt,iVisible); } ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: DeleteCollection(unsigned int iRootTrackID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iRootTrackID); if( motherIt != m_Container.get< TraceID >().end() ) { UpdateCollectionDelete(motherIt); this->m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateCollectionDelete(MultiIndexContainerTraceIDIterator& it) { std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateCollectionDelete(childIt); } ++itDivision; } if( !it->IsLeaf() ) { DeleteADivision(it->TraceID); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateCollectionHighlighted(MultiIndexContainerTraceIDIterator& it, const bool& iHighlighted) { if( !it->IsLeaf() ) { ModifyDivisionHighlight(it, iHighlighted); } std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateCollectionHighlighted(childIt,iHighlighted); } ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int TrackContainer:: ModifyDivisionVisibility(MultiIndexContainerTraceIDIterator& it, const bool& iVisible) { m_Container.get< TraceID >().modify( it , change_visible_division(iVisible) ); typedef void ( QGoImageView3D::*ImageViewMember )(const int &, vtkActor *); ImageViewMember f; if ( iVisible ) { f = &QGoImageView3D::AddActor; } else { f = &QGoImageView3D::RemoveActor; } assert( m_ImageView ); ( m_ImageView->*f )(0, it->TreeNode.ActorXY); ( m_ImageView->*f )(1, it->TreeNode.ActorXZ); ( m_ImageView->*f )(2, it->TreeNode.ActorYZ); ( m_ImageView->*f )(3, it->TreeNode.ActorXYZ); return 1; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int TrackContainer:: ModifyDivisionHighlight(MultiIndexContainerTraceIDIterator& it, const bool& iHighlight ) { vtkProperty* temp_property = vtkProperty::New(); if (!iHighlight) { temp_property->SetColor(it->TreeNode.rgba[0], it->TreeNode.rgba[1], it->TreeNode.rgba[2]); temp_property->SetOpacity(it->TreeNode.rgba[3]); temp_property->SetLineWidth(this->m_IntersectionLineWidth); } else { temp_property->DeepCopy(this->m_HighlightedProperty); } m_Container.get< TraceID >().modify( it, change_highlighted_division(temp_property, iHighlight)); temp_property->Delete(); return 1; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: DeleteADivision( const unsigned int& iMotherID) { // find iterator MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iMotherID); if(motherIt!= m_Container.get< TraceID >().end()) { TrackStructure* mother = const_cast(&(*motherIt)); // Delete the actor // remove actor from visu and delete them this->m_ImageView->RemoveActor(0, mother->TreeNode.ActorXY); this->m_ImageView->RemoveActor(1, mother->TreeNode.ActorXZ); this->m_ImageView->RemoveActor(2, mother->TreeNode.ActorYZ); this->m_ImageView->RemoveActor(3, mother->TreeNode.ActorXYZ); mother->TreeNode.ReleaseData(); // Reset pointers // child (to do first) /* \todo Nicolas - do a loop */ mother->TreeNode.m_Child[0]->TreeNode.m_Mother = NULL; mother->TreeNode.m_Child[1]->TreeNode.m_Mother = NULL; // mother mother->TreeNode.m_Child.resize(0); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list TrackContainer:: GetSubLineage( const unsigned int& iTrackID ) { std::list listOfIDs; // find the iterator MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackID); if( motherIt != m_Container.get< TraceID >().end() ) { UpdateSubLineage(motherIt, listOfIDs); } return listOfIDs; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateSubLineage(MultiIndexContainerTraceIDIterator it, std::list& iList) { iList.push_back( it->TraceID ); std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateSubLineage(childIt,iList); } ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateCollectionHighlighting(const unsigned int& iTraceId) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTraceId); if(motherIt!=m_Container.get().end()) { GetRootIterator( motherIt ); bool highlight = !motherIt->TreeNode.Highlighted; UpdateCollectionHighlighted(motherIt, highlight); this->m_ImageView->UpdateRenderWindows(); // send signal to lineage container emit UpdateLineageHighlightingFromTrackRootID( motherIt->TraceID ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: GetRootIterator(MultiIndexContainerTraceIDIterator& iMotherIterator) { if( iMotherIterator->IsRoot() ) { return; } iMotherIterator = m_Container.get< TraceID >().find( iMotherIterator->TreeNode.m_Mother->TraceID ); GetRootIterator( iMotherIterator ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigureLineageAttributes TrackContainer:: UpdateDivisionsForALineage(unsigned int iTrackIDRoot, double* color) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackIDRoot); GoFigureLineageAttributes Attributes; if(motherIt!=m_Container.get().end()) { UpdateDivisionScalar(motherIt, 0); // 0=depth of the root Attributes = this->GetLineageAttributes(iTrackIDRoot); UpdateDivisionColor(motherIt, color); m_ImageView->UpdateRenderWindows(); } return Attributes; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigureLineageAttributes TrackContainer:: UpdateCollectionScalars(const unsigned int& iTrackID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackID); GoFigureLineageAttributes oAttributes; if( motherIt != m_Container.get< TraceID >().end() ) { UpdateDivisionScalar(motherIt, 0); oAttributes = this->GetLineageAttributes(iTrackID); // 0=depth of the root } return oAttributes; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateDivisionScalar(MultiIndexContainerTraceIDIterator& it, const unsigned int& iDepth) { if(!it->IsLeaf()) { //add array vtkSmartPointer< vtkIntArray > depthArray = vtkSmartPointer< vtkIntArray >::New(); depthArray->SetNumberOfComponents(1); depthArray->SetName("DepthInformation"); depthArray->InsertNextValue(iDepth); depthArray->InsertNextValue(iDepth); depthArray->InsertNextValue(iDepth); m_Container.get< TraceID >().modify( it , add_array_division(depthArray) ); } std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { unsigned int depth = iDepth+1; UpdateDivisionScalar(childIt,depth); } ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateCollectionColors(const unsigned int& iTrackID, const double* color) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackID); if(motherIt != m_Container.get< TraceID >().end()) { UpdateDivisionColor(motherIt, color); m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateDivisionColor(MultiIndexContainerTraceIDIterator& it, const double* iColor) { if(!it->IsLeaf()) { m_Container.get< TraceID >().modify( it , change_data_color_division(iColor) ); m_Container.get< TraceID >().modify( it , change_actor_color_division(iColor) ); } std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateDivisionColor(childIt,iColor); } ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateCollectionColorsData(const unsigned int& iTrackID, const double* color) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackID); if( motherIt != m_Container.get< TraceID >().end() ) { UpdateDivisionColorData(motherIt, color); m_ImageView->UpdateRenderWindows(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateDivisionColorData(MultiIndexContainerTraceIDIterator& it, const double* iColor) { if(!it->IsLeaf()) { m_Container.get< TraceID >().modify( it , change_data_color_division(iColor) ); } std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateDivisionColorData(childIt,iColor); } ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int TrackContainer:: GetCollectionMaxDepth(const unsigned int& iTrackRootID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackRootID); if( motherIt != m_Container.get< TraceID >().end() ) { unsigned int depth = 0; UpdateCollectionMaxDepth(motherIt, 0, depth); //0: root depth return depth; } else { return 0; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateCollectionMaxDepth(MultiIndexContainerTraceIDIterator& it, const unsigned int& iDivisionDepth, unsigned int& iLineageDepth) { if( it->IsLeaf() ) { if( iDivisionDepth > iLineageDepth ) { iLineageDepth = iDivisionDepth; } } std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { unsigned int depth = iDivisionDepth+1; UpdateCollectionMaxDepth(childIt,depth,iLineageDepth); } ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int TrackContainer:: GetCollectionMinDepth(const unsigned int& iTrackRootID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackRootID); if( motherIt != m_Container.get< TraceID >().end() ) { unsigned int depth = std::numeric_limits::max(); UpdateCollectionMinDepth(motherIt, 0, depth); //0: root depth return depth; } else { return 0; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateCollectionMinDepth(MultiIndexContainerTraceIDIterator& it, const unsigned int& iDivisionDepth, unsigned int& iLineageDepth) { if( it->IsLeaf() ) { if( iDivisionDepth < iLineageDepth ) { iLineageDepth = iDivisionDepth; } } std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { unsigned int depth = iDivisionDepth+1; UpdateCollectionMinDepth(childIt,depth,iLineageDepth); } ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int TrackContainer:: GetCollectionNumberOfDivisions(const unsigned int& iTrackRootID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackRootID); if( motherIt != m_Container.get< TraceID >().end() ) { unsigned int numberOfDivisions = 0; UpdateCollectionNumberOfDivisions(motherIt,numberOfDivisions); return numberOfDivisions; } else { return 0; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateCollectionNumberOfDivisions(MultiIndexContainerTraceIDIterator& it, unsigned int& iNumberOfDivisions) { if(!it->IsLeaf()) { ++iNumberOfDivisions; } std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateCollectionNumberOfDivisions(childIt,iNumberOfDivisions); } ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int TrackContainer:: GetCollectionNumberOfLeaves(const unsigned int& iTrackRootID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackRootID); if(motherIt != m_Container.get< TraceID >().end()) { unsigned int numberOfLeaves = 1; UpdateCollectionNumberOfDivisions(motherIt,numberOfLeaves); return numberOfLeaves; } else { return 0; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoFigureLineageAttributes TrackContainer:: GetLineageAttributes(unsigned int iTrackRootID) { //check if possible to iterate on the tree only once GoFigureLineageAttributes LineageAttributes; LineageAttributes.MaxDepth = this->GetCollectionMaxDepth(iTrackRootID); LineageAttributes.MinDepth = this->GetCollectionMinDepth(iTrackRootID); LineageAttributes.NumberOfDivisions = this->GetCollectionNumberOfDivisions(iTrackRootID); LineageAttributes.NumberOfLeaves = this->GetCollectionNumberOfLeaves( iTrackRootID); return LineageAttributes; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateCollectionNumberOfLeaves(MultiIndexContainerTraceIDIterator& it, unsigned int& iNumberOfLeaves) { if(it->IsLeaf()) { ++iNumberOfLeaves; } std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateCollectionNumberOfLeaves(childIt,iNumberOfLeaves); } ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- vtkMutableDirectedGraph* TrackContainer:: ExportLineage(const unsigned int& iTrackID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackID); // graph to be exported vtkMutableDirectedGraph* graph = vtkMutableDirectedGraph::New(); unsigned int pedigree = graph->AddVertex(); // arrays we want to export vtkDoubleArray* id = vtkDoubleArray::New(); id->SetName("Track ID"); // arrays we want to export vtkDoubleArray* depth = vtkDoubleArray::New(); depth->SetName("Lineage Depth"); vtkStringArray* cellType = vtkStringArray::New(); depth->SetName("Cell Type"); UpdateLineage(motherIt, graph, pedigree, 0, // mother vtkIDtype 0,depth,// depth information id); // id info graph->GetVertexData()->AddArray(id); graph->GetVertexData()->AddArray(depth); // delete array id->Delete(); depth->Delete(); cellType->Delete(); return graph; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateLineage(MultiIndexContainerTraceIDIterator& it, vtkMutableDirectedGraph* iGraph, unsigned int iPedrigree, vtkIdType mother, unsigned int iDepth, vtkDoubleArray* iDepthArray, vtkDoubleArray* iIDArray) { // Update mother ID vtkIdType motherPedigree = iPedrigree; //add info iIDArray->InsertValue(iPedrigree, it->TraceID); // add info iDepthArray->InsertValue(iPedrigree, iDepth); if( it->IsLeaf() ) { return; } std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); // add edge iPedrigree = iGraph->AddChild(motherPedigree); //go through tree UpdateLineage(childIt,iGraph, iPedrigree, motherPedigree, iDepth+1, iDepthArray,iIDArray); ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: SetCollectionColorCode(const std::string& iColumnName, const std::map< unsigned int, std::string >& iValues) { typedef std::map< unsigned int, std::string > MapType; typedef MapType::const_iterator MapConstIterator; std::map< std::string, double > stringmap; if ( iColumnName.empty() || iValues.empty() ) { this->RenderAllDivisionsWithOriginalColors(); assert ( m_ImageView ); this->m_ImageView->UpdateRenderWindows(); return; } MapConstIterator it = iValues.begin(); double temp = 0.; try { temp = boost::lexical_cast< double >(it->second); } catch(boost::bad_lexical_cast &) { if ( stringmap.empty() ) { stringmap[it->second] = 0.; } else { std::map< std::string, double >::iterator m_it = stringmap.find(it->second); if ( m_it != stringmap.end() ) { temp = m_it->second; } else { std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin(); temp = r_it->second; temp += 1.0; } } } double min_value = temp; double max_value = temp; while ( it != iValues.end() ) { MultiIndexContainerTraceIDIterator trace_it = this->m_Container.get< TraceID >().find(it->first); // convert value // Here let's make sure you are not passing crazy values! try { temp = boost::lexical_cast< double >(it->second); } catch(boost::bad_lexical_cast &) { // stringmap is not empty and has at least one elements std::map< std::string, double >::iterator m_it = stringmap.find(it->second); if ( m_it != stringmap.end() ) { temp = m_it->second; } else { std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin(); temp = r_it->second; temp += 1.0; } } UpdateDivisionScalarData(trace_it, it->second, temp, min_value, max_value); ++it; } SetScalarRangeForAllDivisions(min_value, max_value); assert ( m_ImageView ); this->m_ImageView->UpdateRenderWindows(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: UpdateDivisionScalarData(MultiIndexContainerTraceIDIterator& it, const std::string& iColumnName, const double& iValue, double& iMin, double& iMax) { if( !it->IsLeaf() ) { if ( iValue > iMax ) { iMax = iValue; } if ( iValue < iMin ) { iMin = iValue; } it->TreeNode.SetScalarData(iColumnName, iValue); } std::vector::const_iterator itDivision = it->TreeNode.m_Child.begin(); while( itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateDivisionScalarData(childIt, iColumnName, iValue, iMin, iMax); } ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: SetDivisionRandomColor(const std::string & iColumnName, const std::map< unsigned int, std::string > & iValues) { typedef std::map< unsigned int, std::string > MapType; typedef MapType::const_iterator MapConstIterator; std::map< std::string, double > stringmap; if ( iColumnName.empty() || iValues.empty() ) { this->RenderAllDivisionsWithOriginalColors(); return; } MapConstIterator it = iValues.begin(); double temp = 0.; try { temp = boost::lexical_cast< double >(it->second); } catch(boost::bad_lexical_cast &) { if ( stringmap.empty() ) { stringmap[it->second] = 0.; } else { std::map< std::string, double >::iterator m_it = stringmap.find(it->second); if ( m_it != stringmap.end() ) { temp = m_it->second; } else { std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin(); temp = r_it->second; temp += 1.0; } } } unsigned int val = static_cast< unsigned int >(temp); unsigned int modulo = val % 30; temp = static_cast< double >(modulo); double min_value = temp; double max_value = temp; using boost::multi_index:: get; while ( it != iValues.end() ) { MultiIndexContainerTraceIDIterator trace_it = this->m_Container.get< TraceID >().find(it->first); if ( trace_it != this->m_Container.get< TraceID >().end() ) { if ( trace_it->TreeNode.Nodes ) //make sure the trace has points !!! { // Here let's make sure you are not passing crazy values! try { temp = boost::lexical_cast< double >(it->second); } catch(boost::bad_lexical_cast &) { // stringmap is not empty and has at least one element std::map< std::string, double >::iterator m_it = stringmap.find(it->second); if ( m_it != stringmap.end() ) { temp = m_it->second; } else { std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin(); temp = r_it->second; temp += 1.0; } } val = static_cast< unsigned int >(temp); modulo = val % 30; temp = static_cast< double >(modulo); UpdateDivisionScalarData(trace_it, it->second, temp, min_value, max_value); } } //end make sure the trace has points !!! ++it; } SetScalarRangeForAllDivisions(min_value, max_value); assert ( m_ImageView ); this->m_ImageView->UpdateRenderWindows(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: AddVolume(const unsigned int& iTrackID, const double& iVolume) { MultiIndexContainerTraceIDIterator trace_it = this->m_Container.get< TraceID >().find(iTrackID); if ( trace_it != m_Container.get< TraceID >().end() ) { m_Container.get< TraceID >().modify( trace_it , add_volume(iVolume) ); } } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/VisualizationTraceContainers/LineageContainer.h0000644000175000017500000001675011667757442026677 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __LineageContainer_h #define __LineageContainer_h #include #include "LineageStructure.h" #include "StructureHelper.h" #include "TraceContainerBase.h" #include "QGoImageView3D.h" namespace boost { typedef multi_index::multi_index_container< LineageStructure, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< TraceID >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, unsigned int, TraceID) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< CollectionID >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, unsigned int, CollectionID) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< Highlighted >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, bool, Highlighted) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< Visible >, BOOST_MULTI_INDEX_MEMBER(TraceStructure, bool, Visible) >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< TrackRootID >, BOOST_MULTI_INDEX_MEMBER(LineageStructure, unsigned int, TrackRootID) > > > MultiIndexLineageContainer; } /** \class LineageContainer \brief Wraps a boost multi index container of LineageStructure. This class intends to synchronize Lineage representation in the Visualization and in the TableWidget \sa LineageStructure QGoTableWidget QGoImageView3D */ class LineageContainer: public TraceContainerBase< boost::MultiIndexLineageContainer > { Q_OBJECT public: typedef TraceContainerBase< boost::MultiIndexLineageContainer > Superclass; typedef Superclass::MultiIndexContainerType MultiIndexContainerType; typedef Superclass::MultiIndexContainerElementType LineageType; typedef MultiIndexContainerType::index< TrackRootID >::type::iterator MultiIndexContainerTrackRootIDIterator; //------------------------------------------------------------------------ /** \brief Constructor. */ explicit LineageContainer( QObject *iParent, QGoImageView3D *iView); /** \brief Destructor. */ virtual ~LineageContainer(); /** \brief insert a new element in the container with all the info needed \param[in] iLineageID ID for the new lineage \param[in] irgba color of the lineage \param[in] iTrackIDRoot for the new lineage \param[in] IsVisible */ void InsertNewLineage( const unsigned int& iLineageID, double irgba[4], const unsigned int& iTrackIDRoot, const bool& IsVisible = false); /* * \brief Get the list of all the lineages roots, as track IDs * \return list containg the track root ids */ std::list GetListOfTrackRootIDs(); /* * \brief Get the list of all the lineages IDs * \return list containg the lineage ids */ std::list GetListOfLineageIDs(); /* * \brief Get the track root ID of the given lineage * \param[in] iTraceID lineage ID of interest * \return related track root ID */ unsigned int GetLineageTrackRootID( const unsigned int& iTraceID ); /* * \brief Get the trace root ID from the track root ID * \param[in] iTraceID track root id * \return related lineage ID */ unsigned int GetTraceIDFromTrackRootID( const unsigned int& iTraceID ); /* * \brief Get the visibility of the given lineage * \param[in] iTraceID lineage ID of interest * \return visibility */ bool GetLineageVisibile( const unsigned int& iTraceID ); /* * \brief Get the hilighted of the given lineage * \param[in] iTraceID lineage ID of interest * \return highlighted */ bool GetLineageHighlighted( const unsigned int& iTraceID ); /* * \brief Get the color of the given lineage * \param[in] iTraceID lineage ID of interest * \return color */ double* GetLineageColor( const unsigned int& iTraceID ); /**\todo implement them:*/ bool DeleteElement(const unsigned int & iId); bool DeleteElement(MultiIndexContainerTraceIDIterator iIter); std::list< unsigned int > DeleteAllHighlightedElements(); signals: void HighlightLineage(const unsigned int&, const bool&); /* \todo Nicolas-Signal there to avoid warning but has to be connected to the box widget */ void TraceVisibilityChanged(unsigned int, Qt::CheckState); void ShowLineage(const unsigned int&, const bool&); void DeleteLineage(unsigned int); /** \brief When one track has been picked (highlighted) from the visualization */ void TracePicked(unsigned int, Qt::CheckState); void ExportLineages(); public slots: /** \brief Change elements highlighting property given a list of TraceIDs and the new status. \param[in] iList list of TraceIDs \param[in] iCheck */ virtual void UpdateElementHighlightingWithGivenTraceIDs( const QStringList& iList, const Qt::CheckState& iCheck ); /** \brief Change elements visibility property given a list of TraceIDs and the new status. \param[in] iList list of TraceIDs \param[in] iCheck */ virtual void UpdateElementVisibilityWithGivenTraceIDs( const QStringList& iList, const Qt::CheckState& iCheck ); /** \brief Update highlighting property of one element given one actor. \param[in] iActor Actor of the element to be modified \return true if the element exists \return false else */ void UpdateElementHighlighting(unsigned int iTraceID) { Qt::CheckState state; Superclass::UpdateElementHighlightingWithTraceID( iTraceID, state ); emit TracePicked(iTraceID, state); } protected: std::vector< vtkActor* > AddTrace( vtkPolyData* , vtkProperty* ); private: Q_DISABLE_COPY(LineageContainer); }; #endif // LineageCONTAINER_H GoFigure2-v0.9.0/Code/GUI/lib/QGoTrackEditingWidget.h0000644000175000017500000002146511667757442021744 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTrackEditingWidget_h #define __QGoTrackEditingWidget_h #include #include #include "ui_TrackEditingWidget.h" #include "QGoGUILibConfigure.h" #include "vtkActor.h" #include "vtkInteractorStyleImage3D.h" #include "vtkEventQtSlotConnect.h" #include "vtkSmartPointer.h" #include "MeshContainer.h" class vtkPoints; /** \class QGoTrackEditingWidget \brief This dialog allows the user to split/merge the tracks using a GUI \ingroup GUI Track */ class QGOGUILIB_EXPORT QGoTrackEditingWidget: public QDialog, private Ui::TrackEditingWidget { Q_OBJECT public: explicit QGoTrackEditingWidget( MeshContainer* imeshContainer = NULL, QWidget *parent = 0 ); ~QGoTrackEditingWidget(); /** * \brief Initialize the renderer, the rendering window, the interactor style * and add the meshes, polylines and labels to the visualization */ void init(); /** * \brief Returns the list of tracks to be created * \return The list of tracks to be created */ std::list< std::list< unsigned int > > GetListOfTracksToBeCreated(); /** * \brief Returns the list of tracks to be updated * \return The list of tracks to be updated */ std::map< unsigned int, std::list< unsigned int > > GetListOfTracksToBeUpdated(); /** * \brief Returns the list of tracks to be deleted * \return The list of tracks to be deleted */ std::list< unsigned int > GetListOfTracksToBeDeleted(); public slots: /** \brief Defines behavior when we pick an actor in the visualization */ void updateCurrentActorSelection(vtkObject *caller); /** \brief Restore the track IDs to theirs original values (ie before entering the widget). Creates a TracksToBeCreated list, a TracksToBeUpdated list and a TracksToBeDeleted list. */ void restoreTrackIDs(); void updateMeshesActors( bool ); private: /** * \brief Change the apperance of the mesh depending on if we want to * highlight it or not. First click on one actor will highlight it. Second * click will restore its original apperance. * \param[in] iHighlight true if we want to highlight the actor (i.e. first click) */ void highlightFirstActor( bool iHighlight ); /** * \brief Modify the mesh collection to the chosen track ID. * \param[in] iMeshID mesh to be modified * \param[in] iCollectionID new track ID of the mesh */ void modifyMeshCollectionID( unsigned int iMeshID, unsigned int iCollectionID); /** * \brief Get and display the meshes actors */ void computeMeshActors(); /** * \brief Get the list of the mesh IDs which belong to the given track * \param[in] iCollection track from which we want to extract the mesh id * \return list of the meshes IDs */ std::list< unsigned int > getMeshIDsInTrack( unsigned int iCollection); /** * \brief Reassigns track IDs and add the meshes, polylines and labels actors * to the visualization */ void initializeVisualization(); /** * \brief Cut a track at the current actor. The actor represents a polyline * between 2 meshes. * \param[in] iActor position where we want to split the track */ void cutTrack( vtkActor* iActor); /** * \brief Merge 2 tracks, given 2 mesh IDs. * Requierements for a successful merge: * -Each mesh must belong to different tracks. * -The tracks can't overlap. * -The mesh has to be a border of its own track. * \param[in] iFirstMesh ID of a mesh belonging to the first track * \param[in] iSecondMesh ID of a mesh belonging to the second track * \return true is the merge was successful */ bool mergeTrack( const unsigned int& iFirstMesh, const unsigned int& iSecondMesh); void merge( MeshContainer::MultiIndexContainerTraceIDIterator iBegin); /** * \brief Get the borders of the given track. * \param[in] iCollectionID track IDs we are interested in * \return time point and mesh id of the first and last mesh of the track */ std::pair< std::pair, std::pair > getTrackBorders( const unsigned int& iCollectionID ); /** * \brief Reassing real track IDs to temporary ones for convenience */ void reassignTrackIDs(); /** * \brief Update track IDs after a merge * -The mesh has to be a border of its own track. * \param[in] iIDToDelete ID of the track to be deleted * \param[in] iIDToUpdate ID of the track to be updated */ void updateTracksIDs( const unsigned int& iIDToDelete, const unsigned int& iIDToUpdate); /** * \brief Create the polyLines actors according to the current MeshContainer */ void computeLineActors(); vtkActor* computeSphere( unsigned int iTraceID, double* iCenter, double radius); void getClosestPoints(); /** * \brief Remove the polyLines actors. Usefull after a merge or a cut. An * "Update" method would be more efficient than remove then compute. */ void removeLineActors(); /** * \brief Create a line between 2 points * \param[in] iCenter1 Center of the first mesh * \param[in] iCenter2 Center of the second mesh * \param[in] iColor1 Color of the first mesh * \param[in] iColor2 Color of the second mesh * \return a pointer to the new actor. It has to be deleted somewhere. */ vtkActor* createPolylineActor( double* iCenter1, double* iCenter2, const double* iColor1 = NULL, const double* iColor2 = NULL ); /** * \brief Create label actors to see the temporal information of each mesh. * It is very useful for the merge. Note that the 2 input parameters have to * ordered in the same way. */ void computeLabelActor(); MeshContainer* m_MeshContainer; std::list< std::list< unsigned int > > m_ListOfNewTrack; std::map< unsigned int, std::list< unsigned int > > m_ListOfUpdatedTracks; std::list< unsigned int > m_ListOfDeletedTracks; QStatusBar *m_StatusBar; unsigned int m_MaxTrackID; unsigned int m_NumberOfTracks; bool m_SecondClick; vtkActor* m_CurrentActor; vtkActor* m_FirstMeshActor; unsigned int m_FirstMeshID; double m_MinimalDistance; vtkInteractorStyleImage3D* m_InteractorStyle3D; vtkSmartPointer m_VtkEventQtConnector; vtkSmartPointer renderer; enum TrackStatusType { NEW_TRACK = 0, UPDATED_TRACK, DELETED_TRACK }; struct TrackInformation { unsigned int RealID; TrackStatusType Status; // Constructors TrackInformation() : RealID( 0 ), Status( NEW_TRACK ) {} TrackInformation(unsigned int A, TrackStatusType B):RealID(A), Status(B){} }; typedef std::map< unsigned int, TrackInformation > TrackMapping; TrackMapping m_TrackMapping; typedef std::map< vtkActor*, unsigned int >::iterator LineActor2MeshIDIterator; std::map< vtkActor*, unsigned int > m_Line2MeshID; private: Q_DISABLE_COPY( QGoTrackEditingWidget ); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoPrintDatabase.cxx0000644000175000017500000024504311667757442021324 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoPrintDatabase.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "vtkActor.h" #include "vtkMySQLDatabase.h" #include "vtkSQLQuery.h" #include "vtkStringArray.h" #include "vtkStdString.h" #include "QGoTableWidget.h" #include "GoDBRecordSet.h" #include "GoDBRecordSetHelper.h" #include "GoDBContourRow.h" #include "GoDBMeshRow.h" #include "GoDBTrackRow.h" #include "GoDBLineageRow.h" #include "GoDBCoordinateRow.h" #include "GoDBColorRow.h" #include "QueryDataBaseHelper.h" #include "ConvertToStringHelper.h" #include "GoDBTraceInfoForTableWidget.h" #include "GoDBExport.h" #include "GoDBImport.h" #include "ContourMeshContainer.h" #include "QGoTrackEditingWidget.h" //-------------------------------------------------------------------------- QGoPrintDatabase::QGoPrintDatabase(QWidget *iParent) : QGoDockWidget(iParent), m_ContoursManager(NULL), m_MeshesManager(NULL), m_TracksManager(NULL), m_LineagesManager(NULL), m_DatabaseConnector(NULL), m_IsDatabaseUsed(false), m_ReeditMode(false), m_MeshGenerationMode(false) { this->SetUpUi(); this->m_CellTypeManager = new QGoDBCellTypeManager(this); this->m_SubCellTypeManager = new QGoDBSubCellTypeManager(this); this->m_ColorManager = new QGoDBColorManager(this); this->m_SelectedTimePoint = new int; this->CreateConnectionsForTraceSettingsWidget(this->m_TraceSettingsWidget); this->CreateConnectionsForTraceSettingsWidget(this->m_TraceSettingsWidgetForToolBar); QObject::connect( this, SIGNAL( customContextMenuRequested(const QPoint &) ), this, SLOT( CreateContextMenu(const QPoint &) ) ); QObject::connect( this->m_TraceSettingsWidget, SIGNAL( TraceChanged( int ) ), this, SLOT( TheTraceHasChanged( int ) ) ); QObject::connect( this->m_TraceSettingsWidgetForToolBar, SIGNAL( TraceChanged( int ) ), this, SLOT( TheTraceHasChanged( int ) ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoPrintDatabase::~QGoPrintDatabase() { if ( m_SelectedTimePoint ) { delete m_SelectedTimePoint; } // Need to release memory allocated for contours, meshes, tracks and lineages // contours if ( m_ContoursManager ) { delete m_ContoursManager; } // meshes if ( m_MeshesManager ) { delete m_MeshesManager; } // tracks if ( m_TracksManager ) { delete m_TracksManager; } // lineages if (m_LineagesManager) { delete m_LineagesManager; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SetUpUi() { this->m_ToggleAction->setToolTip(tr("Show/hide the table widget")); QIcon TableWidgetIcon; TableWidgetIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/TableWidget.png") ), QIcon::Normal, QIcon::Off); this->m_ToggleAction->setIcon(TableWidgetIcon); this->m_TraceSettingsWidget = new QGoTraceSettingsWidget(this); QWidget* Widget = new QWidget; QVBoxLayout* verticalLayout = new QVBoxLayout(Widget); this->m_StackedTables = new QStackedWidget(Widget); verticalLayout->addWidget(this->m_TraceSettingsWidget); this->m_TraceSettingsWidget->setVisible(false); this->m_TraceSettingsVisible = false; verticalLayout->addWidget(this->m_StackedTables); Widget->setLayout(verticalLayout); this->setContextMenuPolicy(Qt::CustomContextMenu); this->setWidget(Widget); this->SetConnectionsBetweenTheInstancesOfTraceSettings(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SetDatabaseVariables( const std::string & iNameDB, const std::string & iServer, const std::string & iUser, const std::string & iPassword, const unsigned int & iImgSessionID, const std::string & iImgSessionName) { m_Server = iServer; m_User = iUser; m_Password = iPassword; m_DBName = iNameDB; m_ImgSessionID = iImgSessionID; m_ImgSessionName = iImgSessionName; this->SetTracesManager(); this->m_BookmarkManager = new QGoDBBookmarkManager(this, this->m_ImgSessionID); QObject::connect( this->m_BookmarkManager, SIGNAL( ListBookmarksChanged() ), this, SIGNAL( OpenBookmarksToUpdate() ) ); this->InitializeTheComboboxesNotTraceRelated(); this->SetTSListCollectionID(); emit DBVariablesSet(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::OpenDBConnection() { if ( m_DatabaseConnector == NULL ) { this->m_DatabaseConnector = OpenDatabaseConnection(m_Server, m_User, m_Password, m_DBName); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::CloseDBConnection() { if ( CloseDatabaseConnection(m_DatabaseConnector) ) { this->m_DatabaseConnector = NULL; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::FillTableFromDatabase(const unsigned int& iThreshold) { bool limitedMemory = ( iThreshold != std::numeric_limits< unsigned int >::max() ); OpenDBConnection(); // Get number of meshes to be loaded unsigned int nbOfTraces = NumberOfElementForGivenImagingSessionAndTrace( this->m_DatabaseConnector, this->m_ImgSessionID, "mesh"); if( ( nbOfTraces <= iThreshold ) || !limitedMemory ) { this->m_VisibleTimePoints.clear(); this->GetContentAndDisplayAllTracesInfo(this->m_DatabaseConnector); } else { // if there are more than 5000 meshes, only load 3 time points in // memory this->m_VisibleTimePoints.resize(3); this->GetContentAndDisplayAllTracesInfoFor3TPs(this->m_DatabaseConnector); } CloseDBConnection(); QString title = QString("Table for: %1 ").arg( m_ImgSessionName.c_str() ); this->setWindowTitle(title); this->m_StackedTables->addWidget(this->m_ContoursManager->GetTableWidget()); this->m_StackedTables->addWidget(this->m_MeshesManager->GetTableWidget()); this->m_StackedTables->addWidget(this->m_TracksManager->GetTableWidget()); this->m_StackedTables->addWidget(this->m_LineagesManager->GetTableWidget()); m_IsDatabaseUsed = true; emit PrintDBReady(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::string QGoPrintDatabase::InWhichTableAreWe() { return this->m_TraceSettingsWidget->GetTraceName(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SaveContoursFromVisuInDB(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iTCoord, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iContourNodes) { OpenDBConnection(); unsigned int ContourID; if ( !this->m_ReeditMode ) { ContourID = this->m_ContoursManager->SaveNewContourFromVisu(iTCoord, iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, iContourNodes, this->m_DatabaseConnector, 1); } else { ContourID = this->m_ContoursManager->SaveReeditedContourFromVisu( iXCoordMin, iYCoordMin, iZCoordMin, iTCoord, iXCoordMax, iYCoordMax, iZCoordMax, iContourNodes, this->m_DatabaseConnector); this->m_ReeditMode = false; } std::list< unsigned int > ListContours; ListContours.push_back(ContourID); std::list< unsigned int > ListMeshes = this->m_ContoursManager->GetListCollectionIDs(this->m_DatabaseConnector, ListContours); if ( !ListMeshes.empty() ) { this->m_MeshesManager->UpdateBoundingBoxes(this->m_DatabaseConnector, ListMeshes); } CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SaveMeshFromVisuInDB(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, int iTCoord, vtkPolyData *iMeshNodes, GoFigureMeshAttributes *iMeshAttributes, int iTrackID) { OpenDBConnection(); if ( !this->m_MeshGenerationMode) { unsigned int TrackID = 0; if(iTrackID != -1) { TrackID = iTrackID; } else { TrackID = this->m_TraceSettingsWidget->GetCurrentSelectedCollectionID(); } //check that there isn't an existing mesh with the same timepoint in the // track,if so, set its trackID to 0: /** \todo print a different message if several meshes are created at the same timepoint*/ QString MessageToPrint = this->m_MeshesManager->CheckExistingMeshesForTheTrack(TrackID, this->m_DatabaseConnector, iTCoord); if ( MessageToPrint != "" ) { // remove old mesh from track average volume int kickedMeshID = MessageToPrint.toInt(); double volume = this->m_MeshesManager->GetVolume(kickedMeshID); this->m_TracksManager->AddVolume(TrackID, (-1)*volume); // write message MessageToPrint = tr( "Warning: existing mesh at this timepoint for this track !!The track of the mesh with the meshID %1 has been reassigned to 0") .arg(kickedMeshID); emit PrintMessage(MessageToPrint); } std::list MotherTrackDivisionToUpdate; MessageToPrint = this->m_TracksManager->CheckMeshCanBeAddedToTrack(this->m_DatabaseConnector, TrackID, *this->m_SelectedTimePoint, MotherTrackDivisionToUpdate).c_str(); unsigned int NewMeshID; if (!MessageToPrint.isEmpty() ) { emit PrintMessage(MessageToPrint); NewMeshID = this->m_MeshesManager->SaveNewMeshWithNoTrackFromVisu(iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, iTCoord, iMeshNodes, this->m_DatabaseConnector, iMeshAttributes); this->CloseDBConnection(); return; } NewMeshID = this->m_MeshesManager->SaveNewMeshFromVisu(iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, iTCoord, iMeshNodes, this->m_DatabaseConnector, iMeshAttributes, TrackID); std::list< unsigned int > ListNewMeshes; ListNewMeshes.push_back(NewMeshID); //here update the CurrentElement for trackContainer with the data from the // database corresponding to the selected trackID: // this->m_TracksManager->UpdateCurrentElementTrackContainer(TrackID); //update the bounding box and the visu for the tracks: std::list< unsigned int > trackIDs = this->m_MeshesManager->GetListCollectionIDs(this->m_DatabaseConnector, ListNewMeshes); // old nb of points in map track structure this->m_TracksManager->AddVolume(TrackID, iMeshAttributes->m_Volume); // new nb of point in map track structure this->m_TracksManager->UpdateBoundingBoxes(this->m_DatabaseConnector, trackIDs); if (!MotherTrackDivisionToUpdate.empty() ) { this->m_TracksManager->UpdateDivisions(MotherTrackDivisionToUpdate); } } else //for mesh generated from contours: { this->m_MeshesManager->SaveGeneratedMeshFromVisu(iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, iMeshNodes, this->m_DatabaseConnector, iMeshAttributes); //as the mesh is generated from contours, there is no TrackID associated. this->m_MeshGenerationMode = false; } CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SaveNewMeshForMeshToContours(int iNumberOfContours) { /*this->OpenDBConnection(); unsigned int TrackID = this->m_TraceWidget->GetCurrentSelectedCollectionID(); QString MessageToPrint = this->m_MeshesManager->CheckExistingMeshesForTheTrack(TrackID, this->m_DatabaseConnector); if ( MessageToPrint != "" ) { emit PrintMessage(MessageToPrint); } unsigned int MeshID = this->m_MeshesManager->CreateNewMeshWithNoContourNoPoints( this->m_DatabaseConnector); std::list< unsigned int > ListLastCreatedContours = this->m_ContoursManager->GetLastCreatedTracesIDs(this->m_DatabaseConnector, iNumberOfContours); this->AddCheckedTracesToCollection< QGoDBContourManager, QGoDBMeshManager >( this->m_ContoursManager, this->m_MeshesManager, MeshID, ListLastCreatedContours); std::list< unsigned int > ListNewMeshes; ListNewMeshes.push_back(MeshID); std::list< unsigned int > trackIDs = this->m_MeshesManager->GetListCollectionIDs(this->m_DatabaseConnector, ListNewMeshes); //here update the CurrentElement for trackContainer with the data from the // database corresponding to the selected trackID: //update the bounding box and the visu for the tracks: this->m_TracksManager->UpdateBoundingBoxes( this->m_DatabaseConnector, trackIDs); this->SetTSListCollectionID(); // need to reload the list of trackIDs as // normally, the new added mesh from create // mesh with no //contour will add the new meshid in the TSList... this->CloseDBConnection();*/ } //------------------------------------------------------------------------- //------------------------------------------------------------------------- unsigned int QGoPrintDatabase::SaveNewContourForMeshToContours( unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iTraceNodes) { /*this->OpenDBConnection(); unsigned int ContourID = this->m_ContoursManager->SaveNewContourFromVisu( iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, iTraceNodes, this->m_DatabaseConnector, 0); this->CloseDBConnection(); return ContourID;*/ return 0; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool QGoPrintDatabase::IsDatabaseUsed() { return m_IsDatabaseUsed; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list< QGoPrintDatabase::ItemColorComboboxData > QGoPrintDatabase::GetListCollectionIDFromDB(vtkMySQLDatabase *iDatabaseConnector, std::string & ioIDToSelect) { std::list< ItemColorComboboxData > EmptyList = std::list< ItemColorComboboxData >(); std::string TraceName = this->m_TraceSettingsWidget->GetTraceName(); if ( TraceName == "contour" ) { return this->m_MeshesManager->GetAllTraceIDsWithColor(iDatabaseConnector, ioIDToSelect); } if ( TraceName == "mesh" ) { return this->m_TracksManager->GetAllTraceIDsWithColor(iDatabaseConnector, ioIDToSelect); } return EmptyList; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SaveNewCollectionFromTraceWidgetInDBAndTW() { this->OpenDBConnection(); std::string TraceName = this->m_TraceSettingsWidget->GetTraceName(); if ( TraceName != "contour" && TraceName != "mesh" ) { return; } else { unsigned int NewCollectionID = 0; if ( TraceName == "contour" ) { NewCollectionID = this->m_MeshesManager->CreateNewMeshWithNoContourNoPoints( this->m_DatabaseConnector); } if ( TraceName == "mesh" ) { NewCollectionID = this->m_TracksManager->CreateNewTrackWithNoMesh( this->m_DatabaseConnector); } ItemColorComboboxData NewCollectionData; NewCollectionData.first = ConvertToString< unsigned int >(NewCollectionID); NewCollectionData.second = this->m_TraceSettingsWidget->GetPointerColorData()->second; } this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::AddBookmark(int iXCoord, int iYCoord, int iZCoord, int iTCoord) { GoDBCoordinateRow BookmarkCoord; BookmarkCoord.SetField< int >("XCoord", iXCoord); BookmarkCoord.SetField< int >("YCoord", iYCoord); BookmarkCoord.SetField< int >("ZCoord", iZCoord); BookmarkCoord.SetField< int >("TCoord", iTCoord); this->OpenDBConnection(); int BookmarkCoordID = BookmarkCoord.SaveInDB(this->m_DatabaseConnector); this->m_BookmarkManager->AddABookmark(BookmarkCoordID, this->m_DatabaseConnector); this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoPrintDatabase::NamesDescrContainerType QGoPrintDatabase::GetListBookmarks() { this->OpenDBConnection(); NamesDescrContainerType ListBookmarks = this->m_BookmarkManager->GetListExistingEntities(this->m_DatabaseConnector); this->CloseDBConnection(); return ListBookmarks; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- GoDBCoordinateRow QGoPrintDatabase::GetCoordinateForBookmark( std::string iName) { this->OpenDBConnection(); GoDBCoordinateRow Coord = this->m_BookmarkManager-> GetCoordinatesForBookmark(this->m_DatabaseConnector, iName); this->CloseDBConnection(); return Coord; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::DeleteBookmarks() { this->OpenDBConnection(); this->m_BookmarkManager->DeleteBookmark(this->m_DatabaseConnector); this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::UpdateSelectedTimePoint(int iTimePoint) { *this->m_SelectedTimePoint = iTimePoint; if ( !this->m_Server.empty() ) //if empty, the database variables are not //been set up yet. { if ( this->m_TraceSettingsWidget->GetTraceName() == "contour" ) { //if we change the timepoint, the list of meshes will be different from // the previous one, so, initialize the list is needed (no pre-selected // collection) this->SetTSListCollectionID(); this->m_ContoursManager->CheckShowRows(); } if ( this->m_TraceSettingsWidget->GetTraceName() == "mesh" ) { this->m_MeshesManager->CheckShowRows(); } } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::TheTraceHasChanged(int iIndex) { this->m_StackedTables->setCurrentIndex(iIndex); this->SetTSListCollectionID(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*void QGoPrintDatabase::SetTable(std::string iTablename) { int Index = 0; if ( iTablename == "mesh" ) { Index = 1; } if ( iTablename == "track" ) { Index = 2; } if ( iTablename == "lineage" ) { Index = 3; } this->m_StackedTables->setCurrentIndex(Index); }*/ //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::UpdateSelectedCollectionForTableWidget(std::string iTableName) { if ( iTableName == "contour" ) { this->m_MeshesManager->UpdateLastSelectedOneAsCollection(); } if ( iTableName == "mesh" ) { this->m_TracksManager->UpdateLastSelectedOneAsCollection(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::ExportContours() { QString p = QFileDialog::getSaveFileName( this, tr("Save Contour Export File"), "", tr("TextFile (*.txt)") ); if ( !p.isNull() ) { if ( !p.endsWith(".txt") ) { p.append( QString(".txt") ); } QFileInfo pathInfo(p); std::string filename = p.toStdString(); GoDBExport ExportHelper(this->m_Server, this->m_User, this->m_Password, this->m_ImgSessionID, filename); ExportHelper.ExportContours(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::ExportMeshes() { QString p = QFileDialog::getSaveFileName( this, tr("Save Contour Export File"), "", tr("TextFile (*.txt)") ); if ( !p.isNull() ) { if ( !p.endsWith(".txt") ) { p.append( QString(".txt") ); } QFileInfo pathInfo(p); std::string filename = p.toStdString(); GoDBExport ExportHelper(this->m_Server, this->m_User, this->m_Password, this->m_ImgSessionID, filename); ExportHelper.ExportMeshes(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::ImportContours() { QStringList p = QFileDialog::getOpenFileNames( this, tr("Open Contours Export File"), "", tr("TextFile (*.txt)") ); QStringList::Iterator it = p.begin(); //refactoring while ( it != p.end() ) { emit PrintMessage( tr("Warning: Close and reopen your imagingsession once the import is done !!") ); QFileInfo pathInfo(*it); std::string filename = (*it).toStdString(); //import into the database: GoDBImport ImportHelper(this->m_Server, this->m_User, this->m_Password, this->m_ImgSessionID, filename, *this->m_SelectedTimePoint); ImportHelper.ImportContours(); std::vector< int > NewContourIDs = ImportHelper.GetVectorNewContourIDs(); std::vector< int > NewMeshIDs = ImportHelper.GetVectorNewMeshIDs(); std::vector< int > NewTrackIDs = ImportHelper.GetVectorNewTracksIDs(); this->OpenDBConnection(); this->m_ContoursManager->UpdateTWAndContainerForImportedTraces(NewContourIDs, this->m_DatabaseConnector); this->m_MeshesManager->UpdateTWAndContainerForImportedTraces(NewMeshIDs, this->m_DatabaseConnector); this->m_TracksManager->UpdateTWAndContainerForImportedTraces(NewTrackIDs, this->m_DatabaseConnector); this->CloseDBConnection(); //as in the import contours file, there are data such as colors,celltype //and subcelltype, the lists may have been updated in the database: this->InitializeTheComboboxesNotTraceRelated(); ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::ImportMeshes() { QStringList p = QFileDialog::getOpenFileNames( this, tr("Open Meshes Export Files"), "", tr("TextFile (*.txt)") ); if( p.size() != 0 ) { emit PrintMessage( tr("Warning: Close and reopen your imagingsession once the import is done !!") ); } #if HAS_OPENMP #pragma omp for #endif for( int i = 0; i < p.size(); i++ ) { QFileInfo pathInfo( p[i] ); std::string filename = ( p[i] ).toStdString(); //import into the database: GoDBImport ImportHelper(this->m_Server, this->m_User, this->m_Password, this->m_ImgSessionID, filename, *this->m_SelectedTimePoint); ImportHelper.ImportMeshes(); // std::vector< int > NewMeshIDs = ImportHelper.GetVectorNewMeshIDs(); // std::vector< int > NewTrackIDs = ImportHelper.GetVectorNewTracksIDs(); // this->OpenDBConnection(); // this->m_MeshesManager->UpdateTWAndContainerForImportedTraces(NewMeshIDs, // this->m_DatabaseConnector); // this->m_TracksManager->UpdateTWAndContainerForImportedTraces(NewTrackIDs, // this->m_DatabaseConnector); // this->CloseDBConnection(); // this->InitializeTheComboboxesNotTraceRelated(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- std::vector< int > QGoPrintDatabase::ImportTracks() { QString p = QFileDialog::getOpenFileName( this, tr("Open Tracks Export File"), "", tr("TextFile (*.txt)") ); std::vector< int > NewTrackIDs = std::vector< int >(); if ( !p.isNull() ) { emit PrintMessage( tr("Warning: Close and reopen your imagingsession once the import is done !!") ); QFileInfo pathInfo(p); std::string filename = p.toStdString(); //import into the database: GoDBImport ImportHelper(this->m_Server, this->m_User, this->m_Password, this->m_ImgSessionID, filename, *this->m_SelectedTimePoint); ImportHelper.ImportTracks(); std::vector< int > NewMeshIDs = ImportHelper.GetVectorNewMeshIDs(); NewTrackIDs = ImportHelper.GetVectorNewTracksIDs(); this->OpenDBConnection(); this->m_MeshesManager->UpdateTWAndContainerForImportedTraces(NewMeshIDs, this->m_DatabaseConnector); this->m_TracksManager->UpdateTWAndContainerForImportedTraces(NewTrackIDs, this->m_DatabaseConnector); this->CloseDBConnection(); this->InitializeTheComboboxesNotTraceRelated(); } return NewTrackIDs; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- //******related to TraceManualEditingDockWidget:**************************** QGoTraceSettingsWidget * QGoPrintDatabase::GetTraceSettingsWidget() { return this->m_TraceSettingsWidget; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoTraceSettingsWidget* QGoPrintDatabase::GetTraceSettingsWidgetForToolBar() { return this->m_TraceSettingsWidgetForToolBar; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SetConnectionsBetweenTheInstancesOfTraceSettings() { this->m_TraceSettingsWidgetForToolBar = new QGoTraceSettingsWidget(this); this->m_TraceSettingsWidgetForToolBar->SetPointerCollectionData( this->m_TraceSettingsWidget->GetPointerCollectionData() ); this->m_TraceSettingsWidgetForToolBar->SetPointerColorData( this->m_TraceSettingsWidget->GetPointerColorData() ); this->m_TraceSettingsWidgetForToolBar->SetPointerSelectedCellType( this->m_TraceSettingsWidget->GetPointerSelectedCellType() ); this->m_TraceSettingsWidgetForToolBar->SetPointerSelectedSubCellType( this->m_TraceSettingsWidget->GetPointerSelectedSubCellType() ); QObject::connect(this->m_TraceSettingsWidget->m_SelectedTrace, SIGNAL(currentIndexChanged (int) ), this->m_TraceSettingsWidgetForToolBar->m_SelectedTrace, SLOT(setCurrentIndex(int) ) ); QObject::connect(this->m_TraceSettingsWidget->m_SelectedColorComboBox, SIGNAL(currentIndexChanged (int) ), this->m_TraceSettingsWidgetForToolBar->m_SelectedColorComboBox, SLOT(setCurrentIndex(int) ) ); QObject::connect(this->m_TraceSettingsWidget->m_ChoseCellType, SIGNAL(currentIndexChanged (int) ), this->m_TraceSettingsWidgetForToolBar->m_ChoseCellType, SLOT(setCurrentIndex(int) ) ); QObject::connect(this->m_TraceSettingsWidget->m_ChoseSubCellType, SIGNAL(currentIndexChanged (int) ), this->m_TraceSettingsWidgetForToolBar->m_ChoseSubCellType, SLOT(setCurrentIndex(int) ) ); QObject::connect(this->m_TraceSettingsWidget->m_CollectionColorComboBox, SIGNAL(currentIndexChanged (int) ), this->m_TraceSettingsWidgetForToolBar->m_CollectionColorComboBox, SLOT(setCurrentIndex(int) ) ); QObject::connect(this->m_TraceSettingsWidgetForToolBar->m_SelectedTrace, SIGNAL(currentIndexChanged (int) ), this->m_TraceSettingsWidget->m_SelectedTrace, SLOT(setCurrentIndex(int) ) ); QObject::connect(this->m_TraceSettingsWidgetForToolBar->m_SelectedColorComboBox, SIGNAL(currentIndexChanged (int) ), this->m_TraceSettingsWidget->m_SelectedColorComboBox, SLOT(setCurrentIndex(int) ) ); QObject::connect(this->m_TraceSettingsWidgetForToolBar->m_ChoseCellType, SIGNAL(currentIndexChanged (int) ), this->m_TraceSettingsWidget->m_ChoseCellType, SLOT(setCurrentIndex(int) ) ); QObject::connect(this->m_TraceSettingsWidgetForToolBar->m_ChoseSubCellType, SIGNAL(currentIndexChanged (int) ), this->m_TraceSettingsWidget->m_ChoseSubCellType, SLOT(setCurrentIndex(int) ) ); QObject::connect(this->m_TraceSettingsWidgetForToolBar->m_CollectionColorComboBox, SIGNAL(currentIndexChanged (int) ), this->m_TraceSettingsWidget->m_CollectionColorComboBox, SLOT(setCurrentIndex(int) ) ); QObject::connect(this->m_TraceSettingsWidget, SIGNAL( destroyed() ), this->m_TraceSettingsWidgetForToolBar, SLOT(SetSelectedPointersToNull() ) ); QObject::connect(this->m_TraceSettingsWidgetForToolBar, SIGNAL( destroyed() ), this->m_TraceSettingsWidget, SLOT(SetSelectedPointersToNull() ) ); QObject::connect( this, SIGNAL(topLevelChanged(bool) ), this, SLOT(ShowHideTraceSettingsFromContextMenu(bool) ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::CreateConnectionsForTraceSettingsWidget( QGoTraceSettingsWidget* iTraceSettingsWidget) { QObject::connect( iTraceSettingsWidget, SIGNAL( AddNewColor() ), this, SLOT( AddNewColor() ) ); QObject::connect( iTraceSettingsWidget, SIGNAL( DeleteColor() ), this, SLOT( DeleteColor() ) ); QObject::connect( iTraceSettingsWidget, SIGNAL( NewCollectionToBeCreated() ), this, SLOT( SaveNewCollectionFromTraceWidgetInDBAndTW() ) ); QObject::connect( iTraceSettingsWidget, SIGNAL( AddANewCellType() ), this, SLOT( AddNewCellType() ) ); QObject::connect( iTraceSettingsWidget, SIGNAL( AddANewSubCellType() ), this, SLOT( AddNewSubCellType() ) ); QObject::connect( iTraceSettingsWidget, SIGNAL( DeleteCellType() ), this, SLOT( DeleteCellType() ) ); QObject::connect( iTraceSettingsWidget, SIGNAL( DeleteSubCellType() ), this, SLOT( DeleteSubCellType() ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SetTraceNameForTableWidget(std::string iTraceName) { std::string PreviousTraceName = this->m_TraceSettingsWidget->GetTraceName(); if (PreviousTraceName != iTraceName) { this->UpdateSelectedCollectionForTableWidget(PreviousTraceName); this->m_TraceSettingsWidget->SetCurrentTraceName(iTraceName); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::InitializeTheComboboxesNotTraceRelated() { this->SetTSListColors(); this->SetTSListCellTypes(); this->SetTSListSubCellTypes(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SetTSListColors(std::string iNewColorToSelect) { this->OpenDBConnection(); this->blockSignals(true); this->m_TraceSettingsWidget->SetListColors( this->m_ColorManager->GetListExistingColors(this->m_DatabaseConnector), iNewColorToSelect); this->m_TraceSettingsWidgetForToolBar->SetListColors( this->m_ColorManager->GetListExistingColors(this->m_DatabaseConnector), iNewColorToSelect); this->blockSignals(false); this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SetTSListColorsWithPreviousSelectedOne() { this->OpenDBConnection(); this->m_TraceSettingsWidget->SetListColorsWithSelectedOne( this->m_ColorManager->GetListExistingColors(this->m_DatabaseConnector) ); this->m_TraceSettingsWidgetForToolBar->SetListColorsWithSelectedOne( this->m_ColorManager->GetListExistingColors(this->m_DatabaseConnector) ); this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SetTSListCollectionID() { //std::string TraceName = this->InWhichTableAreWe(); //if (TraceName == "contour" || TraceName == "mesh") // { this->OpenDBConnection(); std::string IDToSelect; std::list< ItemColorComboboxData > ListCollectionID = this->GetListCollectionIDFromDB(this->m_DatabaseConnector, IDToSelect); this->m_TraceSettingsWidget->SetListCollectionID(ListCollectionID, IDToSelect); this->m_TraceSettingsWidgetForToolBar->SetListCollectionID(ListCollectionID, IDToSelect); this->CloseDBConnection(); // } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SetTSListCellTypes(std::string iCellTypeToSelect) { this->OpenDBConnection(); this->m_TraceSettingsWidget->SetListCellTypes( this->m_CellTypeManager->GetListExistingEntities(this->m_DatabaseConnector), iCellTypeToSelect); this->m_TraceSettingsWidgetForToolBar->SetListCellTypes( this->m_CellTypeManager->GetListExistingEntities(this->m_DatabaseConnector), iCellTypeToSelect); this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SetTSListCellTypesWithPreviousSelectedOne() { this->OpenDBConnection(); this->m_TraceSettingsWidget->SetListCellTypeWithSelectedOne( this->m_CellTypeManager->GetListExistingEntities(this->m_DatabaseConnector) ); this->m_TraceSettingsWidgetForToolBar->SetListCellTypeWithSelectedOne( this->m_CellTypeManager->GetListExistingEntities(this->m_DatabaseConnector) ); this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SetTSListSubCellTypes(std::string iSubCellTypeToSelect) { this->OpenDBConnection(); this->m_TraceSettingsWidget->SetListSubCellTypes( this->m_SubCellTypeManager->GetListExistingEntities(this->m_DatabaseConnector), iSubCellTypeToSelect); this->m_TraceSettingsWidgetForToolBar->SetListSubCellTypes( this->m_SubCellTypeManager->GetListExistingEntities(this->m_DatabaseConnector), iSubCellTypeToSelect); this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::SetTSListSubCellTypesWithPreviousSelectedOne() { this->OpenDBConnection(); this->m_TraceSettingsWidget->SetListSubCellTypeWithSelectedOne( this->m_SubCellTypeManager->GetListExistingEntities(this->m_DatabaseConnector) ); this->m_TraceSettingsWidgetForToolBar->SetListSubCellTypeWithSelectedOne( this->m_SubCellTypeManager->GetListExistingEntities(this->m_DatabaseConnector) ); this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::AddNewCellType() { this->OpenDBConnection(); std::string NewCellType = this->m_CellTypeManager->AddAnEntity( this->m_DatabaseConnector); if ( !NewCellType.empty() ) { this->SetTSListCellTypes(NewCellType); } else //if the NewCellType is empty, go to the last selected one: { this->m_TraceSettingsWidget->SetCurrentCellTypeToSelectedOne(); this->m_TraceSettingsWidgetForToolBar->SetCurrentCellTypeToSelectedOne(); } this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::AddNewSubCellType() { this->OpenDBConnection(); std::string NewSubCellType = this->m_SubCellTypeManager->AddAnEntity(this->m_DatabaseConnector); if ( !NewSubCellType.empty() ) { this->SetTSListSubCellTypes(NewSubCellType); } else //if the NewSubCellType is empty, go to the last selected one: { this->m_TraceSettingsWidget->SetCurrentSubCellTypeToSelectedOne(); this->m_TraceSettingsWidgetForToolBar->SetCurrentSubCellTypeToSelectedOne(); } this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::AddNewColor() { this->OpenDBConnection(); ItemColorComboboxData NewColor = this->m_ColorManager->AddANewColor( this->m_DatabaseConnector); if ( !NewColor.first.empty() ) { this->SetTSListColors(NewColor.first); } else //if the NewColor name is empty, go to the last selected one: { this->m_TraceSettingsWidget->SetCurrentColorToSelectedOne(); this->m_TraceSettingsWidgetForToolBar->SetCurrentColorToSelectedOne(); } this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::DeleteCellType() { this->OpenDBConnection(); if ( this->m_CellTypeManager->DeleteEntity(this->m_DatabaseConnector) ) { this->SetTSListCellTypesWithPreviousSelectedOne(); } else //if the user cancelled, go to the last selected one: { this->m_TraceSettingsWidget->SetCurrentCellTypeToSelectedOne(); this->m_TraceSettingsWidgetForToolBar->SetCurrentCellTypeToSelectedOne(); } this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::DeleteColor() { this->OpenDBConnection(); if ( this->m_ColorManager->DeleteEntity(this->m_DatabaseConnector) ) { this->SetTSListColorsWithPreviousSelectedOne(); } else //if the user cancelled, go to the last selected one: { this->m_TraceSettingsWidget->SetCurrentColorToSelectedOne(); this->m_TraceSettingsWidgetForToolBar->SetCurrentColorToSelectedOne(); } this->CloseDBConnection(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::DeleteSubCellType() { this->OpenDBConnection(); if ( this->m_SubCellTypeManager->DeleteEntity(this->m_DatabaseConnector) ) { this->SetTSListSubCellTypesWithPreviousSelectedOne(); } else //if the user cancelled, go to the last selected one: { this->m_TraceSettingsWidget->SetCurrentSubCellTypeToSelectedOne(); this->m_TraceSettingsWidgetForToolBar->SetCurrentSubCellTypeToSelectedOne(); } this->CloseDBConnection(); } //*********************RELATED TO QGODBTRACEMANAGER************************** void QGoPrintDatabase::GetContentAndDisplayAllTracesInfo( vtkMySQLDatabase *iDatabaseConnector) { this->m_ContoursManager->DisplayInfoAndLoadVisuContainerForAllContours( iDatabaseConnector); this->m_MeshesManager->DisplayInfoAndLoadVisuContainerForAllMeshes( iDatabaseConnector); this->m_TracksManager->DisplayInfoAndLoadVisuContainerForAllTracks( iDatabaseConnector); this->m_TracksManager->LoadInfoVisuContainerForTrackFamilies(iDatabaseConnector); this->m_LineagesManager->DisplayInfoAndLoadVisuContainerForAllLineages( iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::GetContentAndDisplayAllTracesInfoFor3TPs( vtkMySQLDatabase *iDatabaseConnector) { m_VisibleTimePoints.clear(); if(*this->m_SelectedTimePoint>0) { m_VisibleTimePoints.push_back(*this->m_SelectedTimePoint-1); } m_VisibleTimePoints.push_back(*this->m_SelectedTimePoint); m_VisibleTimePoints.push_back(*this->m_SelectedTimePoint+1); this->m_ContoursManager-> DisplayInfoAndLoadVisuContainerForAllContoursForSpecificTPs( iDatabaseConnector, m_VisibleTimePoints); this->m_MeshesManager-> DisplayInfoAndLoadVisuContainerForAllMeshesForSpecificTPs(iDatabaseConnector, m_VisibleTimePoints); this->m_TracksManager->DisplayInfoAndLoadVisuContainerForAllTracks( iDatabaseConnector); this->m_TracksManager->LoadInfoVisuContainerForTrackFamilies(iDatabaseConnector); this->m_LineagesManager->DisplayInfoAndLoadVisuContainerForAllLineages( iDatabaseConnector); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::RemoveTracesFromListTimePoints( vtkMySQLDatabase *iDatabaseConnector, std::list iListTimePoints) { this->m_ContoursManager->RemoveTracesFromTWAndContainerForVisuForSpecificTPs( iDatabaseConnector, iListTimePoints); this->m_MeshesManager->RemoveTracesFromTWAndContainerForVisuForSpecificTPs( iDatabaseConnector, iListTimePoints); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::CreateContextMenu(const QPoint & iPos) { QMenu *ContextMenu = new QMenu; QAction *TraceSettings = new QAction(tr("TraceSettings"), ContextMenu); TraceSettings->setCheckable(true); TraceSettings->setChecked(this->m_TraceSettingsVisible); QObject::connect( TraceSettings, SIGNAL( triggered (bool) ), this, SLOT( ShowHideTraceSettingsFromContextMenu(bool) ) ); ContextMenu->addAction(TraceSettings); ContextMenu->exec( this->mapToGlobal(iPos) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::DeleteCheckedContours() { this->DeleteCheckedTraces< QGoDBContourManager, QGoDBMeshManager, QGoDBContourManager >( this->m_ContoursManager, this->m_MeshesManager, this->m_ContoursManager); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::DeleteCheckedMeshes() { // upade average mesh volume over a track // get IDs std::list< std::pair > temp_list = this->m_MeshesManager->GetListVolumes(); // update tracks volumes this->m_TracksManager->RemoveVolumes(temp_list); this->DeleteCheckedTraces< QGoDBMeshManager, QGoDBTrackManager, QGoDBContourManager >( this->m_MeshesManager, this->m_TracksManager, this->m_ContoursManager); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::DeleteCheckedTracks() { this->DeleteCheckedTraces< QGoDBTrackManager, QGoDBLineageManager, QGoDBMeshManager >( this->m_TracksManager, this->m_LineagesManager, this->m_MeshesManager); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::DeleteCheckedLineages() { this->DeleteCheckedTraces< QGoDBLineageManager, QGoDBLineageManager, QGoDBTrackManager >( this->m_LineagesManager, this->m_LineagesManager, this->m_TracksManager, true); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::ChangeMeshColor() { this->ChangeTraceColor< QGoDBMeshManager, QGoDBContourManager >( this->m_MeshesManager, this->m_ContoursManager); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::ChangeTrackColor() { this->ChangeTraceColor< QGoDBTrackManager, QGoDBMeshManager >( this->m_TracksManager, this->m_MeshesManager); } //------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::ChangeLineageColor() { this->ChangeTraceColor< QGoDBLineageManager, QGoDBTrackManager >( this->m_LineagesManager, this->m_TracksManager); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoPrintDatabase::PrintVolumeAreaForMesh(GoFigureMeshAttributes * iMeshAttributes, unsigned int iMeshID) { this->m_MeshesManager->DisplayOnlyVolumeAreaForExistingMesh( iMeshAttributes, iMeshID); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::PrintCalculatedValuesForTrack(GoFigureTrackAttributes * iTrackAttributes, unsigned int iTrackID) { // straight forward values from track polydata this->m_TracksManager->DisplayOnlyCalculatedValuesForExistingTrack( iTrackAttributes, iTrackID); // other values from mesh // do sth for the average volume // do everything here but should be optimized later on // calculate average volume //std::list< std::pair > list =this->m_MeshesManager->GetAverageVolumePerTrack(); //modify structure (which will update table!) //this->m_TracksManager->SetAverageVolumePerTrack(list); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SetContoursContainer(ContourContainer *iContainer) { this->m_ContoursManager->SetContoursInfoContainerForVisu(iContainer); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SetMeshesContainer(MeshContainer *iContainer) { this->m_MeshesManager->SetMeshesInfoContainerForVisu(iContainer); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SetTracksContainer(TrackContainer *iContainer) { this->m_TracksManager->SetTracksInfoContainerForVisu(iContainer); QObject::connect( this->m_TracksManager, SIGNAL ( NeedMeshesInfoForImportedTrack(unsigned int) ), this, SLOT ( PassMeshesInfoForImportedTrack(unsigned int) ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SetLineagesContainers(LineageContainer *iContainer, TrackContainer *iTrackContainer) { this->m_LineagesManager->SetLineagesInfoContainersForVisu(iContainer, iTrackContainer); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SetTracesManager() { this->SetContoursManager(); this->SetMeshesManager(); this->SetTracksManager(); this->SetLineagesManager(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SetContoursManager() { this->m_ContoursManager = new QGoDBContourManager(m_ImgSessionID, this); this->m_ContoursManager->SetSelectedCollection ( this->m_TraceSettingsWidget->GetPointerCollectionData() ); QObject::connect( this->m_ContoursManager, SIGNAL( NeedToGetDatabaseConnection() ), this, SLOT( PassDBConnectionToContoursManager() ) ); QObject::connect( this->m_ContoursManager, SIGNAL( CheckedTracesToDelete() ), this, SLOT( DeleteCheckedContours() ) ); QObject::connect( this->m_ContoursManager, SIGNAL( NeedToGoToTheLocation(int, int, int, int) ), this, SIGNAL( NeedToGoToTheLocation(int, int, int, int) ) ); QObject::connect( this->m_ContoursManager, SIGNAL( TraceToReEdit(unsigned int) ), this, SLOT( ReEditTrace(unsigned int) ) ); QObject::connect( this->m_ContoursManager, SIGNAL( NewCollectionFromCheckedTraces(std::list< unsigned int > ) ), this, SLOT( CreateNewMeshFromCheckedContours(std::list< unsigned int > ) ) ); QObject::connect( this->m_ContoursManager, SIGNAL( CheckedTracesToAddToSelectedCollection( std::list< unsigned int > ) ), this, SLOT( AddCheckedContoursToSelectedMesh(std::list< unsigned int > ) ) ); QObject::connect( this->m_ContoursManager, SIGNAL( DBConnectionNotNeededAnymore() ), this, SLOT( CloseDBConnection() ) ); QObject::connect( this->m_ContoursManager, SIGNAL( PrintMessage(QString, int) ), this, SIGNAL( PrintMessage(QString, int) ) ); this->m_ContoursManager->SetSelectedCollection( this->m_TraceSettingsWidget->GetPointerCollectionData() ); this->m_ContoursManager->SetCurrentTimePoint(this->m_SelectedTimePoint); this->m_ContoursManager->SetSelectedColor( this->m_TraceSettingsWidget->GetPointerColorData() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SetMeshesManager() { this->m_MeshesManager = new QGoDBMeshManager(m_ImgSessionID, this); QObject::connect( this->m_MeshesManager, SIGNAL( NeedToGetDatabaseConnection() ), this, SLOT( PassDBConnectionToMeshesManager() ) ); QObject::connect( this->m_MeshesManager, SIGNAL( TraceColorToChange() ), this, SLOT( ChangeMeshColor() ) ); QObject::connect( this->m_MeshesManager, SIGNAL( CheckedTracesToDelete() ), this, SLOT( DeleteCheckedMeshes() ) ); QObject::connect( this->m_MeshesManager, SIGNAL( NeedToGoToTheLocation(int, int, int, int) ), this, SIGNAL( NeedToGoToTheLocation(int, int, int, int) ) ); QObject::connect( this->m_MeshesManager, SIGNAL ( NewCollectionFromCheckedTraces(std::list< unsigned int > ) ), this, SLOT( CreateNewTrackFromListMeshes(std::list< unsigned int > ) ) ); QObject::connect( this->m_MeshesManager, SIGNAL( CheckedTracesToAddToSelectedCollection( std::list< unsigned int > ) ), this, SLOT( AddCheckedMeshesToSelectedTrack(std::list< unsigned int > ) ) ); QObject::connect( this->m_MeshesManager, SIGNAL( DBConnectionNotNeededAnymore() ), this, SLOT( CloseDBConnection() ) ); QObject::connect( this->m_MeshesManager, SIGNAL( AddNewTraceIDInTS(std::pair< std::string, QColor > ) ), this->m_TraceSettingsWidget, SLOT( AddANewCollectionID(std::pair< std::string, QColor > ) ) ); QObject::connect( this->m_MeshesManager, SIGNAL( AddNewTraceIDInTS(std::pair< std::string, QColor > ) ), this->m_TraceSettingsWidgetForToolBar, SLOT( AddANewCollectionID(std::pair< std::string, QColor > ) ) ); QObject::connect( this->m_MeshesManager, SIGNAL( PrintMessage(QString, int) ), this, SIGNAL( PrintMessage(QString, int) ) ); //related to traceEditingWidget and meshes_manager (celltype + subcelltype + // collectionData + colordata): this->m_MeshesManager->SetSelectedCollection ( this->m_TraceSettingsWidget->GetPointerCollectionData() ); this->m_MeshesManager->SetSelectedCellType( this->m_TraceSettingsWidget->GetPointerSelectedCellType() ); this->m_MeshesManager->SetSelectedSubCellType( this->m_TraceSettingsWidget->GetPointerSelectedSubCellType() ); this->m_MeshesManager->SetCurrentTimePoint(this->m_SelectedTimePoint); this->m_MeshesManager->SetSelectedColor( this->m_TraceSettingsWidget->GetPointerColorData() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SetTracksManager() { this->m_TracksManager = new QGoDBTrackManager(m_ImgSessionID, this); QObject::connect( this->m_TracksManager, SIGNAL( TraceColorToChange() ), this, SLOT( ChangeTrackColor() ) ); QObject::connect( this->m_TracksManager, SIGNAL( CheckedTracesToDelete() ), this, SLOT( DeleteCheckedTracks() ) ); QObject::connect( this->m_TracksManager, SIGNAL( NeedToGetDatabaseConnection() ), this, SLOT( PassDBConnectionToTracksManager() ) ); QObject::connect( this->m_TracksManager, SIGNAL( NeedToGoToTheRealLocation(double, double, double, int) ), this, SIGNAL( NeedToGoToTheRealLocation(double, double, double, int) ) ); QObject::connect( this->m_TracksManager, SIGNAL( DBConnectionNotNeededAnymore() ), this, SLOT( CloseDBConnection() ) ); QObject::connect( this->m_TracksManager, SIGNAL( NeedToGetDatabaseConnection() ), this, SLOT( PassDBConnectionToTracksManager() ) ); QObject::connect( this->m_TracksManager, SIGNAL( DBConnectionNotNeededAnymore() ), this, SLOT( CloseDBConnection() ) ); QObject::connect( this->m_TracksManager, SIGNAL( TrackToSplit(unsigned int, std::list< unsigned int > ) ), this, SLOT( SplitTheTrack(unsigned int, std::list< unsigned int > ) ) ); QObject::connect( this->m_TracksManager, SIGNAL( TrackIDToBeModifiedWithWidget(std::list< unsigned int > ) ), this, SLOT( SplitMergeTracksWithWidget(std::list< unsigned int > ) ) ); QObject::connect( this->m_TracksManager, SIGNAL( MeshesToAddToTrack(std::list< unsigned int >, unsigned int) ), this, SLOT( AddListMeshesToATrack(std::list< unsigned int >, unsigned int) ) ); QObject::connect( this->m_TracksManager, SIGNAL( AddNewTraceIDInTS(std::pair< std::string, QColor > ) ), this->m_TraceSettingsWidget, SLOT( AddANewCollectionID(std::pair< std::string, QColor > ) ) ); QObject::connect( this->m_TracksManager, SIGNAL( AddNewTraceIDInTS(std::pair< std::string, QColor > ) ), this->m_TraceSettingsWidgetForToolBar, SLOT( AddANewCollectionID(std::pair< std::string, QColor > ) ) ); QObject::connect( this->m_TracksManager, SIGNAL( PrintMessage(QString, int) ), this, SIGNAL( PrintMessage(QString, int) ) ); QObject::connect(this->m_TracksManager, SIGNAL(CheckedTracksToAddToSelectedLineage( std::list< unsigned int >, unsigned int, std::list ) ), this, SLOT( AddCheckedTracksToSelectedLineage(std::list< unsigned int >, unsigned int, std::list ) ) ); QObject::connect( this->m_TracksManager, SIGNAL ( NewLineageToCreateFromTracks( std::list, unsigned int, std::list )), this, SLOT( CreateNewLineageFromTracks(std::list< unsigned int >, unsigned int, std::list ) ) ); this->m_TracksManager->SetSelectedCollection( this->m_TraceSettingsWidget->GetPointerCollectionData() ); this->m_TracksManager->SetSelectedColor( this->m_TraceSettingsWidget->GetPointerColorData() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SetLineagesManager() { this->m_LineagesManager = new QGoDBLineageManager(m_ImgSessionID, this); QObject::connect( this->m_LineagesManager, SIGNAL( NeedToGetDatabaseConnection() ), this, SLOT( PassDBConnectionToLineagesManager() ) ); QObject::connect( this->m_LineagesManager, SIGNAL( DBConnectionNotNeededAnymore() ), this, SLOT( CloseDBConnection() ) ); QObject::connect( this->m_LineagesManager, SIGNAL( CheckedTracesToDelete() ), this, SLOT( DeleteCheckedLineages() ) ); /* \todo Nicolas - change color */ QObject::connect( this->m_LineagesManager, SIGNAL( TraceColorToChange() ), this, SLOT( ChangeLineageColor() ) ); this->m_LineagesManager->SetSelectedColor( this->m_TraceSettingsWidget->GetPointerColorData() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::PassDBConnectionToContoursManager() { this->OpenDBConnection(); this->m_ContoursManager->SetDatabaseConnection(this->m_DatabaseConnector); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::PassDBConnectionToMeshesManager() { this->OpenDBConnection(); this->m_MeshesManager->SetDatabaseConnection(this->m_DatabaseConnector); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::PassDBConnectionToTracksManager() { this->OpenDBConnection(); this->m_TracksManager->SetDatabaseConnection(this->m_DatabaseConnector); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::PassDBConnectionToLineagesManager() { this->OpenDBConnection(); this->m_LineagesManager->SetDatabaseConnection(this->m_DatabaseConnector); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::ReEditTrace(unsigned int iTraceID) { this->m_ReeditMode = true; emit TraceToReEdit(iTraceID); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::PassMeshesInfoForImportedTrack(unsigned int iTrackID) { std::list< unsigned int > TrackIDs; TrackIDs.push_back(iTrackID); this->OpenDBConnection(); //get the meshesID that have iTrackID as a collectionID: std::list< unsigned int > ListMeshesIDs = this->m_TracksManager->GetListTracesIDsFromThisCollectionOf( this->m_DatabaseConnector, TrackIDs); if ( !ListMeshesIDs.empty() ) { //get the coordinate info from the meshes: std::map< unsigned int, double * > MeshesInfo = this->m_MeshesManager-> GetMeshesInfoForImportedMesh(ListMeshesIDs); if ( !MeshesInfo.empty() ) { //pass the coordinate info from the meshes in order to calculate the //points/string of the track: this->m_TracksManager->UpdatePointsOfCurrentElementForImportedTrack( MeshesInfo, this->m_DatabaseConnector); } } this->CloseDBConnection(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SplitTheTrack(unsigned int iTrackID, std::list< unsigned int > iListMeshIDs) { this->OpenDBConnection(); std::list< unsigned int > ListMeshesForNewTrack = this->m_MeshesManager->GetMeshesWithTimePointInfToTheCheckedOne( iTrackID, this->m_DatabaseConnector, iListMeshIDs); if(ListMeshesForNewTrack.size() != 0) { this->CreateNewTrackFromListMeshes(ListMeshesForNewTrack); } this->CloseDBConnection(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::CreateNewTrackFromListMeshes( std::list< unsigned int > iListCheckedMeshes) { this->OpenDBConnection(); unsigned int NewTrackID = this->m_TracksManager->CreateNewTrackWithNoMesh( this->m_DatabaseConnector); std::list< std::pair > temp; std::list< unsigned int > ListMeshToBelongToTheTrack; std::list< unsigned int > ListMeshToReassign; std::string MessageToPrint = this->m_MeshesManager->CheckListMeshesFromDifferentTimePoints( this->m_DatabaseConnector, iListCheckedMeshes, ListMeshToBelongToTheTrack, ListMeshToReassign); // remove all meshes from previous track avg_volume, from mesh ID temp = this->m_MeshesManager->GetListVolumes(ListMeshToBelongToTheTrack); // update tracks volumes // do remove add at same time? this->m_TracksManager->RemoveVolumes(temp); // strategy: // 1-delete previous division // 2-create new track // 3-create new division // therefore we ensure to have a correct lineage tree // Get old track mother and 2 daughters from database unsigned int oldMotherID = 0; unsigned int oldTrackID = 0; unsigned int newTrackID = NewTrackID; unsigned int oldDaughter = 0; std::list< std::pair >::const_iterator it = temp.begin(); if(it != temp.end()) { oldTrackID = (*it).first; } // get track family from daughter std::vector family = this->m_TracksManager->GetTrackFamily(this->m_DatabaseConnector, oldTrackID); // if track belongs to a lineage if(family.size() > 0) { oldMotherID = family[1]; if(family[2] == oldTrackID) { oldDaughter = family[3]; } else { oldDaughter = family[2]; } // Delete old track mother division std::list oldList; oldList.push_back(oldMotherID); this->m_TracksManager->DeleteTheDivisions(oldList); } //at that moment, do nothing for the checked meshes not selected to be part of // the track if ( MessageToPrint != "" ) { emit PrintMessage( MessageToPrint.c_str() ); } // remove all meshes from previous track avg_volume, from mesh ID //temp = this->m_MeshesManager->GetListVolumes(ListMeshToBelongToTheTrack); // update tracks volumes this->m_TracksManager->AddVolumes(temp, NewTrackID); this->AddCheckedTracesToCollection< QGoDBMeshManager, QGoDBTrackManager >( this->m_MeshesManager, this->m_TracksManager, NewTrackID, ListMeshToBelongToTheTrack); // if track belongs to a lineage if(family.size() > 0) { // Create division old mother and new daughter std::list newdaughter; newdaughter.push_back(oldMotherID); newdaughter.push_back(oldDaughter); newdaughter.push_back(newTrackID); this->m_TracksManager->CreateCorrespondingTrackFamily(newdaughter); } this->CloseDBConnection(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::CreateNewTrackFromListMeshes( std::list< std::list< unsigned int > > iListsCheckedMeshes) { std::list< std::list< unsigned int > >::iterator iter = iListsCheckedMeshes.begin(); while ( iter != iListsCheckedMeshes.end() ) { CreateNewTrackFromListMeshes(*iter); ++iter; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::CreateNewMeshFromCheckedContours( std::list< unsigned int > iListCheckedContours) { this->OpenDBConnection(); unsigned int NewMeshID = this->m_MeshesManager->CreateNewMeshWithNoContourNoPoints( this->m_DatabaseConnector); this->AddCheckedTracesToCollection< QGoDBContourManager, QGoDBMeshManager >( this->m_ContoursManager, this->m_MeshesManager, NewMeshID, iListCheckedContours); this->m_MeshGenerationMode = true; emit NewMeshToGenerate(iListCheckedContours, NewMeshID); this->CloseDBConnection(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::CreateNewLineageFromTracks( std::list< unsigned int > iListCheckedTracks, unsigned int iTrackRoot, std::list< unsigned int > iListLineagesToDelete) { this->OpenDBConnection(); unsigned int NewLineageID = this->m_LineagesManager->CreateNewLineageWithTrackRoot( this->m_DatabaseConnector, iTrackRoot); this->AddCheckedTracksToSelectedLineage (iListCheckedTracks, NewLineageID, iListLineagesToDelete); this->CloseDBConnection(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::AddCheckedContoursToSelectedMesh(std::list< unsigned int > iListCheckedContours) { this->OpenDBConnection(); this->AddCheckedTracesToCollection< QGoDBContourManager, QGoDBMeshManager > (this->m_ContoursManager, this->m_MeshesManager, this->m_TraceSettingsWidget->GetCurrentSelectedCollectionID(), iListCheckedContours); this->CloseDBConnection(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase:: AddListMeshesToATrack(std::list< unsigned int > iListMeshes, unsigned int iTrackID) { this->OpenDBConnection(); std::list< unsigned int > ListMeshToBelongToTheTrack; std::list< unsigned int > ListNullMeshToBelongToTheTrack; std::list< std::pair > temp; if ( iTrackID == 0 ) { ListMeshToBelongToTheTrack = iListMeshes; } else { // list the meshes which will not be moved // i.e. if we try to move 2 points belonging to T0, // the smallest ID will not move std::list< unsigned int > ListMeshToReassign; std::string MessageToPrint = this->m_MeshesManager->CheckListMeshesFromDifferentTimePoints( this->m_DatabaseConnector, iListMeshes, ListMeshToBelongToTheTrack, ListMeshToReassign); // remove all meshes from previous track avg_volume, from mesh ID temp = this->m_MeshesManager->GetListVolumes(ListMeshToBelongToTheTrack); // update tracks volumes this->m_TracksManager->RemoveVolumes(temp); // if there is already a mesh at the same time point in the track, // change the mesh's track id to 0 MessageToPrint += this->m_MeshesManager->CheckExistingMeshesForTheTrack( iTrackID, this->m_DatabaseConnector, ListMeshToBelongToTheTrack, ListNullMeshToBelongToTheTrack).toStdString(); // remove meshes assigned to 0 temp = this->m_MeshesManager->GetListVolumes(ListNullMeshToBelongToTheTrack); this->m_TracksManager->RemoveVolumes(temp, iTrackID); // add meshes to next track average volume, from Mesh ID temp = this->m_MeshesManager->GetListVolumes(ListMeshToBelongToTheTrack); this->m_TracksManager->AddVolumes(temp, iTrackID); if ( MessageToPrint != "" ) { emit PrintMessage( MessageToPrint.c_str() ); } } // assign meshes to the track since we have cleaned the track now this->AddCheckedTracesToCollection< QGoDBMeshManager, QGoDBTrackManager >( this->m_MeshesManager, this->m_TracksManager, iTrackID, ListMeshToBelongToTheTrack); // update the visualization container! this->m_MeshesManager->ModifyTrackIDInVisuContainer(iTrackID, ListMeshToBelongToTheTrack, ListNullMeshToBelongToTheTrack); this->CloseDBConnection(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::AddListMeshesToATrack( std::map< unsigned int, std::list< unsigned int > > iListMeshesWithTracks) { std::map< unsigned int, std::list< unsigned int > >::iterator iter = iListMeshesWithTracks.begin(); while ( iter != iListMeshesWithTracks.end() ) { AddListMeshesToATrack(iter->second, iter->first); ++iter; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::AddCheckedMeshesToSelectedTrack(std::list< unsigned int > iListCheckedMeshes) { unsigned int SelectedTrackID = this->m_TraceSettingsWidget->GetCurrentSelectedCollectionID(); this->AddListMeshesToATrack(iListCheckedMeshes, SelectedTrackID); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::SplitMergeTracksWithWidget( std::list< unsigned int > iTrackIDs) { this->OpenDBConnection(); MeshContainer *MeshContainerTemp = this->m_MeshesManager-> GetMeshesInfoFromDBAndCreateContainerForVisu( this->m_DatabaseConnector, iTrackIDs); QGoTrackEditingWidget *win = new QGoTrackEditingWidget(MeshContainerTemp); win->init(); if ( win->exec() ) { std::list< std::list< unsigned int > > ListTracksToCreate = win->GetListOfTracksToBeCreated(); std::map< unsigned int, std::list< unsigned int > > ListTracksToUpdate = win->GetListOfTracksToBeUpdated(); //std::list< unsigned int > ListTracksToDelete = // win->GetListOfTracksToBeDeleted(); if ( !ListTracksToCreate.empty() ) { this->CreateNewTrackFromListMeshes(ListTracksToCreate); } if ( !ListTracksToUpdate.empty() ) { this->AddListMeshesToATrack(ListTracksToUpdate); } /*if ( !ListTracksToDelete.empty() ) { this->DeleteListTraces< QGoDBTrackManager, QGoDBMeshManager, QGoDBMeshManager >( this->m_TracksManager, this->m_MeshesManager, this->m_MeshesManager, ListTracksToDelete); }*/ } delete win; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::AddCheckedTracksToSelectedLineage( std::list iListDaughters, unsigned int iLineageID, std::list iListLineagesToDelete) { if (!iListLineagesToDelete.empty() ) { this->DeleteListTraces< QGoDBLineageManager, QGoDBLineageManager > ( this->m_LineagesManager, this->m_LineagesManager, this->m_TracksManager, iListLineagesToDelete, true); } if (!iListDaughters.empty() ) { this->OpenDBConnection(); this->AddCheckedTracesToCollection< QGoDBTrackManager, QGoDBLineageManager >( this->m_TracksManager, this->m_LineagesManager, iLineageID, iListDaughters); this->CloseDBConnection(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoPrintDatabase::ShowHideTraceSettingsFromContextMenu(bool isVisible) { this->m_TraceSettingsWidget->setVisible(isVisible); this->m_TraceSettingsVisible = isVisible; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool QGoPrintDatabase::NeedTraceSettingsToolBarVisible() { if (!this->isVisible() ) { return true; } if(this->isFloating()) { return false; } return !this->m_TraceSettingsVisible; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::list QGoPrintDatabase:: UpdateTableWidgetAndContainersForGivenTimePoint( const unsigned int& iNewTimePoint) { this->OpenDBConnection(); if(this->m_VisibleTimePoints.size() > 0) { // list to be removed std::list listToRemove; listToRemove = m_VisibleTimePoints; // iterator std::list::iterator it_listToRemove = listToRemove.begin(); // list to be added std::list listToAdd; if(iNewTimePoint>0) { listToAdd.push_back(iNewTimePoint-1); } listToAdd.push_back(iNewTimePoint); listToAdd.push_back(iNewTimePoint+1); // iterator std::list::iterator it_listToAdd = listToAdd.begin(); m_VisibleTimePoints = listToAdd; // list common t points std::list listCommonT; while(it_listToRemove != listToRemove.end()) { while(it_listToAdd != listToAdd.end()) { if(*it_listToRemove == *it_listToAdd) { /** \todo check if we can do it properly // remove elements from a list while iterating on it doesn't sound safe // that's why we use listCommonT // To be checked */ listCommonT.push_back(*it_listToRemove); } ++it_listToAdd; } it_listToAdd = listToAdd.begin(); ++it_listToRemove; } // remove common t points // iterator std::list::iterator it_listCommonT = listCommonT.begin(); while(it_listCommonT != listCommonT.end()) { listToRemove.remove(*it_listCommonT); listToAdd.remove(*it_listCommonT); ++it_listCommonT; } // remove time points if(listToRemove.size() > 0) { this->m_ContoursManager->CleanTWAndContainerForGivenTimePoint( this->m_DatabaseConnector, listToRemove); this->m_MeshesManager->CleanTWAndContainerForGivenTimePoint( this->m_DatabaseConnector, listToRemove); } // add time points if(listToAdd.size() > 0) { this->m_ContoursManager-> DisplayInfoAndLoadVisuContainerForAllContoursForSpecificTPs( this->m_DatabaseConnector, listToAdd); this->m_MeshesManager-> DisplayInfoAndLoadVisuContainerForAllMeshesForSpecificTPs( this->m_DatabaseConnector, listToAdd); } this->CloseDBConnection(); return listToAdd; } return this->m_VisibleTimePoints; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::list QGoPrintDatabase:: GetVisibleTimePoints() { return m_VisibleTimePoints; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- int QGoPrintDatabase:: GetNumberOfElementForTraceAndTimePoint(std::string iTrace, int iTimePoint) { this->OpenDBConnection(); int test = NumberOfElementForGivenImagingSessionAndTraceForGivenTimePoint( this->m_DatabaseConnector, this->m_ImgSessionID, iTrace, iTimePoint); this->CloseDBConnection(); return test; } GoFigure2-v0.9.0/Code/GUI/lib/QGoCreateMeshDialog.h0000644000175000017500000000613611667757442021366 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoCreateMeshDialog_h #define __QGoCreateMeshDialog_h #include #include #include #include #include #include #include "QGoGUILibConfigure.h" class QGOGUILIB_EXPORT QGoCreateMeshDialog:public QDialog { Q_OBJECT public: explicit QGoCreateMeshDialog(QWidget *parent = 0); virtual ~QGoCreateMeshDialog(); public slots: // void ChangeLookupTable( const int& ); protected: QDialogButtonBox *ButtonBox; /*QVBoxLayout* VLayoutLabel; QVBoxLayout* VLayoutCombobox; QVBoxLayout* VLayoutDescription; QHBoxLayout* HorizontalLayout;*/ QGridLayout *GridLayout; QSpacerItem *HorizontalSpacer; QLabel * LineCellType; QLabel * LineSubCellType; QLabel * LineColor; QComboBox * SelectCellType; QComboBox * SelectSubCellType; QComboBox * SelectColor; //QTextEdit* DescriptionCell; //QTextEdit* DescriptionSubCell; //QTextEdit* DescriptionColor; QLineEdit * DescriptionCell; QLineEdit * DescriptionSubCell; QLineEdit * DescriptionColor; QScrollArea *ScrollDescrCell; QScrollArea *ScrollDescrSubCell; QScrollArea *ScrollDescrColor; QPushButton *OkButton; QPushButton *CancelButton; QPushButton *NewCellType; QPushButton *NewSubCellType; QPushButton *NewColor; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoColorCodingDialog.h0000644000175000017500000000717711667757442021556 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoColorCodingDialog_h #define __QGoColorCodingDialog_h #include #include #include #include "QGoGUILibConfigure.h" #include "QGoLUTDialog.h" /** \class QGoColorCodingDialog \brief This dialog asks the user to chose the way he wants its traces to be colorcoded \ingroup GUI */ class QGOGUILIB_EXPORT QGoColorCodingDialog:public QDialog { Q_OBJECT public: /** \brief Constructor \param[in] iTraceName name of the trace to be colorcoded \param[in] iParent parent of the widget \param[in] iRandomIncluded true if the random option needs to be included */ explicit QGoColorCodingDialog(std::string iTraceName, bool iRandomIncluded, QWidget *iParent = 0); enum ColorWay{Nothing,Default,Random,LUT}; /** \brief Destructor */ virtual ~QGoColorCodingDialog(); /** \brief get the way the user wants its traces to be colorcoded and the LUT if he chooses the LUT \param[in] iTraceName name of the trace to be colorcoded \param[in,out] ioLUT lookup table choosen by the user \param[in] iiParent parent of the widget \param[in] iRandomIncluded true if the random option needs to be included */ static ColorWay GetColorWay( std::string iTraceName, vtkLookupTable **ioLUT, bool iRandomIncluded, QWidget *iiParent = 0 ); protected: QRadioButton* m_DefaultButton; QRadioButton* m_LUTButton; QRadioButton* m_RandomButton; vtkLookupTable* m_LUT; /** \brief set the components of the widget and the connection \param[in] iTraceName name of the trace to be colorcoded \param[in] iRandomIncluded true if the random option needs to be included */ void SetUpUi(std::string iTraceName, bool iRandomIncluded); protected slots: /** \brief open tha QGoLUTDialog to let the user choose a LUT */ void OpenLUTDialog(); private: Q_DISABLE_COPY( QGoColorCodingDialog ); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoLineageViewDockWidget.cxx0000644000175000017500000001017211667757442022740 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoLineageViewDockWidget.h" #include #include #include //------------------------------------------------------------------------- QGoLineageViewDockWidget::QGoLineageViewDockWidget( QWidget *iParent) : QGoDockWidget(iParent) { this->SetUpUi(); QIcon Lineageicon; Lineageicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/LineageView.png") ), QIcon::Normal, QIcon::Off); this->m_ToggleAction->setIcon(Lineageicon); this->m_ToggleAction->setToolTip("Lineage View"); this->setWindowTitle("Lineage View"); // color code QObject::connect( this->m_depthLineage, SIGNAL( toggled(bool) ), this, SLOT( ColorCodeLineagesByDepth(bool) ) ); QObject::connect( this->m_real, SIGNAL( toggled(bool) ), this, SLOT( ColorCodeLineagesByOriginalColor(bool) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoLineageViewDockWidget:: ~QGoLineageViewDockWidget() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLineageViewDockWidget::ColorCodeLineagesByDepth(bool iChecked) { if ( iChecked ) { emit ChangeDivisionsColorCode("DepthInformation"); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLineageViewDockWidget::ColorCodeLineagesByOriginalColor(bool iChecked) { if ( iChecked ) { emit ChangeDivisionsColorCode("Original"); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoLineageViewDockWidget::SetUpUi() { QWidget* LineageViewWidget = new QWidget; this->m_depthLineage = new QRadioButton(tr("Depth Color Code") ); this->m_real = new QRadioButton(tr("Original Color") ); this->m_real->setChecked(true); QVBoxLayout* VLayout = new QVBoxLayout; VLayout->addWidget(this->m_real); VLayout->addWidget(this->m_depthLineage); LineageViewWidget->setLayout(VLayout); this->setWidget(LineageViewWidget); LineageViewWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed); } GoFigure2-v0.9.0/Code/GUI/lib/QSplitterChild.cxx0000644000175000017500000000447511667757442021071 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QSplitterChild.h" QSplitterChild:: QSplitterChild(QWidget *iParent) : QSplitter(iParent), Prevpos( 0 ), Previndex( 0 ) { } QSplitterChild:: QSplitterChild(Qt::Orientation iOrientation, QWidget *iParent) : QSplitter(iOrientation, iParent), Prevpos( 0 ), Previndex( 0 ) { } QSplitterChild::~QSplitterChild() { } void QSplitterChild::moveSplitter(int iPos, int index) { if ( ( Prevpos != iPos ) || ( Previndex != index ) ) { Prevpos = iPos; Previndex = index; QSplitter::moveSplitter(iPos, index); } } GoFigure2-v0.9.0/Code/GUI/lib/Resources/0000755000175000017500000000000011667757442017412 5ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/lib/Resources/ContourManualSegmentationWidget.ui0000644000175000017500000000463311667757442026270 0ustar mathieumathieu ContourManualSegmentationWidget 0 0 184 137 Form QFrame::StyledPanel QFrame::Raised true Validate Contour Apply true Reinitialize Contour Delete false true Change Contour Settings Settings ... Qt::Vertical 20 40 GoFigure2-v0.9.0/Code/GUI/lib/Resources/NavigationDockWidget.ui0000644000175000017500000002752411667757442024027 0ustar mathieumathieu NavigationDockWidget 0 0 139 564 0 0 :/fig/navigation.png:/fig/navigation.png Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea Navigation QLayout::SetMinimumSize 6 54 20 XSlice XSliceSpinBox YSlice YSliceSpinBox ZSlice ZSliceSpinBox TSlice TSliceSpinBox 0 Qt::Horizontal QSlider::TicksAbove 100 Qt::Horizontal QSlider::TicksAbove 100 Qt::Horizontal QSlider::TicksAbove Qt::Horizontal QSlider::TicksAbove 1 Min Max Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Min Max Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Min Max Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Min Max Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Horizontal Classic Doppler Step 1 # of T false 3 Channel Name Qt::Vertical 20 40 XSliceSpinBox YSliceSpinBox ZSliceSpinBox TSliceSpinBox XSliceSpinBox valueChanged(int) XSliceSlider setValue(int) 98 42 68 69 YSliceSpinBox valueChanged(int) YSliceSlider setValue(int) 98 95 68 122 ZSliceSpinBox valueChanged(int) ZSliceSlider setValue(int) 98 148 68 175 TSliceSpinBox valueChanged(int) TSliceSlider setValue(int) 98 201 68 228 XSliceSlider valueChanged(int) XSliceSpinBox setValue(int) 68 69 98 42 YSliceSlider valueChanged(int) YSliceSpinBox setValue(int) 68 122 98 95 ZSliceSlider valueChanged(int) ZSliceSpinBox setValue(int) 68 175 98 148 TSliceSlider valueChanged(int) TSliceSpinBox setValue(int) 68 228 98 201 GoFigure2-v0.9.0/Code/GUI/lib/Resources/NewVideoRecorderDockWidget.ui0000644000175000017500000004050211667757442025125 0ustar mathieumathieu NewDockWidgetVideoRecorder 0 0 309 397 0 0 Video Recorder 0 Video through stacks QFrame::StyledPanel QFrame::Raised X Y Z T Qt::Horizontal 40 20 to QFrame::StyledPanel QFrame::Raised true 4 0 Qt::DefaultContextMenu Browse 10 10 10 0 2 2 Location Frame Rate Quality Start false Restart false End Live Record QFrame::StyledPanel QFrame::Raised true 4 0 Qt::DefaultContextMenu Browse 10 10 Location Frame Rate 10 0 2 2 Quality Qt::Horizontal 40 20 Start recording Lenght (s) QLCDNumber::Flat Qt::Horizontal 40 20 Qt::Horizontal 40 20 End recording <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#aa0000;">PLEASE GO IN FULL SCREEN MODE</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#aa0000;">TO USE THE VIDEO RECORDER</span></p></body></html> Qt::Vertical 20 40 GoFigure2-v0.9.0/Code/GUI/lib/Resources/QGoPluginInformationWidget.ui0000644000175000017500000000741411667757442025176 0ustar mathieumathieu Form 0 0 376 597 Form 20 10 346 574 Name: TextLabel Description: TextLabel Version: TextLabel GoFigure2 Compatibillity Version: TextLabel Distributor: TextLabel Copyright: License: QDialogButtonBox::Ok buttonBox accepted() Form close() 333 568 368 133 GoFigure2-v0.9.0/Code/GUI/lib/Resources/TransferFunctionDockWidget.ui0000644000175000017500000000234111667757442025210 0ustar mathieumathieu TransferFunctionDockWidget 0 0 171 96 0 0 :/fig/navigation.png:/fig/navigation.png Qt::AllDockWidgetAreas Transfer Function -1 GoFigure2-v0.9.0/Code/GUI/lib/Resources/TrackEditingWidget.ui0000644000175000017500000000534011667757442023467 0ustar mathieumathieu TrackEditingWidget 0 0 567 425 Dialog 0 0 Qt::Horizontal 40 20 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok true Real meshes false QVTKWidget QWidget
QVTKWidget.h
buttonBox accepted() TrackEditingWidget accept() 248 254 157 274 buttonBox rejected() TrackEditingWidget reject() 316 260 286 274
GoFigure2-v0.9.0/Code/GUI/lib/Resources/ManualSegmentationSettingsDlg.ui0000644000175000017500000001060311667757442025714 0ustar mathieumathieu ManualSegmentationSettingsDlg 0 0 350 390 Dialog 170 350 177 34 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok 5 120 341 221 160 10 185 101 QFormLayout::AllNonFixedFieldsGrow 20 Line Color Select Color Node Color Select Color Activated Node Color Select Color 20 10 124 28 Line Width LineWidthSpinBox 1 10.000000000000000 1.000000000000000 1.000000000000000 QVTKWidget QWidget
QVTKWidget.h
buttonBox accepted() ManualSegmentationSettingsDlg accept() 248 254 157 274 buttonBox rejected() ManualSegmentationSettingsDlg reject() 316 260 286 274
GoFigure2-v0.9.0/Code/GUI/lib/Resources/LsmToMegaExportDialog.ui0000644000175000017500000001522511667757442024130 0ustar mathieumathieu LsmToMegaExportDialog 0 0 294 304 LSM to MegaCapture exporter <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Parameters</span></p></body></html> QFrame::StyledPanel QFrame::Raised Browse... true LSM file Browse... true Path Output format PNG TIFF <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Conversion</span></p></body></html> QFrame::StyledPanel QFrame::Raised Qt::Horizontal 40 20 Convert GoFigure2-v0.9.0/Code/GUI/lib/Resources/SegmentationDockWidgetBase.ui0000644000175000017500000000433211667757442025150 0ustar mathieumathieu SegmentationDockWidgetBase 0 0 223 122 DockWidget QFrame::StyledPanel QFrame::Raised Mode Manual Semi Automatic Automatic QFrame::StyledPanel QFrame::Raised Qt::Vertical 20 0 GoFigure2-v0.9.0/Code/GUI/lib/Resources/QNameDescriptionInputDialog.ui0000644000175000017500000000545711667757442025331 0ustar mathieumathieu QNameDescriptionInputDialog 0 0 286 173 Dialog 75 false true false false Please enter the name and description of the 75 true new bookmark you want to save: QFormLayout::AllNonFixedFieldsGrow Name: Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok NameLineEdit NameDescriptionButtonBox NameDescriptionButtonBox rejected() QNameDescriptionInputDialog reject() 316 260 286 274 GoFigure2-v0.9.0/Code/GUI/lib/Resources/QGoSynchronizedView.ui0000644000175000017500000000106011667757442023667 0ustar mathieumathieu QGoSynchronizedView 0 0 456 300 Form GoFigure2-v0.9.0/Code/GUI/lib/Resources/BookmarkDialog.ui0000644000175000017500000000506111667757442022640 0ustar mathieumathieu Dialog Qt::ApplicationModal 0 0 362 274 Bookmark Dialog 190 240 164 32 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok false 10 10 339 226 Name NameEditor Description DescriptionEditor buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 GoFigure2-v0.9.0/Code/GUI/lib/QGoLUTDialog.h0000644000175000017500000000701511667757442020007 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoLUTDialog_h #define __QGoLUTDialog_h #include #include #include #include #include #include #include class vtkLookupTable; class vtkScalarBarActor; #include "vtkSmartPointer.h" #include "QVTKWidget.h" #include "QGoGUILibConfigure.h" /** * \class QGoLUTDialog * \brief Look-up Table Dialog * \image html QGoLUTDialog.png * \example GUI/lib/qgolutdialog.cxx */ class QGOGUILIB_EXPORT QGoLUTDialog:public QDialog { Q_OBJECT public: /** \brief Constructor */ explicit QGoLUTDialog(QWidget *parent = 0); /** \brief Destructor */ virtual ~QGoLUTDialog(); /** \brief get the selected look up table*/ vtkLookupTable * GetLookupTable(); /** \brief get the selected look up table*/ static vtkLookupTable * GetLookupTable(QWidget *iParent, const QString & iTitle, const int & iIdx = 0); public slots: /** \brief Change look up table*/ void ChangeLookupTable(const int &); protected: vtkLookupTable * LUT; vtkSmartPointer< vtkScalarBarActor > LUTActor; vtkSmartPointer< vtkRenderer > Renderer; QDialogButtonBox * ButtonBox; QVTKWidget * QvtkWidget; QHBoxLayout * HorizontalLayout; QHBoxLayout * HorizontalLayout_2; QVBoxLayout * VerticalLayout; QSpacerItem * HorizontalSpacer; QLabel * Label; QComboBox * LUTComboBox; void setupUi(QDialog *LUTDialog); private: Q_DISABLE_COPY(QGoLUTDialog); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoImageInfo.h0000644000175000017500000001137311667757442020063 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoImageInfo_h #define __QGoImageInfo_h #include #include #include #include #include #include #include #include #include #include "QGoGUILibConfigure.h" class QGOGUILIB_EXPORT QGoImageInfo:public QWidget { Q_OBJECT public: explicit QGoImageInfo(QWidget *parent = 0); virtual ~QGoImageInfo(); public slots: void setDimension(const unsigned int &); void setNumberOfChannels(const unsigned int &); void setMemory(const unsigned long &); void setSize(const std::vector< unsigned int > &); void setSpacing(const std::vector< float > &); void setPixelPosition(const std::vector< unsigned int > &); void setWorldPosition(const std::vector< float > &); void setTimePoint(const float &); void setValue(const std::vector< float > &); protected: QVBoxLayout *verticalLayout; QScrollArea *scrollArea; QWidget * scrollAreaWidgetContents; QGridLayout *gridLayout; QLabel *TImageStaticlabel; QLabel *TImageLabel; QLabel *DimensionStaticLabel; QLabel *DimensionLabel; QLabel *ChannelStaticLabel; QLabel *ChannelLabel; QLabel *SpacingStaticLabel; QLabel *SpacingLabel; QLabel *PPositionLabel; QLabel *WPositionStaticLabel; QLabel *WPositionLabel; QLabel *TTimeStaticLabel; QLabel *TTimeLabel; QLabel *TValueStaticLabel; QLabel *TValueLabel; QLabel *ValueStaticLabel; QLabel *ValueLabel; QLabel *SizeStaticLabel; QLabel *SizeLabel; QLabel *TimeStaticLabel; QLabel *TimeLabel; QLabel *TPositionLabel; QLabel *TPositionStaticLabel; QLabel *MemoryStaticLabel; QLabel *MemoryLabel; QLabel *PPositionStaticLabel; unsigned int m_Dimension; unsigned int m_Channel; unsigned long m_Memory; std::vector< unsigned int > m_Size; std::vector< float > m_Spacing; std::vector< unsigned int > m_PPos; std::vector< float > m_WPos; std::vector< float > m_Value; float m_TimePoint; template< class TContainer > QString ConvertToQString(const TContainer & iVector) { if ( iVector.empty() ) { return QString(); } else { size_t tsize = iVector.size(); if ( tsize == 1 ) { return QString("%1").arg( *iVector.begin() ); } else { QString v("[ "); unsigned int i = 0; for ( typename TContainer::const_iterator it = iVector.begin(); it != iVector.end(); ++it, ++i ) { if ( i == ( tsize - 1 ) ) { v.append( QString("%1 ]").arg(*it) ); } else { v.append( QString("%1 ; ").arg(*it) ); } } return v; } } } void setupUi(QWidget *Form); void retranslateUi(QWidget *Form); private: QGoImageInfo(const QGoImageInfo &); void operator=(const QGoImageInfo &); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoAboutWidget.cxx.in0000644000175000017500000002066311667757442021425 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoAboutWidget.h" #include #include #include #include #include #include #include #include #include #include QGoAboutWidget::QGoAboutWidget(QWidget *iParent) : QWidget(iParent) { Q_INIT_RESOURCE(axes); QString version("@GOFIGURE2_VERSION@"); QString date("Date: @DATE@\n\n"); QString about_gofigure( tr("Description: Software for the visualization and \nthe analysis of biological microscope images.\n") ); QString message = QString("Version: GoFigure2-%1\n\n").arg(version); message.append(date); message.append(about_gofigure); QVBoxLayout *vlayout = new QVBoxLayout(this); QLabel *GofigureLabel = new QLabel(message, this); GofigureLabel->setAlignment(Qt::AlignCenter); QLabel *TabExplanation = new QLabel( tr("\nGofigure uses different librairies,click on the tabs bellow to have a look at their copyright:\n"), this); TabExplanation->setAlignment(Qt::AlignJustify); QTabWidget *TabWidget = new QTabWidget(this); this->SetTabWidget(TabWidget); this->SetTheBackGround(GofigureLabel, TabWidget, TabExplanation); vlayout->addWidget(GofigureLabel); vlayout->addWidget(TabExplanation); vlayout->addWidget(TabWidget); this->setLayout(vlayout); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoAboutWidget::~QGoAboutWidget() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoAboutWidget::AddTabAbout(QString iTextLicense, QString iTabTitle, QTabWidget *iTabWidget) { QLabel *TextLicense = new QLabel(iTextLicense); QScrollArea *scrollArea = new QScrollArea; scrollArea->setBackgroundRole(QPalette::Light); scrollArea->setWidget(TextLicense); TextLicense->setStyleSheet("font-size:6x"); //TextLicense->setAlignment(Qt::AlignCenter); TextLicense->setAlignment(Qt::AlignJustify); iTabWidget->addTab(scrollArea, iTabTitle); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoAboutWidget::GetContributors() { QString authors( tr("Authors:\n\n") ); authors.append(" * 2008 ~ Arnaud Gelas\n"); authors.append(" * 2009 ~ Nicolas Rannou\n"); authors.append(" * 2008 ~ Kishore Mosaliganti\n"); authors.append(" * 2006 ~ Sean G. Megason\n"); authors.append(" ------- \n" ); authors.append(" * 2008-11 ~ Lydie Souhait\n"); authors.append(" * 2010-11 ~ Evan Schwab\n"); authors.append(" * 2010 ~ Antonin Perrot-Audet\n"); authors.append(" * 2007-09 ~ Alexandre Gouaillard\n\n"); QString contributors( tr("Contributors:\n\n") ); contributors.append(" * Mathieu Malaterre (Debian Packaging)\n" ); contributors.append(" * Ankur Sinha (Fedora Packaging)\n" ); authors.append( contributors ); return authors; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoAboutWidget::SetTabWidget(QTabWidget *iTabWidget) { QString TabTitle( tr("Contributors") ); this->AddTabAbout(this->GetContributors(), TabTitle, iTabWidget); this->WriteLicenseText(iTabWidget); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoAboutWidget::SetTheBackGround(QLabel *ilabel, QTabWidget *TabWidget, QLabel *ilabeltwo) { QPixmap Image( QString::fromUtf8(":/fig/splash2.png") ); ilabel->setMaximumSize( Image.size() ); ilabel->setMinimumSize( Image.size() ); ilabel->setStyleSheet("QLabel{color:rgb(255,255,255);background-image: url(:/fig/splash2.png); font: bold 12px}"); ilabel->setStyleSheet("color:rgb(255,255,255);background-image: url(:/fig/splash2.png); font: bold 12px"); int twidth = Image.width(); TabWidget->setMaximumWidth(twidth); TabWidget->setMinimumWidth(twidth); ilabeltwo->setMaximumWidth(twidth); ilabeltwo->setMinimumWidth(twidth); ilabel->setAlignment(Qt::AlignCenter); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoAboutWidget::ReadLicenseText(QString iFilename) { QString app_dir = QCoreApplication::applicationDirPath(); QDir temp = QDir(app_dir); temp.cdUp(); QString app_up_dir = temp.path(); temp.cdUp(); temp.cdUp(); QString app_up_up_up_dir = temp.path(); // linux no install, mac install QStringList search_dir(app_dir + "/Licenses"); // windows without install search_dir << app_up_dir + "/Licenses"; // linux with install search_dir << app_up_dir + "/share/doc/gofigure2/Licenses"; // mac without install search_dir << app_up_up_up_dir + "/Licenses"; QDir::setSearchPaths("licenses", search_dir); QString Filename("licenses:"); Filename.append(iFilename); QFile file(Filename); file.open(QIODevice::ReadOnly); QTextStream textStream( & file); QString LicenseText = textStream.readAll(); std::string test = LicenseText.toStdString(); return LicenseText; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoAboutWidget::WriteLicenseText(QTabWidget *iTabWidget) { this->AddTabAbout(this->ReadLicenseText("Copyright.txt"), "Gofigure", iTabWidget); this->AddTabAbout(this->ReadLicenseText("CopyrightOxygen.txt"), "Icon Oxygen", iTabWidget); this->AddTabAbout(this->ReadLicenseText("CopyrightNuvola.txt"), "Icon Nuvola", iTabWidget); this->AddTabAbout(this->ReadLicenseText("CopyrightCrystal.txt"), "Icon Crystal", iTabWidget); this->AddTabAbout(this->ReadLicenseText("VTKCopyright.txt"), "Vtk", iTabWidget); this->AddTabAbout(this->ReadLicenseText("ITKCopyright.txt"), "Itk", iTabWidget); this->AddTabAbout(this->ReadLicenseText("vtkINRIA3DCopyright.txt"), "VtkInria3D", iTabWidget); this->AddTabAbout(this->ReadLicenseText("BioimageXDCopyright.txt"), "BioImageXD", iTabWidget); this->AddTabAbout( this->ReadLicenseText("PoissonreconstructionCopyright.txt"), "Poisson Reconstruction", iTabWidget); #ifdef ENABLEFFMPEG this->AddTabAbout(this->ReadLicenseText("FFmpegCopyright.txt"), "FFmpeg", iTabWidget); #endif } GoFigure2-v0.9.0/Code/GUI/lib/QGoSelectedColorComboBox.cxx0000644000175000017500000000470411667757442022760 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSelectedColorComboBox.h" #include #include QGoSelectedColorComboBox::QGoSelectedColorComboBox(QWidget *iparent) : QGoColorComboBox("Add a new color...", iparent) //,"Delete colors...") { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoSelectedColorComboBox::~QGoSelectedColorComboBox() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoSelectedColorComboBox::ActionWhenNewOneRequested() { emit AddNewColorActivated(); }GoFigure2-v0.9.0/Code/GUI/lib/QGoImageView2D.cxx0000644000175000017500000001234711667757442020645 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoImageView2D.h" #include "QVTKWidget.h" #include "vtkEventQtSlotConnect.h" #include "vtkLookupTable.h" #include "vtkRenderWindow.h" #include "vtkRendererCollection.h" #include "vtkImageData.h" #include "vtkTextProperty.h" #include "vtkViewImage2DCollection.h" #include "vtkViewImage2D.h" //-------------------------------------------------------------------------- QGoImageView2D::QGoImageView2D(QWidget *iiParent) : QGoImageView(iiParent) { m_VTKEventQtConnector = vtkEventQtSlotConnect::New(); this->setupUi(this); vtkViewImage2D *View = vtkViewImage2D::New(); SetupViewGivenQVTKWidget(View, m_QVTKWidgetXY); m_Pool->AddItem(View); View->Delete(); QGoImageView::InitializeSeedWidget(); QGoImageView::InitializeDistanceWidget(); QGoImageView::InitializeAngleWidget(); QGoImageView::InitializeContourWidget(); } //-------------------------------------------------------------------------- QGoImageView2D:: ~QGoImageView2D() { m_VTKEventQtConnector->Delete(); } //-------------------------------------------------------------------------- void QGoImageView2D::setupUi(QWidget *iiParent) { if ( iiParent->objectName().isEmpty() ) { iiParent->resize(800, 800); } m_QVTKWidgetXY = new QVTKWidget(this); m_QVTKWidgetXY->resize(800, 800); m_LayOut = new QHBoxLayout(iiParent); m_LayOut->addWidget(m_QVTKWidgetXY); retranslateUi(iiParent); QMetaObject::connectSlotsByName(iiParent); } //-------------------------------------------------------------------------- void QGoImageView2D::retranslateUi(QWidget *iParent) { iParent->setWindowTitle( tr("QGoImageView2D") ); Q_UNUSED(iParent); } //-------------------------------------------------------------------------- void QGoImageView2D::SetImage(vtkImageData *iImage) { int dim[3]; iImage->GetDimensions(dim); if ( ( dim[0] > 1 ) && ( dim[1] > 1 ) && ( dim[2] > 1 ) ) { std::cout << "void QGoTabImageView2D::SetImage( vtkImageData* iImage )" << std::endl; std::cout << "This widget only display 2D images." << std::endl; return; } else { m_Image = iImage; } } //-------------------------------------------------------------------------- QVTKInteractor * QGoImageView2D::GetInteractor(const int & i) { if ( i == 0 ) { return m_QVTKWidgetXY->GetInteractor(); } else { return 0; } } //-------------------------------------------------------------------------- void QGoImageView2D::Update() { vtkViewImage2D *View = m_Pool->GetItem(0); View->SetInput(this->m_Image); View->GetTextProperty()->SetFontFamilyToArial(); View->GetTextProperty()->SetFontSize(20); View->SetViewOrientation(vtkViewImage2D::VIEW_ORIENTATION_AXIAL); View->SetViewConvention(vtkViewImage2D::VIEW_CONVENTION_NEUROLOGICAL); m_Pool->Initialize(); m_Pool->InitializeAllObservers(); m_Pool->SyncSetShowAnnotations(true); m_Pool->SyncSetShowScalarBar(false); m_Pool->SyncRender(); m_Pool->SyncReset(); } //-------------------------------------------------------------------------- QString QGoImageView2D::SnapshotViewXY(const GoFigure::FileType & iType, const QString & iBaseName) { QString filename = SnapshotView(this->m_QVTKWidgetXY, iType, iBaseName, m_SnapshotId); m_SnapshotId++; return filename; } //------------------------------------------------------------------------- void QGoImageView2D::ChangeCursorShape(QCursor iCursorShape) { //Change cursor m_QVTKWidgetXY->setCursor(iCursorShape); }GoFigure2-v0.9.0/Code/GUI/lib/QGoDeleteFromListDialog.cxx0000644000175000017500000001531311667757442022600 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDeleteFromListDialog.h" #include #include #include #include #include #include #include #include #include #include #include #include "ConvertToStringHelper.h" QGoDeleteFromListDialog::QGoDeleteFromListDialog (std::vector< std::string > iVectorEntities, QWidget *iParent, std::string iEntityName ) : QDialog(iParent) { this->SetUpUi(iEntityName); this->SetItemsFromTheVector(iVectorEntities); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoDeleteFromListDialog::QGoDeleteFromListDialog( QGoDeleteFromListDialog::ListOfItemColorComboboxData iDataListWithColor, QWidget *iParent, std::string iEntityName ) : QDialog(iParent) { this->SetUpUi(iEntityName); this->SetItemsInTheListWithColor(iDataListWithColor); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoDeleteFromListDialog::~QGoDeleteFromListDialog() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoDeleteFromListDialog::SetItemsFromTheVector( std::vector< std::string > iVectorItems) { for ( size_t i = 0; i < iVectorItems.size(); ++i ) { QListWidgetItem *item = new QListWidgetItem(iVectorItems[i].c_str(), this->m_ListWidget); (void)item; } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDeleteFromListDialog::SetItemsInTheListWithColor( std::list< ItemColorComboboxData > iDataList) { std::list< ItemColorComboboxData >::iterator iter = iDataList.begin(); QPixmap pix(12, 12); QPainter painter(&pix); QIcon Icon; while ( iter != iDataList.end() ) { if ( iter->second.isValid() ) { painter.setPen(Qt::gray); painter.setBrush( QBrush(iter->second) ); painter.drawRect(0, 0, 12, 12); } Icon.addPixmap(pix); QListWidgetItem *item = new QListWidgetItem(Icon, iter->first.c_str(), this->m_ListWidget); (void)item; ++iter; } } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDeleteFromListDialog::SelectionValidation() { QList< QListWidgetItem * > ListEntitiesToDeleteSelected = this->m_ListWidget->selectedItems(); if ( !ListEntitiesToDeleteSelected.empty() ) { QMessageBox msgBox; msgBox.setText( tr("Are you sure you want to delete these %1s ?") .arg( this->m_EntityName.c_str() ) ); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); int r = msgBox.exec(); if ( r == 16384 ) { DeleteSelection(ListEntitiesToDeleteSelected); this->accept(); } else { msgBox.close(); } } else { QMessageBox msgBox; msgBox.setText( tr("Please select at least one %1.") .arg( this->m_EntityName.c_str() ) ); msgBox.exec(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoDeleteFromListDialog::DeleteSelection( QList< QListWidgetItem * > iListEntitiesToDelete) { std::vector< std::string > VectorNamesToDelete; for ( int i = 0; i < iListEntitiesToDelete.size(); i++ ) { VectorNamesToDelete.push_back( iListEntitiesToDelete.at(i)->text().toStdString() ); } emit ListEntitiesToDelete(VectorNamesToDelete); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoDeleteFromListDialog::SetUpUi(std::string iEntityName) { this->m_EntityName = iEntityName; this->m_ListWidget = new QListWidget(this); this->m_ListWidget->setSelectionMode(QAbstractItemView::MultiSelection); QDialogButtonBox *ButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); QVBoxLayout *vlayout = new QVBoxLayout(this); vlayout->addWidget(this->m_ListWidget); vlayout->addWidget(ButtonBox); this->setWindowTitle( tr("Delete a %1").arg( this->m_EntityName.c_str() ) ); this->setLayout(vlayout); QObject::connect( ButtonBox, SIGNAL( rejected() ), this, SLOT( reject() ) ); QObject::connect( ButtonBox, SIGNAL( rejected() ), this, SIGNAL( CancelRequested() ) ); QObject::connect( ButtonBox, SIGNAL( accepted() ), this, SLOT( SelectionValidation() ) ); } GoFigure2-v0.9.0/Code/GUI/lib/QGoComboBox.cxx0000644000175000017500000001634211667757442020311 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoComboBox.h" #include #include QGoComboBox::QGoComboBox(std::string iTextToAddANewOne, QWidget *iparent, std::string iTextToDelete) : QComboBox(iparent) { this->m_TextToAddANewOne = iTextToAddANewOne; this->m_TextToDelete = iTextToDelete; if ( this->m_TextToDelete.empty() ) { this->m_NumberOfItemsAfterList = 1; } else { this->m_NumberOfItemsAfterList = 2; } QObject::connect( this, SIGNAL( activated(int) ), this, SLOT( CheckUserAction(int) ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoComboBox::~QGoComboBox() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoComboBox::InitializeTheList(QStringList iListItems) { this->SetItemsFromList(iListItems); //if it is the 1rst time for the list to be displayed, there has to be an // activated //item: //by default, the one selected by the combobox is the one to stick to: this->EmitActivatedItem( this->currentIndex() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoComboBox::InitializeTheList(NamesDescrContainerType iItemsData) { this->InitializeTheList( this->GetQStringListNames(iItemsData) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoComboBox::AddItemsEndOfList() { this->SetAddText(); if ( !this->m_TextToDelete.empty() ) { this->addItem( this->m_TextToDelete.c_str() ); } this->show(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoComboBox::SetItemsFromList(QStringList iDataFromList) { this->clear(); if ( !iDataFromList.empty() ) { this->addItems(iDataFromList); this->AddItemsEndOfList(); } else { this->SetAddText(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoComboBox::SetItemsFromList(NamesDescrContainerType iItemsData) { this->SetItemsFromList( this->GetQStringListNames(iItemsData) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QStringList QGoComboBox::GetQStringListNames(NamesDescrContainerType iContainer) { QStringList oQListItems; NamesDescrContainerType::iterator iter = iContainer.begin(); while ( iter != iContainer.end() ) { oQListItems.append( iter->first.c_str() ); ++iter; } return oQListItems; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoComboBox::CheckUserAction(int iIndexActivatedItem) { //int numberitem = this->count(); int IndexAdd = this->count() - this->m_NumberOfItemsAfterList; int IndexDelete = this->count() - 1; //in case there is normally an add and a delete but the list is empty,so //there is temporarily only the "add..": if ( IndexAdd < 0 ) { IndexAdd = IndexDelete; } if ( iIndexActivatedItem == IndexAdd ) { emit AddANewOneActivated(); return; } //if there is an item "Delete..." if ( IndexDelete != IndexAdd ) { if ( iIndexActivatedItem == IndexDelete ) { emit DeleteActivated(); return; } } this->EmitActivatedItem(iIndexActivatedItem); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoComboBox::EmitActivatedItem(int iIndexActivatedItem) { emit ItemSelected( this->itemText(iIndexActivatedItem).toStdString() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoComboBox::SetCurrentItem(std::string iItemText) { int index = this->findText( iItemText.c_str() ); if ( index == -1 ) { this->setCurrentIndex(0); } else { this->setCurrentIndex(index); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoComboBox::SetAddText() { this->addItem( this->m_TextToAddANewOne.c_str() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoComboBox::SetCurrentItemAndActivate(int iIndex) { this->setCurrentIndex(iIndex); this->EmitActivatedItem(iIndex); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoComboBox::SetCurrentItemAndActivate(std::string iItemText) { int index = this->findText( iItemText.c_str() ); if ( index == -1 ) { index = 0; } this->setCurrentIndex(index); this->EmitActivatedItem(index); } GoFigure2-v0.9.0/Code/GUI/lib/QGoLUTDialog.cxx0000644000175000017500000001663111667757442020366 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoLUTDialog.h" #include "QDebug" #include "QColorDialog" #include "vtkLookupTable.h" #include "vtkScalarBarActor.h" #include "vtkLookupTableManager.h" #include "vtkTextProperty.h" #include "vtkRenderer.h" #include "vtkRendererCollection.h" #include "vtkRenderWindow.h" QGoLUTDialog::QGoLUTDialog(QWidget *iParent) : QDialog(iParent), LUT(0) { setupUi(this); this->LUT = vtkLookupTableManager::GetBWLookupTable(); this->Renderer = vtkSmartPointer< vtkRenderer >::New(); vtkRenderWindow *renwin = this->QvtkWidget->GetRenderWindow(); renwin->AddRenderer(this->Renderer); this->LUTActor = vtkSmartPointer< vtkScalarBarActor >::New(); this->LUTActor->SetLookupTable(this->LUT); this->LUTActor->SetOrientationToHorizontal(); this->LUTActor->SetWidth(0.8); this->LUTActor->SetHeight(0.9); this->LUTActor->SetPosition(0.1, 0.1); this->LUTActor->SetTitle("LUT"); this->Renderer->AddActor2D(this->LUTActor); renwin->Render(); } QGoLUTDialog::~QGoLUTDialog() { // Is deleted outside //this->LUT->Delete(); delete this->QvtkWidget; } vtkLookupTable * QGoLUTDialog::GetLookupTable() { return this->LUT; } vtkLookupTable * QGoLUTDialog::GetLookupTable(QWidget *iiParent, const QString & iTitle, const int & iIdx) { QGoLUTDialog dlg(iiParent); if ( !iTitle.isEmpty() ) { dlg.setWindowTitle(iTitle); } dlg.ChangeLookupTable(iIdx); if ( dlg.exec() == QDialog::Accepted ) { return dlg.GetLookupTable(); } else { dlg.GetLookupTable()->Delete(); return NULL; } } void QGoLUTDialog::setupUi(QDialog *LUTDialog) { if ( LUTDialog->objectName().isEmpty() ) { LUTDialog->setObjectName( QString::fromUtf8("LUTDialog") ); } LUTDialog->resize(321, 183); LUTDialog->setMinimumSize(200, 150); LUTDialog->setModal(true); this->VerticalLayout = new QVBoxLayout(LUTDialog); this->VerticalLayout->setObjectName( QString::fromUtf8("VerticalLayout") ); this->VerticalLayout->setContentsMargins(10, 10, 10, 10); this->VerticalLayout->setSpacing(20); this->HorizontalLayout = new QHBoxLayout; this->HorizontalLayout->setObjectName( QString::fromUtf8("HorizontalLayout") ); this->HorizontalLayout->setContentsMargins(0, 0, 0, 0); this->Label = new QLabel; this->Label->setObjectName( QString::fromUtf8("Label") ); this->Label->setText( tr("Lookup Table") ); this->HorizontalLayout->addWidget(Label); this->LUTComboBox = new QComboBox; this->LUTComboBox->setObjectName( QString::fromUtf8("LUTComboBox") ); this->LUTComboBox->setLayoutDirection(Qt::RightToLeft); this->LUTComboBox->setAutoFillBackground(false); this->LUTComboBox->setEditable(false); this->LUTComboBox->setFrame(true); std::vector< std::string > lut_names = vtkLookupTableManager::GetAvailableLookupTables(); size_t k = 0; for (; k < lut_names.size(); k++ ) { this->LUTComboBox->insertItem( static_cast< int >( k ), QString::fromStdString(lut_names[k]) ); } this->LUTComboBox->insertItem( static_cast< int >( k ), tr("HSV Based") ); this->HorizontalLayout->addWidget(this->LUTComboBox); this->VerticalLayout->addLayout(this->HorizontalLayout); this->QvtkWidget = new QVTKWidget; this->QvtkWidget->setObjectName( QString::fromUtf8("qvtkWidget") ); this->QvtkWidget->setGeometry( QRect(10, 50, 301, 100) ); this->VerticalLayout->addWidget(this->QvtkWidget); this->HorizontalLayout_2 = new QHBoxLayout; this->HorizontalLayout_2->setObjectName( QString::fromUtf8("horizontalLayout_2") ); this->HorizontalLayout_2->setContentsMargins(0, 0, 0, 0); this->HorizontalSpacer = new QSpacerItem(166, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); this->HorizontalLayout_2->addItem(HorizontalSpacer); this->ButtonBox = new QDialogButtonBox; this->ButtonBox->setObjectName( QString::fromUtf8("buttonBox") ); this->ButtonBox->setGeometry( QRect(60, 160, 252, 32) ); this->ButtonBox->setOrientation(Qt::Horizontal); this->ButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); this->ButtonBox->setCenterButtons(false); this->HorizontalLayout_2->addWidget(ButtonBox); this->VerticalLayout->addLayout(this->HorizontalLayout_2); LUTDialog->setLayout(this->VerticalLayout); QObject::connect( this->ButtonBox, SIGNAL( accepted() ), LUTDialog, SLOT( accept() ) ); QObject::connect( this->ButtonBox, SIGNAL( rejected() ), LUTDialog, SLOT( reject() ) ); QObject::connect( this->LUTComboBox, SIGNAL( currentIndexChanged(int) ), this, SLOT( ChangeLookupTable(int) ) ); LUTComboBox->setCurrentIndex(0); QMetaObject::connectSlotsByName(LUTDialog); } void QGoLUTDialog::ChangeLookupTable(const int & idx) { this->LUT->Delete(); int N = this->LUTComboBox->count(); if ( ( idx >= N ) || ( idx < 0 ) ) { qWarning() << "QGoLUTDialog idx is out of range"; return; } else { if ( idx == N - 1 ) { QColor color = QColorDialog::getColor(Qt::green); double hsv[3]; if ( color.isValid() ) { hsv[0] = color.hueF(); hsv[1] = color.saturationF(); hsv[2] = color.valueF(); } else { color = Qt::green; hsv[0] = color.hueF(); hsv[1] = color.saturationF(); hsv[2] = color.valueF(); } this->LUT = vtkLookupTableManager::GetHSVBasedLookupTable(hsv); } else { this->LUT = vtkLookupTableManager::GetLookupTable(idx); } this->LUTActor->SetLookupTable(this->LUT); this->QvtkWidget->GetRenderWindow()->Render(); } }GoFigure2-v0.9.0/Code/GUI/lib/QSplitterChild.h0000644000175000017500000000470011667757442020505 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QSplitterChild_h #define __QSplitterChild_h #include #include "MegaVTK2Configure.h" /** \class QSplitterChild \brief in the QSplitter class, the method moveSplitter is protected, so it is not possible to use connect between the QSplitter to synchronize them. that's the reason for the creation of QSplitterchild. */ class QSplitterChild:public QSplitter { Q_OBJECT public: explicit QSplitterChild(QWidget *parent = 0); explicit QSplitterChild(Qt::Orientation orientation, QWidget *parent = 0); virtual ~QSplitterChild(); public slots: void moveSplitter(int pos, int index); protected: int Prevpos; int Previndex; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/QGoImageView3D.h0000644000175000017500000001725011667757442020271 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoImageView3D_h #define __QGoImageView3D_h #include "QGoImageView.h" #include "SnapshotHelper.h" #include #include #include #include #include #include #include #include #include "vtkInteractorStyleImage2D.h" #include "QGoGUILibConfigure.h" #include "vtkCommand.h" class QVTKWidget; class vtkEventQtSlotConnect; class QSplitterChild; class vtkProp3D; class vtkProperty; class vtkImageData; class vtkViewImage2D; class vtkViewImage3D; class vtkViewImage2DCollection; // For the box widget class vtkOrientedBoxWidget; // For the plane widget class vtkImplicitPlaneWidget; // volumre rendering class vtkPiecewiseFunction; /** \class QGoImageView3D \brief class for the visualization of 3D Image represented by one vtkImageData*. \example GUI/lib/qgoimageview3d.cxx */ class QGOGUILIB_EXPORT QGoImageView3D:public QGoImageView { Q_OBJECT public: /** \brief Constructor by default */ explicit QGoImageView3D(QWidget *parent = 0); /** \brief Destructor. */ virtual ~QGoImageView3D(); void Update(); vtkViewImage3D * GetImageViewer3D(); QVTKInteractor * GetInteractor(const int &); /** \brief Set the image to displaid. */ virtual void SetImage(vtkImageData *iImage); virtual void RemoveActor(const int & iId, vtkActor *iActor); virtual void AddActor(const int & iId, vtkActor *iActor); // std::vector< vtkQuadricLODActor* > std::vector< vtkActor * > AddContour(vtkPolyData *iDataset, vtkProperty *iProperty = NULL); virtual void setupUi(QWidget *parent); virtual void retranslateUi(QWidget *parent); int GetFullScreenView() const; void SaveStateSplitters(); int GetSliceViewXY() const; int GetSliceViewXZ() const; int GetSliceViewYZ() const; // MODES /** * \brief Use the default interactor style */ void DefaultMode(); /** * \brief Use the zoom interactor style */ void ZoomMode(); /** * \brief Use the pan interactor style */ void PanMode(); /** * \brief switch to contour picking mode */ void ActorPickingMode(); // WIDGETS /** * \brief Use the one click interactor style */ void EnableSeedWidget(bool iActivate); /** * \brief Creates a box in 3d view to allow multiple meshes selection */ void EnableBoxWidget(bool); /** * \brief Creates a box in 3d view to allow multiple meshes selection */ void EnablePlaneWidget(bool); /** * \brief Creates a box in 3d view to allow multiple meshes selection */ vtkProp * GetPickedActor(); vtkActor * GetCurrentActor(); bool GetCurrentState(); void ChangeCursorShape(QCursor iCursorShape); signals: void SliceViewXYChanged(int Slice); void SliceViewXZChanged(int Slice); void SliceViewYZChanged(int Slice); void FullScreenViewChanged(int View); void SelectionChanged(); void VisibilityChanged(); void CurrentActorUpdated(); void UpdateRenderEvent(); void NewWindowLevel(double, double); public slots: QString SnapshotViewXY( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xy-") ); QString SnapshotViewXZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xz-") ); QString SnapshotViewYZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-yz") ); QString SnapshotViewXYZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xyz-") ); void SetSliceViewXY(const int &); void SetSliceViewXZ(const int &); void SetSliceViewYZ(const int &); void SetFullScreenView(const int & iS); void SetCamera(int); void UpdateLUT(); void ShowSplinePlane(); void ShowCube3D(); /** * \brief Creates a box in 3d view to allow multiple meshes selection */ void EnableVolumeRendering(const std::vector& iImages, const std::vector& iOpacities); void DisableVolumeRendering(); void UpdateCurrentActorSelection(vtkObject *caller); void UpdateCurrentActorVisibility(vtkObject *caller); virtual void SetLookupTable(vtkLookupTable *); virtual void ShowScalarBar(const bool &); /* * \brief Synchronize the views * \param[in] iSynchronize Enable/disable synchronization */ void SynchronizeViews( bool iSynchronize); /* * \brief Show/hide the planes in the 3d view * \param[in] iSynchronize Enable/disable synchronization */ void ShowPlanes( bool iShow); protected: QSplitter * VSplitter; QSplitterChild *HtSplitter; QSplitterChild *HbSplitter; QWidget * LayOutWidget1; QHBoxLayout *LayOut1; QSlider * SliderXY; QVTKWidget * QvtkWidget_XY; QWidget * LayOutWidget2; QHBoxLayout *LayOut2; QSlider * SliderXZ; QVTKWidget * QvtkWidget_XZ; QWidget * LayOutWidget3; QHBoxLayout *LayOut3; QSlider * SliderYZ; QVTKWidget * QvtkWidget_YZ; QWidget * LayOutWidget4; QHBoxLayout *LayOut4; QVTKWidget * QvtkWidget_XYZ; vtkViewImage3D *m_View3D; vtkEventQtSlotConnect *VtkEventQtConnector; vtkProperty * m_HighlightedContourProperty; int IsFullScreen; bool m_FirstRender; bool m_Initialized; bool m_ShowCube; vtkOrientedBoxWidget * m_BoxWidget; vtkImplicitPlaneWidget *m_PlaneWidget; vtkActor *m_CurrentActor; bool m_CurrentState; virtual void resizeEvent(QResizeEvent *event); void SetupVTKtoQtConnections(); void UpdateOnFirstRender(); void Quadview(); void FullScreenViewXY(); void FullScreenViewXZ(); void FullScreenViewYZ(); void FullScreenViewXYZ(); void InitializeBoxWidget(); void InitializePlaneWidget(); protected slots: void MoveSliderXY(); void MoveSliderXZ(); void MoveSliderYZ(); private: Q_DISABLE_COPY(QGoImageView3D); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TransferFunctionEditor/0000755000175000017500000000000011667757442022101 5ustar mathieumathieuGoFigure2-v0.9.0/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionWidget.cxx0000644000175000017500000002366611667757442027566 0ustar mathieumathieu/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the demonstration applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoTransferFunctionWidget.h" #include "hoverpoints.h" //vtk #include "vtkLookupTable.h" //------------------------------------------------------------------------- GoTransferFunctionWidget::GoTransferFunctionWidget(QColor iColor, double iMax, QWidget *parent) : QWidget(parent), m_color(iColor) { // set max value m_Max = iMax; // set minimum size to avoid bad appearance this->setMinimumWidth(50); this->setMinimumHeight(50); setAttribute(Qt::WA_NoBackground); // LUT curve m_LUTPoints = new HoverPoints(this, HoverPoints::RectangleShape); m_LUTPoints->setConnectionType(HoverPoints::LineConnection); // connect signal connect(this, SIGNAL(enableLUTCurve(bool)), m_LUTPoints, SLOT(setEnabled(bool))); // opacity TF m_OpacityTFPoints = new HoverPoints(this, HoverPoints::CircleShape); m_OpacityTFPoints->setConnectionType(HoverPoints::LineConnection); // connect signal connect(this, SIGNAL(enableOpacityTF(bool)), m_OpacityTFPoints, SLOT(setEnabled(bool))); connect(m_OpacityTFPoints, SIGNAL(pointsChanged(QPolygonF)), this, SIGNAL(opacityChanged())); // set size policy setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QPolygonF GoTransferFunctionWidget::points() const { return m_OpacityTFPoints->points(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionWidget::paintEvent(QPaintEvent * event) { // generate shade, if necessary if (m_shade.isNull() || m_shade.size() != size()) { generateShade(); } // draw shade QPainter p(this); p.drawImage(0, 0, m_shade); p.setPen(QColor(146, 146, 146)); p.drawRect(0, 0, width() - 1, height() - 1); // draw histogram if(m_Histogram.size() > 0) { QVector listOfPoints; qreal x_range = m_Histogram.size(); for(int i=0; isetPoints(iPoints); m_OpacityTFPoints->setPointLock(0, HoverPoints::LockToLeft); m_OpacityTFPoints->setPointLock(iPoints.size()-1, HoverPoints::LockToRight); m_OpacityTFPoints->setSortType(HoverPoints::XSort); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionWidget:: AddPointsToLUT(const QPolygonF& iPoints) { m_LUTPoints->setPoints(iPoints); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionWidget:: UpdateLookupTable(vtkLookupTable* iLUT, qreal iGamma, qreal iMin, qreal iMax) { QPolygonF iPoints; int numTableValues = m_Max; qreal width = this->width(); qreal height = this->height(); iLUT->SetNumberOfTableValues(iMax-iMin); // points affected with gamma correction, in the window int count = 0; // first point iPoints << QPointF((qreal)(iMin)*(width-1)/numTableValues, height - 1); iLUT->SetTableValue(count, 0, 0, 0); count++; for(int i=iMin+1; iSetTableValue(count, power*m_color.redF(), power*m_color.greenF(), power*m_color.blueF()); count++; } // last point iPoints << QPointF((qreal)(iMax)*(width-1)/numTableValues,0); iLUT->SetTableValue(count, m_color.redF(), m_color.greenF(), m_color.blueF()); iLUT->SetRange(iMin, iMax); iLUT->Modified(); // print new curve m_LUTPoints->setPoints(iPoints); update(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionWidget:: SetHistogram(QVector iHistogram) { m_Histogram = iHistogram; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionWidget:: ResetOpacity() { // reset opacity TF QPolygonF points; points << QPointF(0, height()) << QPointF(width(),0); m_OpacityTFPoints->setPoints(points); m_OpacityTFPoints->setPointLock(0, HoverPoints::LockToLeft); m_OpacityTFPoints->setPointLock(1, HoverPoints::LockToRight); m_OpacityTFPoints->setSortType(HoverPoints::XSort); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionWidget:: setColor(QColor iColor) { // modify color m_color = iColor; // generate new shade generateShade(); // update the shade update(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionWidget:: setMax(double iMax) { m_Max = iMax; } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/TransferFunctionEditor/QGoTransferFunctionDockWidget.h0000644000175000017500000000532411667757442030124 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTransferFunctionDockWidget_h #define __QGoTransferFunctionDockWidget_h #include #include "ui_TransferFunctionDockWidget.h" #include "GoFigureGlobalDefinition.h" #include "QGoDockWidget.h" #include "QGoGUILibConfigure.h" class GoTransferFunctionEditorWidget; /** \class QGoTransferFunctionDockWidget * \brief Dock Widget for browsing images (changing slice, time point...) * \ingroup GUI */ class QGOGUILIB_EXPORT QGoTransferFunctionDockWidget: public QGoDockWidget, private Ui::TransferFunctionDockWidget { Q_OBJECT public: /** \brief Constructor */ explicit QGoTransferFunctionDockWidget(QWidget *parent = 0); /** \brief Destructor */ ~QGoTransferFunctionDockWidget(); void AddTransferFunction(QString iName, GoTransferFunctionEditorWidget* iTF); int GetCurrentWidget(); QWidget* GetWidget(int iIndex); void SetCurrentWidget(int iIndex); void DeleteTabs(); int GetNumberOfTabs(); }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TransferFunctionEditor/hoverpoints.h0000644000175000017500000001473711667757442024646 0ustar mathieumathieu/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the demonstration applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef HOVERPOINTS_H #define HOVERPOINTS_H #include QT_FORWARD_DECLARE_CLASS(QBypassWidget) class HoverPoints : public QObject { Q_OBJECT public: enum PointShape { CircleShape, RectangleShape }; enum LockType { LockToLeft = 0x01, LockToRight = 0x02, LockToTop = 0x04, LockToBottom = 0x08 }; enum SortType { NoSort, XSort, YSort }; enum ConnectionType { NoConnection, LineConnection, CurveConnection }; HoverPoints(QWidget *widget, PointShape shape); bool eventFilter(QObject *object, QEvent *event); void paintPoints(); inline QRectF boundingRect() const; void setBoundingRect(const QRectF &boundingRect) { m_bounds = boundingRect; } QPolygonF points() const { return m_points; } void setPoints(const QPolygonF &points); QSizeF pointSize() const { return m_pointSize; } void setPointSize(const QSizeF &size) { m_pointSize = size; } SortType sortType() const { return m_sortType; } void setSortType(SortType sortType) { m_sortType = sortType; } ConnectionType connectionType() const { return m_connectionType; } void setConnectionType(ConnectionType connectionType) { m_connectionType = connectionType; } void setConnectionPen(const QPen &pen) { m_connectionPen = pen; } void setShapePen(const QPen &pen) { m_pointPen = pen; } void setShapeBrush(const QBrush &brush) { m_pointBrush = brush; } void setPointLock(int pos, LockType lock) { m_locks[pos] = lock; } void setEditable(bool editable) { m_editable = editable; } bool editable() const { return m_editable; } public slots: void setEnabled(bool enabled); signals: void pointsChanged(const QPolygonF &points); public: void firePointChange(); private: inline QRectF pointBoundingRect(int i) const; void movePoint(int i, const QPointF &newPos, bool emitChange = true); QWidget *m_widget; QPolygonF m_points; QRectF m_bounds; PointShape m_shape; SortType m_sortType; ConnectionType m_connectionType; QVector m_locks; QSizeF m_pointSize; int m_currentIndex; bool m_editable; bool m_enabled; QHash m_fingerPointMapping; QPen m_pointPen; QBrush m_pointBrush; QPen m_connectionPen; double m_oldSize[2]; }; inline QRectF HoverPoints::pointBoundingRect(int i) const { QPointF p = m_points.at(i); qreal w = m_pointSize.width(); qreal h = m_pointSize.height(); qreal x = p.x() - w / 2; qreal y = p.y() - h / 2; return QRectF(x, y, w, h); } inline QRectF HoverPoints::boundingRect() const { if (m_bounds.isEmpty()) return m_widget->rect(); else return m_bounds; } #endif // HOVERPOINTS_H GoFigure2-v0.9.0/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionEditorWidget.cxx0000644000175000017500000005463611667757442030736 0ustar mathieumathieu/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the demonstration applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoTransferFunctionEditorWidget.h" // Gofigure #include "GoTransferFunctionWidget.h" #include "QGoLUTDialog.h" #include "hoverpoints.h" //qt #include #include //vtk #include "vtkLookupTable.h" #include "vtkImageAccumulate.h" #include "vtkImageData.h" #include "vtkPointData.h" #include "vtkPiecewiseFunction.h" // std #include //------------------------------------------------------------------------- GoTransferFunctionEditorWidget:: GoTransferFunctionEditorWidget(QString iChannel, const std::vector& iColor, std::vector iLUTParameters, double iMax, QWidget *parent ) : QWidget(parent ) { // set current color of the channel m_Color.setRedF(iColor[0]/255); m_Color.setGreenF(iColor[1]/255); m_Color.setBlueF(iColor[2]/255); m_Color.setAlphaF(iColor[3]/255); // save original color of the channel if the user want to reset it m_Color_original = m_Color; // set the maximum value in the image m_Max = iMax; // init LUT to NULL m_LUT = NULL; // set channel name m_Channel = iChannel; // global layout of the widget QVBoxLayout *vbox = new QVBoxLayout(this); vbox->setSpacing(1); vbox->setMargin(1); // first part of the widget: the color /* --------------------------- | _____________ | | Color: |_P_U_S_H_____| | | | --------------------------- */ // items //label QLabel *color = new QLabel("Color: "); // push button m_ColorPushButton = new QPushButton(this); m_ColorPushButton->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); QString style = "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop: 0 black, stop: 1 rgb(%1, %2, %3)); border-radius: 4px;"; m_ColorPushButton->setStyleSheet( style.arg(m_Color.red()).arg(m_Color .green()).arg(m_Color.blue())); m_ColorPushButton->setToolTip("Click to modify the color of this channel"); // add items to layout QHBoxLayout *colorLayout = new QHBoxLayout; colorLayout->addWidget(color); colorLayout->addWidget(m_ColorPushButton); // connect signals connect(m_ColorPushButton, SIGNAL(clicked()), this, SLOT(ChangeColor())); // add layout to the widget vbox->addLayout(colorLayout); // second part of the widget: the TH Widget /* ----------------------------- | |------------------|--| | | _____________________ | | | | | | | | | | | | | | | | | | |_____________________| | | | | |---|-----------------| | ----------------------------- */ // items // Left spacer QSpacerItem* spacer_red1 = new QSpacerItem(10, 10, QSizePolicy::Minimum, QSizePolicy::Minimum); // right spacer QSpacerItem* spacer_red2 = new QSpacerItem(10, 10, QSizePolicy::Minimum, QSizePolicy::Minimum); // TF widget m_TFWidget = new GoTransferFunctionWidget( m_Color, m_Max, this); //min slider m_MinSlider = new QSlider(this); m_MinSlider->setObjectName("min"); m_MinSlider->setOrientation(Qt::Horizontal); m_MinSlider->setMaximum(m_Max); m_MinSlider->setValue(iLUTParameters[1]); m_MinSlider->setStyleSheet("QSlider::groove:horizontal {border: 1px solid #bbb;background: rgba(0, 0, 0, 0);height: 4px;position: absolute; right: 10px;left: 10px; }QSlider::handle:horizontal {image: url(/home/nr52/gitroot/gofigure/Resources/widget/arrow_up.png);width: 20px;height: 6px;margin-top: -2px;margin-bottom: -2px; right: -10px; left:-10px; border: 1px solid black; background: rgba(255, 255, 255, 200); border-radius: 4px;}QSlider::sub-page:horizontal {background: #909090;border: 1px solid black;}QSlider::add-page:horizontal {background: rgba(0, 0, 0, 0);border: 1px solid black;}"); // max slider m_MaxSlider = new QSlider(this); m_MaxSlider->setObjectName("max"); m_MaxSlider->setOrientation(Qt::Horizontal); m_MaxSlider->setMaximum(m_Max); m_MaxSlider->setValue(m_Max); m_MaxSlider->setStyleSheet("QSlider::groove:horizontal {border: 1px solid #bbb;background: rgba(0, 0, 0, 0);height: 4px;position: absolute; right: 10px;left: 10px; }QSlider::handle:horizontal {image: url(/home/nr52/gitroot/gofigure/Resources/widget/arrow_down.png);width: 20px;height: 6px;margin-top: -2px;margin-bottom: -2px; right: -10px; left:-10px; border: 1px solid black; background: rgba(255, 255, 255, 200); border-radius: 4px;}QSlider::sub-page:horizontal {background: rgba(0, 0, 0, 0);border: 1px solid black;}QSlider::add-page:horizontal {background: #909090;border: 1px solid black;}"); // more spacer QSpacerItem* spacerShade1 = new QSpacerItem(10, 10, QSizePolicy::Minimum, QSizePolicy::Minimum); // more spacer QSpacerItem* spacerShade2 = new QSpacerItem(10, 10, QSizePolicy::Minimum, QSizePolicy::Minimum); // connect signals connect(m_MinSlider, SIGNAL(valueChanged(int)), this, SLOT(updateSliders(int))); connect(m_MaxSlider, SIGNAL(valueChanged(int)), this, SLOT(updateSliders(int))); // add items to layout 1 QHBoxLayout *m_TFWidget_layout = new QHBoxLayout; m_TFWidget_layout->addSpacerItem(spacer_red1); m_TFWidget_layout->addWidget(m_TFWidget); m_TFWidget_layout->addSpacerItem(spacer_red2); // add items to layout 2 QVBoxLayout* shadeVerticalLayout = new QVBoxLayout; shadeVerticalLayout->addWidget(m_MaxSlider); shadeVerticalLayout->addLayout(m_TFWidget_layout); shadeVerticalLayout->addWidget(m_MinSlider); // add items to layout 3 QHBoxLayout* shadeHorizontalLayout= new QHBoxLayout; shadeHorizontalLayout->addItem(spacerShade1); shadeHorizontalLayout->addLayout(shadeVerticalLayout); shadeHorizontalLayout->addItem(spacerShade2); // connect signals connect(m_TFWidget, SIGNAL(opacityChanged()), this, SLOT(updateOpacityTF())); // add layout to the widget vbox->addLayout(shadeHorizontalLayout); // third part: the gamma slider /* ------------------------------ | Gamma: |---|------------| | ------------------------------ */ // items // gamma label QLabel* gammaName = new QLabel((QChar)(0x0263)); // gamma slider m_GammaSlider = new QSlider(this); m_GammaSlider->setOrientation(Qt::Horizontal); m_GammaSlider->setMaximum(199); m_GammaSlider->setMinimum(1); m_GammaSlider->setValue(iLUTParameters[0]); // connect signals connect(m_GammaSlider, SIGNAL(valueChanged(int)), this, SLOT(UpdateLUT())); // add items to layout QHBoxLayout *gammaLayout = new QHBoxLayout; gammaLayout->addWidget(gammaName); gammaLayout->addWidget(m_GammaSlider); // add layout to the widget vbox->addLayout(gammaLayout); // fourth part: the visibility checkboxes /* ------------------------------ | + Color TF | | - Opacity TF | | + Log Histogram | ------------------------------ */ // items // color TF checkbox QCheckBox* tfCB = new QCheckBox("Color Transfer Function"); tfCB->setChecked(true); QString style5 = "color: black; border: 1px solid rgb(0, 0, 0); background-color: rgba(255, 255, 255, 150); border-radius: 4px;"; tfCB->setStyleSheet(style5); // opacity TF checkbox QCheckBox* tfoCB = new QCheckBox("Opacity Transfer Function"); tfoCB->setChecked(false); QString style2 = "color: white; border: 1px solid rgb(0, 0, 0); background-color: rgba(0, 0, 0, 150); border-radius: 4px;"; tfoCB->setStyleSheet(style2); // histogram checkbox QCheckBox* histogramCB = new QCheckBox("Log Histogram"); histogramCB->setChecked(true); QString style3 = "border: 1px solid rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0); border-radius: 4px;"; histogramCB->setStyleSheet(style3); // connect signals connect(tfoCB, SIGNAL(clicked(bool)), m_TFWidget, SIGNAL(enableOpacityTF(bool))); connect(tfCB, SIGNAL(clicked(bool)), m_TFWidget, SIGNAL(enableLUTCurve(bool))); connect(histogramCB, SIGNAL(clicked(bool)), this, SLOT(ShowHistogram(bool))); // add items to the widget vbox->addWidget(tfCB); vbox->addWidget(tfoCB); vbox->addWidget(histogramCB); // fith part: apply/reset pushbutton /* --------------------------- | _________ _________ | | |_A_PPL_Y_| |_R_ESE_T_| | | | --------------------------- */ // items // apply pushbutton QPushButton *okPushButton = new QPushButton("Apply", this); // reset pushbutton QPushButton *ResetLUTPushButton = new QPushButton("Reset", this); // connect signals connect(okPushButton, SIGNAL(released()), this, SLOT(ApplyChanges())); connect(ResetLUTPushButton, SIGNAL(pressed()), this, SLOT(ResetLUT())); // layout QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(okPushButton); layout->addWidget(ResetLUTPushButton); // add layout to widget vbox->addLayout(layout); this->setLayout(vbox); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: UpdateLUT() { if(m_LUT) { qreal side = m_GammaSlider->value()/(100); int ope = pow(-1, side + 1); qreal value = (qreal)(ope*(m_GammaSlider->value()-100) + ope); qreal gamma_value; if(value > 2) { qreal temp = log(value); gamma_value = pow(temp, ope); } else { gamma_value = 1; } // update the LUT m_TFWidget->UpdateLookupTable(m_LUT, gamma_value, (qreal)m_MinSlider->value(), (qreal)m_MaxSlider->value()); // send signal to update the visualization emit updateVisualization(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: AddPoints( const std::map< unsigned int, unsigned int>& iPoints) { // points QPolygonF points; // convert points ConvertSTDMapToQPolygonF(iPoints, points); // add points to the opacity TF m_TFWidget->AddPointsToOpacityTF(points); // add points to the LUT m_TFWidget->AddPointsToLUT(points); // update LUT in widget and visualization UpdateLUT(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: ConvertSTDMapToQPolygonF(const std::map< unsigned int, unsigned int>& iMap, QPolygonF& iPoints) { // all shades have same width and height qreal width = m_TFWidget->width(); qreal height = m_TFWidget->height(); std::map< unsigned int, unsigned int>::const_iterator it0; std::map< unsigned int, unsigned int>::const_iterator it255; it0 = iMap.begin(); it255 = iMap.end(); // check x and y while(it0!=it255) { iPoints << QPointF((qreal)(it0->first)*width/m_Max, height*(1-(qreal)(it0->second)/m_Max)); ++it0; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: AddLookupTable(vtkLookupTable* iLUT) { m_LUT = iLUT; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: AddOpacityTransferFunction(vtkPiecewiseFunction* iOpacity) { m_OpacityTF = iOpacity; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: AddHistogram(vtkImageAccumulate* iHistogram) { // get the x range int x_range = iHistogram->GetOutput()->GetNumberOfPoints(); // get the y values vtkDataArray* scalars = iHistogram->GetOutput()->GetPointData()->GetScalars(); // get the scalar values to normalize double* range = iHistogram->GetOutput()->GetScalarRange(); QVector histogram; for(int i=0; iGetTuple1(i); histogram.push_back(log(value)/log(range[1])); } m_Histogram = histogram; // add histogram the the TF Widget m_TFWidget->SetHistogram(m_Histogram); // update the widget so the histogram is visible m_TFWidget->update(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: AddColor(const std::vector& iColor) { m_Color.setRedF(iColor[0]/255); m_Color.setGreenF(iColor[1]/255); m_Color.setBlueF(iColor[2]/255); m_Color.setAlphaF(iColor[3]/255); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: AddName(QString iChannel) { m_Channel = iChannel; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: ResetLUT() { // reset the color m_Color = m_Color_original; // reset the opacity TF m_TFWidget->ResetOpacity(); // reset the color m_TFWidget->setColor(m_Color); // reset button color QString style = "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop: 0 black, stop: 1 rgb(%1, %2, %3)); border-radius: 4px;"; m_ColorPushButton->setStyleSheet( style.arg(m_Color.red()).arg(m_Color .green()).arg(m_Color.blue())); // Reset Gamma, Min and Max m_GammaSlider->setValue(100); m_MinSlider->setValue(0); m_MaxSlider->setValue(m_Max); // Update LUT UpdateLUT(); // might be buggy updateOpacityTF(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: ApplyChanges() { // opacity std::map< unsigned int, unsigned int> pointsVector; QPolygonF opacityPoints = m_TFWidget->points(); ConvertQPolygonFToSTDMap(opacityPoints, pointsVector); // send values to the image structure emit UpdateImageStructure(m_Channel, pointsVector, m_Color, m_MinSlider->value(), m_MaxSlider->value(), m_GammaSlider->value()); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: ConvertQPolygonFToSTDMap(const QPolygonF& iPoints, std::map< unsigned int, unsigned int>& iMap) { qreal width = m_TFWidget->width(); qreal height = m_TFWidget->height(); int numberOfPoints = iPoints.size(); if(numberOfPoints>m_Max) { qDebug() << "Too many points: " << numberOfPoints << " points"; return; } for(int i=0; iwidth(); qreal height = m_TFWidget->height(); int numberOfPoints = m_TFWidget->points().size(); m_OpacityTF->Initialize(); for(int i=0; ipoints().at(i).x())*m_Max/width; // y 0 to 1 double y = (1-(m_TFWidget->points().at(i).y())/height); m_OpacityTF->AddPoint(x, y); } m_OpacityTF->Modified(); emit updateVisualization(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: ChangeColor() { QColor color = QColorDialog::getColor(); // if we selected a color and clicked on "OK" if(color.isValid()) { m_Color = color; } // update button QString style = "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop: 0 black, stop: 1 rgb(%1, %2, %3)); border-radius: 4px;"; m_ColorPushButton->setStyleSheet( style.arg(m_Color.red()).arg(m_Color .green()).arg(m_Color.blue())); // update shade m_TFWidget->setColor(m_Color); // update LUT UpdateLUT(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: ShowHistogram(bool iShow){ if(iShow) { m_TFWidget->SetHistogram(this->m_Histogram); } else { QVector removeHisto; m_TFWidget->SetHistogram(removeHisto); } // to be tested might be buggy // update might be better? m_TFWidget->repaint(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: AdjustWindowLevel(double iMin, double iMax){ this->m_MinSlider->blockSignals(true); this->m_MinSlider->setValue(iMin); this->m_MinSlider->blockSignals(false); this->m_MaxSlider->blockSignals(true); this->m_MaxSlider->setValue(iMax); this->m_MaxSlider->blockSignals(false); UpdateLUT(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: SetMaximumValue( double iMax) { m_Max = iMax; m_TFWidget->setMax(m_Max); if(m_MaxSlider->maximum() > m_Max) { m_MaxSlider->setValue(iMax); } else { m_MaxSlider->setValue(m_MaxSlider->value()); } m_MinSlider->setMaximum(m_Max); m_MaxSlider->setMaximum(m_Max); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void GoTransferFunctionEditorWidget:: updateSliders( int iValue) { // min and max must be separated by at least 2 to create a consitent LUT // since a consistent LUT need 2 values at least. /* need value in between ^ LUT: MIN VALUE | color 1 | color 2 | MAX VALUE */ if(m_MinSlider->value() > m_MaxSlider->value() - 2) { QString name = QObject::sender()->objectName(); if(! name.compare("min") ) { m_MinSlider->setValue(iValue - 1); } else { m_MaxSlider->setValue(iValue + 1); } return; } UpdateLUT(); } GoFigure2-v0.9.0/Code/GUI/lib/TransferFunctionEditor/hoverpoints.cpp0000644000175000017500000003542211667757442025173 0ustar mathieumathieu/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the demonstration applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifdef QT_OPENGL_SUPPORT #include #endif #include "hoverpoints.h" #define printf HoverPoints::HoverPoints(QWidget *widget, PointShape shape) : QObject(widget) { m_widget = widget; widget->installEventFilter(this); widget->setAttribute(Qt::WA_AcceptTouchEvents); m_oldSize[0] = -1; m_oldSize[1] = -1; m_connectionType = CurveConnection; m_sortType = NoSort; m_shape = shape; m_pointPen = QPen(QColor(255, 255, 255, 191), 1); m_connectionPen = QPen(QColor(255, 255, 255, 127), 2); m_pointBrush = QBrush(QColor(191, 191, 191, 127)); m_pointSize = QSize(11, 11); m_currentIndex = -1; m_editable = true; m_enabled = true; if(shape == HoverPoints::CircleShape){ m_pointPen = QPen(QColor(50, 50, 50, 191), 1); m_connectionPen = QPen(QColor(0, 0, 0, 127), 2); m_enabled = false; } connect(this, SIGNAL(pointsChanged(QPolygonF)), m_widget, SLOT(update())); } void HoverPoints::setEnabled(bool enabled) { if (m_enabled != enabled) { m_enabled = enabled; m_widget->update(); } } bool HoverPoints::eventFilter(QObject *object, QEvent *event) { if (object == m_widget) { switch (event->type()) { case QEvent::MouseButtonPress: { if(m_shape != CircleShape || !m_enabled) break; if (!m_fingerPointMapping.isEmpty()) return true; QMouseEvent *me = (QMouseEvent *) event; QPointF clickPos = me->pos(); int index = -1; for (int i=0; ibutton() == Qt::LeftButton) { if (index == -1) { if (!m_editable) return false; int pos = 0; // Insert sort for x or y if (m_sortType == XSort) { for (int i=0; i clickPos.x()) { pos = i; break; } } else if (m_sortType == YSort) { for (int i=0; i clickPos.y()) { pos = i; break; } } m_points.insert(pos, clickPos); m_locks.insert(pos, 0); m_currentIndex = pos; firePointChange(); } else { m_currentIndex = index; } return true; } else if (me->button() == Qt::RightButton) { if (index >= 0 && m_editable) { if (m_locks[index] == 0) { m_locks.remove(index); m_points.remove(index); } firePointChange(); return true; } } } break; case QEvent::MouseButtonRelease: if(m_shape != CircleShape || !m_enabled) break; if (!m_fingerPointMapping.isEmpty()) return true; m_currentIndex = -1; break; case QEvent::MouseMove: if(m_shape != CircleShape || !m_enabled) break; if (!m_fingerPointMapping.isEmpty()) return true; if (m_currentIndex >= 0) movePoint(m_currentIndex, ((QMouseEvent *)event)->pos()); break; case QEvent::TouchBegin: case QEvent::TouchUpdate: { if(m_shape != CircleShape || !m_enabled) break; const QTouchEvent *const touchEvent = static_cast(event); const QList points = touchEvent->touchPoints(); const qreal pointSize = qMax(m_pointSize.width(), m_pointSize.height()); foreach (const QTouchEvent::TouchPoint &touchPoint, points) { const int id = touchPoint.id(); switch (touchPoint.state()) { case Qt::TouchPointPressed: { // find the point, move it QSet activePoints = QSet::fromList(m_fingerPointMapping.values()); int activePoint = -1; qreal distance = -1; const int pointsCount = m_points.size(); const int activePointCount = activePoints.size(); if (pointsCount == 2 && activePointCount == 1) { // only two points activePoint = activePoints.contains(0) ? 1 : 0; } else { for (int i=0; i::iterator it = m_fingerPointMapping.find(id); movePoint(it.value(), touchPoint.pos()); m_fingerPointMapping.erase(it); } break; case Qt::TouchPointMoved: { // move the point const int pointIdx = m_fingerPointMapping.value(id, -1); if (pointIdx >= 0) // do we track this point? movePoint(pointIdx, touchPoint.pos()); } break; default: break; } } if (m_fingerPointMapping.isEmpty()) { event->ignore(); return false; } else { return true; } } break; case QEvent::TouchEnd: if(m_shape != CircleShape || !m_enabled) break; if (m_fingerPointMapping.isEmpty()) { event->ignore(); return false; } return true; break; // even if !enable, we should update the position of the points on // resize event case QEvent::Resize: { QResizeEvent *e = (QResizeEvent *) event; if (m_oldSize[0] == 0 || m_oldSize[1] == 0) break; qreal stretch_x = e->size().width() / qreal(m_oldSize[0]); qreal stretch_y = e->size().height() / qreal(m_oldSize[1]); for (int i=0; im_oldSize[0] = e->size().width(); m_oldSize[1] = e->size().height(); break; } case QEvent::Paint: { if(!m_enabled) break; QWidget *that_widget = m_widget; m_widget = 0; QApplication::sendEvent(object, event); m_widget = that_widget; paintPoints(); return true; } default: break; } } return false; } void HoverPoints::paintPoints() { QPainter p; p.begin(m_widget); p.setRenderHint(QPainter::Antialiasing); if (m_connectionPen.style() != Qt::NoPen && m_connectionType != NoConnection) { p.setPen(m_connectionPen); p.drawPolyline(m_points); } if(m_shape != CircleShape) return; p.setPen(m_pointPen); p.setBrush(m_pointBrush); for (int i=0; i right || (lock & HoverPoints::LockToRight)) p.setX(right); if (p.y() < top || (lock & HoverPoints::LockToTop)) p.setY(top); else if (p.y() > bottom || (lock & HoverPoints::LockToBottom)) p.setY(bottom); return p; } void HoverPoints::setPoints(const QPolygonF &points) { if (points.size() != m_points.size()) m_fingerPointMapping.clear(); m_points.clear(); for (int i=0; i 0) { m_locks.resize(m_points.size()); m_locks.fill(0); } } void HoverPoints::movePoint(int index, const QPointF &point, bool emitUpdate) { m_points[index] = bound_point(point, boundingRect(), m_locks.at(index)); if (emitUpdate) firePointChange(); } inline static bool x_less_than(const QPointF &p1, const QPointF &p2) { return p1.x() < p2.x(); } inline static bool y_less_than(const QPointF &p1, const QPointF &p2) { return p1.y() < p2.y(); } void HoverPoints::firePointChange() { if (m_sortType != NoSort) { QPointF oldCurrent; if (m_currentIndex != -1) { oldCurrent = m_points[m_currentIndex]; } if (m_sortType == XSort) qSort(m_points.begin(), m_points.end(), x_less_than); else if (m_sortType == YSort) qSort(m_points.begin(), m_points.end(), y_less_than); // Compensate for changed order... if (m_currentIndex != -1) { for (int i=0; i #include //std #include #include // gofigure class HoverPoints; class GoTransferFunctionWidget; // qt class QPolygonF; class QTextStream; class QPushButton; class QSlider; //vtk class vtkLookupTable; class vtkImageAccumulate; class vtkPiecewiseFunction; class GoTransferFunctionEditorWidget : public QWidget { Q_OBJECT public: explicit GoTransferFunctionEditorWidget( QString iChannel, const std::vector& iColor, std::vector iLUTParameters, double iMax, QWidget *parent = 0 ); /** * \brief Add points to both LUT and Opacity transfer function * \param[in] iPoints map containing the points. The key is the "X" poisition, * the value is the "Y" position. */ void AddPoints( const std::map& iPoints); /** * \brief Add LUT to the GoTransferFunctionEditorWidget * \param[in] iLUT the vtk Look Up Table */ void AddLookupTable(vtkLookupTable* iLUT); /** * \brief 1- Add Histogram to the GoTransferFunctionEditorWidget * 2- Convert it to QVector * 3- Add it to the m_TFWidget * 4- Update the m_TFWidget * \param[in] iHistogram a vtkImage Accumulate */ void AddHistogram(vtkImageAccumulate* iHistogram); /** * \brief Add color of the channel to the GoTransferFunctionEditorWidget. It modifies m_Color. m_Color is necessary for reset and to initialize the m_TFWidget; \param[in] iColor is a vector of size 4 (RGBA), with values between 0 and 255. Add color then normalize the values between 0 and 1. */ void AddColor(const std::vector& iColor); /** * \brief Add name of the channel to the GoTransferFunctionEditorWidget. * \param[in] iChannel name of the channel */ void AddName(QString iChannel); /** * \brief Add pointer to the opacity TF for a direct access. */ void AddOpacityTransferFunction(vtkPiecewiseFunction* iOpacity); /** * \bried Set maximum value of the current channel. Useful to adjust the range of the LUT. */ void SetMaximumValue( double iMax); public slots: /** * \brief Update the LUT based on the min, max and gamma. * It updates the m_TFWidget and the visualition. */ void UpdateLUT(); /** * \brief Opens a QColorDialog. If chosen color is valid, then: 1- Modify push button color 2- Modify m_TFWidget color 3- Update LUT */ void ChangeColor(); /** * \brief Reset the channel to its original state (color, LUT, opacity) */ void ResetLUT(); /** * \brief Apply changes (color, min, manx, gamma, opacity TF) to the channel. It modifies informations relative to the given channel in the QGoImageStructure. */ void ApplyChanges(); // opacity TF // might be buggy, to be checked void updateOpacityTF(); /** * \brief Show/hide histogram in m_TFWidget * \param[in] iShow true: paint current histogram, false paint an empty histogram */ void ShowHistogram(bool iShow); /** * \brief Adjust window/level between the input values. * LUT (using the gamma value) will be calculated between those 2 points. * Before iMin, LUT = (0, 0, 0) * After iMax, LUT = ChannelColor. * It modifies the values of the sliders then update the LUT. * \param[in] iMin pixel intensity below which the pixels will be mapped to black * \param[in] iMax pixel intensity above which the pixels will be mapped to the channel color */ void AdjustWindowLevel(double iMin, double iMax); /** * \brief When Min and Max sliders change, update the value of the one which * sent the signal, if it doesn't overlap with the other one. * param[in] iValue new value. Else modify its value back to original. */ void updateSliders(int iValue); signals: /** * \brief Modify the visualization when the LUT or opacity changed */ void updateVisualization(); /** * \brief Modify the image structure when apply clicked */ void UpdateImageStructure(QString, std::map< unsigned int, unsigned int>, QColor, int, int, int); private: /** * \brief Convenience method to convert a QPolygonF to a std::map * \param[in] iPoints QPolygonF to be converted * \param[out] iMap std::map to be filled */ void ConvertQPolygonFToSTDMap( const QPolygonF& iPoints, std::map< unsigned int, unsigned int>& iMap); /** * \brief Convenience method to convert a std::map to a QPolygonF * \param[in] iMap std::map to be converted * \param[out] iPoints QPolygonF to be filled */ void ConvertSTDMapToQPolygonF( const std::map< unsigned int, unsigned int>& iMap, QPolygonF& iPoints); /** * \brief Push button to modify the color */ QPushButton* m_ColorPushButton; /** * \brief The widget containing the shade, histogram, LUT and opacity TF */ GoTransferFunctionWidget *m_TFWidget; /** * \brief Slider to modify the value of gamma */ QSlider* m_GammaSlider; /** * \brief Slider to modify the min value */ QSlider* m_MinSlider; /** * \brief Slider to modify the max value */ QSlider* m_MaxSlider; /** * \brief Current color of the channel */ QColor m_Color; /** * \brief Original color of the channel */ QColor m_Color_original; /** * \brief Name of the channel */ QString m_Channel; /** * \brief Pointer to the channel LUT */ vtkLookupTable *m_LUT; /** * \brief Pointer to the channel opacity LUT */ vtkPiecewiseFunction *m_OpacityTF; /** * \brief Histogram of the current channel for current time point */ QVector m_Histogram; /** * \brief Maximum pixel intensity for the channel at current time point */ double m_Max; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionWidget.h0000644000175000017500000001512611667757442027203 0ustar mathieumathieu/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the demonstration applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoTransferFunctionWidget_h #define __GoTransferFunctionWidget_h #include class HoverPoints; // vtk class vtkLookupTable; class GoTransferFunctionWidget : public QWidget { Q_OBJECT public: GoTransferFunctionWidget(QColor iColor, double iMax, QWidget *parent); /** * \brief Paint event: 1- generate new shade is size of the widget changed 2- draw the shade 3- draw the histogram */ void paintEvent(QPaintEvent *e); QSize sizeHint() const { return QSize(150, 40); } QPolygonF points() const; /** * \brief Add points to the opacity transfer function. * Called at initialization or reset. * \param[in] iPoints points to create the opacity transfer function */ void AddPointsToOpacityTF(const QPolygonF& iPoints); /** * \brief Add points to the LUT. * Called at initialization or reset. * \param[in] iPoints points to create the opacity transfer function */ void AddPointsToLUT(const QPolygonF& iPoints); /** * \brief Modify LUT with given parameters. * \param[in] iLUT pointere to the LUT * \param[in] iGamma gamma value * \param[in] iMin min window value * \param[in] iMin max window value */ void UpdateLookupTable(vtkLookupTable* iLUT, qreal iGamma, qreal iMin, qreal iMax); /** * \brief Set the histogram */ void SetHistogram(QVector iHistogram); /** * \brief Reset the opacity TF from min to max, from 0 to 1 */ void ResetOpacity(); /** * \brief Set the color of the channel. * 1- Modify the color * 2- Update the shade * 3- Update the visualization */ void setColor(QColor iColor); /** * \brief Set maximum pixel intensity for current channel at current T point */ void setMax(double iMax); signals: /** * \brief Point added in the Opacity TF then update the visualization */ void opacityChanged(); /** * \brief enable/disable opacity TF */ void enableOpacityTF(bool); /** * \brief enable/disable LUT curve */ void enableLUTCurve(bool); private: /** * \brief Generate the shade when the color changed. */ void generateShade(); /** * \brief Color of the current channel */ QColor m_color; /** * \brief Shade generated, based on the color */ QImage m_shade; /** * \brief Opacity transfer function points */ HoverPoints *m_OpacityTFPoints; /** * \brief LUT points */ HoverPoints *m_LUTPoints; /** * \brief the histogram */ QVector m_Histogram; /** * \brief Maximum pixel value in the current channel at given time point */ double m_Max; }; #endif GoFigure2-v0.9.0/Code/GUI/lib/TransferFunctionEditor/QGoTransferFunctionDockWidget.cxx0000644000175000017500000001035611667757442030500 0ustar mathieumathieu /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTransferFunctionDockWidget.h" #include "GoTransferFunctionEditorWidget.h" QGoTransferFunctionDockWidget:: QGoTransferFunctionDockWidget( QWidget *iParent) : QGoDockWidget(iParent) { this->setupUi(this); QIcon Navigation; Navigation.addPixmap(QPixmap( QString::fromUtf8(":/fig/transferFunction.png") ), QIcon::Normal, QIcon::Off); this->m_ToggleAction->setIcon(Navigation); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QGoTransferFunctionDockWidget:: ~QGoTransferFunctionDockWidget() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTransferFunctionDockWidget:: AddTransferFunction(QString iName, GoTransferFunctionEditorWidget* iTF) { this->tabWidget->addTab(iTF, iName); int nb_index = this->tabWidget->count(); this->tabWidget->setCurrentIndex(nb_index); this->tabWidget->setCurrentIndex(0); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoTransferFunctionDockWidget:: GetCurrentWidget() { return this->tabWidget->currentIndex(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QWidget* QGoTransferFunctionDockWidget:: GetWidget(int iIndex) { return this->tabWidget->widget(iIndex); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTransferFunctionDockWidget:: SetCurrentWidget(int iIndex) { return this->tabWidget->setCurrentIndex(iIndex); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTransferFunctionDockWidget:: DeleteTabs() { int nb_index = this->tabWidget->count(); for( int i = nb_index; i>0; i--) { this->tabWidget->removeTab(i-1); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int QGoTransferFunctionDockWidget:: GetNumberOfTabs() { return this->tabWidget->count(); } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/GUI/lib/SnapshotHelper.cxx0000644000175000017500000001661511667757442021134 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "SnapshotHelper.h" #include "vtkRenderWindow.h" #include "vtkRendererCollection.h" #include "vtkImageData.h" #include "vtkImageClip.h" #include "vtkImagePermute.h" #include "vtkImageResample.h" #include "vtkWindowToImageFilter.h" #include "vtkSmartPointer.h" #include "vtkBMPWriter.h" #include "vtkPostScriptWriter.h" #include "vtkJPEGWriter.h" #include "vtkPNGWriter.h" #include "vtkTIFFWriter.h" #include "QVTKWidget.h" #include "vtkImageWriterHelper.h" #include "vtkViewImage2D.h" //------------------------------------------------------------------------- bool BuildScreenshotFromImage(vtkImageData *image, vtkImageData *screenshot, int tsize) { if ( !image || !screenshot ) { return false; } // Empty image, remove thumbnail/screenshot int image_dims[3]; image->GetDimensions(image_dims); if ( image_dims[0] == 0 || image_dims[1] == 0 || image_dims[2] == 0 ) { return false; } vtkImageData *resample_input, *resample_output; // First, let's make sure we are processing the image as it // is by clipping its UpdateExtent. By doing so, we prevent our resample // and permute filter the process the image's *whole* extent. vtkSmartPointer< vtkImageClip > clip = vtkSmartPointer< vtkImageClip >::New(); clip->SetInput(image); clip->SetOutputWholeExtent( image->GetUpdateExtent() ); clip->Update(); // Permute, as a convenience int clip_dims[3]; clip->GetOutput()->GetDimensions(clip_dims); vtkSmartPointer< vtkImagePermute > permute = vtkSmartPointer< vtkImagePermute >::New(); if ( clip_dims[2] != 1 ) { permute->SetInput( clip->GetOutput() ); if ( clip_dims[0] == 1 ) { permute->SetFilteredAxes(1, 2, 0); } else { permute->SetFilteredAxes(0, 2, 1); } resample_input = permute->GetOutput(); } else { resample_input = clip->GetOutput(); } resample_input->Update(); int resample_input_dims[3]; //, resample_output_dims[3]; resample_input->GetDimensions(resample_input_dims); double *resample_input_spacing = resample_input->GetSpacing(); int large_dim = 0, small_dim = 1; if ( resample_input_dims[0] < resample_input_dims[1] ) { large_dim = 1; small_dim = 0; } if ( tsize != 0 ) { vtkSmartPointer< vtkImageResample > resample = vtkSmartPointer< vtkImageResample >::New(); resample->SetInput(resample_input); resample->SetInterpolationModeToCubic(); resample->SetDimensionality(2); // Create the screenshot double factor = static_cast< double >( tsize ) / static_cast< double >( resample_input_dims[large_dim] ); resample->SetAxisMagnificationFactor(large_dim, factor); resample->SetAxisMagnificationFactor( small_dim, factor * ( resample_input_spacing[small_dim] / resample_input_spacing[large_dim] ) ); resample->Update(); resample_output = resample->GetOutput(); // resample_output->GetDimensions(resample_output_dims); screenshot->ShallowCopy(resample_output); } else { screenshot->ShallowCopy(resample_input); } return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- bool BuildScreenshotFromRenderWindow( vtkRenderWindow *win, vtkImageData *screenshot, int tsize) { if ( win && screenshot ) { vtkSmartPointer< vtkWindowToImageFilter > filter = vtkSmartPointer< vtkWindowToImageFilter >::New(); filter->ShouldRerenderOff(); filter->SetInput(win); filter->Update(); bool res = BuildScreenshotFromImage(filter->GetOutput(), screenshot, tsize); return res; } return false; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- QString SnapshotView(QVTKWidget *iWidget, const GoFigure::FileType & iType, const QString & iBaseName, const unsigned int & iSnapshotId) { vtkSmartPointer< vtkImageData > image = vtkSmartPointer< vtkImageData >::New(); BuildScreenshotFromRenderWindow(iWidget->GetRenderWindow(), image); QString filename = iBaseName; filename.append( QString("%1").arg(iSnapshotId) ); switch ( iType ) { case GoFigure::BMP: { filename.append(".bmp"); vtkWriteImage< vtkBMPWriter >(image, filename); break; } case GoFigure::EPS: { filename.append(".eps"); vtkWriteImage< vtkPostScriptWriter >(image, filename); break; } case GoFigure::JPEG: { filename.append(".jpeg"); vtkWriteImage< vtkJPEGWriter >(image, filename); break; } case GoFigure::PNG: { filename.append(".png"); vtkWriteImage< vtkPNGWriter >(image, filename); break; } case GoFigure::TIFF: { filename.append(".tiff"); vtkWriteImage< vtkTIFFWriter >(image, filename); break; } default: { std::cerr << "FileType is not supported for Snapshot" << std::endl; return QString(); } } return filename; } //------------------------------------------------------------------------- void SetupViewGivenQVTKWidget(vtkViewImage2D *iView, QVTKWidget *iWidget) { vtkRenderWindow *renwin = iWidget->GetRenderWindow(); iView->SetRenderWindow(renwin); iView->SetRenderer( renwin->GetRenderers()->GetFirstRenderer() ); iView->SetupInteractor( iWidget->GetInteractor() ); } GoFigure2-v0.9.0/Code/GUI/lib/QGoDockWidget.cxx0000644000175000017500000000537011667757442020624 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoDockWidget.h" QGoDockWidget::QGoDockWidget(QWidget* iParent) : QDockWidget(iParent) { this->m_ToggleAction = new QAction(this); this->m_ToggleAction->setCheckable(true); QObject::connect(m_ToggleAction, SIGNAL(toggled(bool) ), this, SLOT(setVisible(bool) ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoDockWidget::~QGoDockWidget() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QAction* QGoDockWidget::toggleViewAction() { return this->m_ToggleAction; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoDockWidget::closeEvent(QCloseEvent *iEvent) { (void)iEvent; this->m_ToggleAction->setChecked(false); } GoFigure2-v0.9.0/Code/GUI/lib/QGoComboBox.h0000755000175000017500000001163211667757442017736 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoComboBox_h #define __QGoComboBox_h #include #include "QGoGUILibConfigure.h" /** \class QGoComboBox \brief inherits from Qt QCombobox but add a the end of the list of items, 1 or 2 items: the first one to add new items and the second one to delete them \ingroup GUI */ class QGOGUILIB_EXPORT QGoComboBox:public QComboBox { Q_OBJECT public: /** \brief if the string iTextToDelete is empty, there will be only the add a new item at the end of the list */ explicit QGoComboBox(std::string iTextToAddANewOne, QWidget *iparent = 0, std::string iTextToDelete = ""); virtual ~QGoComboBox(); typedef std::vector< std::pair< std::string, std::string > > NamesDescrContainerType; /** \brief select the current item located at iIndex and send a signal with the name of this item. \param[in] iIndex index to select and at which to get the info */ void SetCurrentItemAndActivate(int iIndex); /** \overload */ void SetCurrentItemAndActivate(std::string iItemText); signals: void AddANewOneActivated(); void ItemSelected(std::string); void DeleteActivated(); public slots: /** \brief call the method SetItemsFromList and send a signal with the current index. \param[in] iListItems contains the names of the items to be displayed in the combobox */ virtual void InitializeTheList(QStringList iListItems); /** \overload */ virtual void InitializeTheList(NamesDescrContainerType iItemsData); /** \brief clear the items already in the combobox,displayed the one in the QStringList and the items to add/delete \param[in] iDataFromList contains the names of the items to be displayed in the combobox */ virtual void SetItemsFromList(QStringList iDataFromList); /** \overload */ virtual void SetItemsFromList(NamesDescrContainerType iItemsData); /** \brief set the activated item corresponding to the iTemText (no need to emit the signal ItemSelected) \param[in] iItemText name of the item to be set to activated in the combobox */ void SetCurrentItem(std::string iItemText); protected: std::string m_TextToAddANewOne; std::string m_TextToDelete; int m_NumberOfItemsAfterList; /** \brief Add the "Add a new one..." and "Delete..." text items at the end of the items list */ void AddItemsEndOfList(); /** \brief Get a QStringList with the names of the item from a NamesDescrContainerType \param[in] iContainer contains all the items with their name and description \return QStringList with the names of the items */ QStringList GetQStringListNames(NamesDescrContainerType iContainer); /** \brief add the "add new one" item at the end of the list */ void SetAddText(); protected slots: /** \brief check which item has been clicked and emit the corresponding signal: addanewone, deleteactivated or itemselected \param[in] iIndexActivatedItem index of the clicked item */ void CheckUserAction(int iIndexActivatedItem); /** \brief call the signal to send the index of the activated item. \param[in] iIndexActivatedItem index of the activated item */ virtual void EmitActivatedItem(int iIndexActivatedItem); }; #endif GoFigure2-v0.9.0/Code/CMakeLists.txt0000644000175000017500000000051211667757442017004 0ustar mathieumathieu# add subdirectories ADD_SUBDIRECTORY( ExternalCode ) ADD_SUBDIRECTORY( Database ) ADD_SUBDIRECTORY( IO ) ADD_SUBDIRECTORY( Filters ) ADD_SUBDIRECTORY( GUI ) FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) INSTALL( FILES ${__source_file_h} DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Code/Attic/0000755000175000017500000000000011667757442015312 5ustar mathieumathieuGoFigure2-v0.9.0/Code/Attic/QGoPrintDatabase.ui0000644000175000017500000000262711667757442021010 0ustar mathieumathieu WidgetPrintDatabase 0 0 679 417 Form 0 0 75 false true false QTabWidget::West 0 Lineage GoFigure2-v0.9.0/Code/Attic/MeshTextFileImport.cxx0000644000175000017500000001460311667757442021576 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "MeshTextFileImport.h" #include "vtkPolyDataReader.h" #include "vtkPolyData.h" #include "MegaCaptureHeaderReader.h" #include "vtkMySQLDatabase.h" #include "QueryDataBaseHelper.h" #include "GoDBCoordinateRow.h" #include "GoDBMeshRow.h" MeshTextFileImport::MeshTextFileImport(const std::string & iServerName, const std::string & iLogin, const std::string & iPassword, const std::string & iDBName, const unsigned int & iImagingSessionId) : m_ImagingSessionId(iImagingSessionId) { m_DBConnector = OpenDatabaseConnection(iServerName, iLogin, iPassword, iDBName); } MeshTextFileImport:: ~MeshTextFileImport() { m_DBConnector->Delete(); } void MeshTextFileImport::SetDirectory(const std::string & iDir) { m_Directory = iDir; } void MeshTextFileImport::SetFileName(const std::string & iFileName) { m_FileName = iFileName; } void MeshTextFileImport::Read() { std::string filename0 = m_Directory; filename0 += m_FileName; std::string line; std::ifstream ifs(filename0.c_str(), std::ifstream::in); if ( ifs.is_open() ) { // getline(ifs, line); //HeaderFile CaltechZebrafishSubsetData.meg std::string word; ifs >> word >> m_MegaCaptureHeaderFile; std::string filename1 = m_Directory; filename1 += m_MegaCaptureHeaderFile; // Read megacapture header MegaCaptureHeaderReader header_reader(filename1); header_reader.Read(); m_NumberOfChannels = header_reader.m_NumberOfChannels; double spacing[3]; spacing[0] = header_reader.m_VoxelSizeX; spacing[1] = header_reader.m_VoxelSizeY; spacing[2] = header_reader.m_VoxelSizeZ; getline(ifs, line); // getline(ifs, line); // NumberOfMeshes 1622 ifs >> word >> m_NumberOfMeshes; getline(ifs, line); unsigned int ch; for ( unsigned int i = 0; i < m_NumberOfMeshes; i++ ) { InternalMeshStructure mesh(m_NumberOfChannels); // getline(ifs, line); // TrackId 1685 ifs >> word >> mesh.m_TrackId; // TCoord 2 ifs >> word >> mesh.m_TCoord; getline(ifs, line); // Centroid 89.6544 2.1618 29.8110 // useless information getline(ifs, line); // Volume 531.28 ifs >> word >> mesh.m_Volume; std::string filename; std::string filename2 = m_Directory; //Filename 2_1.vtk ifs >> word >> filename; getline(ifs, line); filename2 += filename; // Read filename vtkPolyDataReader *reader = vtkPolyDataReader::New(); reader->SetFileName( filename2.c_str() ); reader->Update(); vtkPolyData *vtk_mesh = reader->GetOutput(); double bounds[6]; vtk_mesh->GetBounds(bounds); mesh.m_XMin = static_cast< unsigned int >( bounds[0] / spacing[0] ); mesh.m_XMax = static_cast< unsigned int >( bounds[1] / spacing[0] ); mesh.m_YMin = static_cast< unsigned int >( bounds[2] / spacing[1] ); mesh.m_YMax = static_cast< unsigned int >( bounds[3] / spacing[1] ); mesh.m_ZMin = static_cast< unsigned int >( bounds[4] / spacing[2] ); mesh.m_ZMax = static_cast< unsigned int >( bounds[5] / spacing[2] ); mesh.m_Points = vtk_mesh; for ( ch = 0; ch < m_NumberOfChannels; ch++ ) { // getline(ifs, line); // Channel 0 getline(ifs, line); // AverageValue 119.68 ifs >> word >> mesh.m_AverageIntensity[ch]; m_ListOfMeshes.push_back(mesh); getline(ifs, line); // getline(ifs, line); } // getline(ifs, line); SaveMeshInDataBase(mesh); reader->Delete(); } } } void MeshTextFileImport::SaveMeshInDataBase(const InternalMeshStructure & iMesh) { GoDBCoordinateRow coord_min; coord_min.SetField< unsigned int >("XCoord", iMesh.m_XMin); coord_min.SetField< unsigned int >("YCoord", iMesh.m_YMin); coord_min.SetField< unsigned int >("ZCoord", iMesh.m_ZMin); coord_min.SetField< unsigned int >("TCoord", iMesh.m_TCoord); GoDBCoordinateRow coord_max; coord_max.SetField< unsigned int >("XCoord", iMesh.m_XMax); coord_max.SetField< unsigned int >("YCoord", iMesh.m_YMax); coord_max.SetField< unsigned int >("ZCoord", iMesh.m_ZMax); coord_max.SetField< unsigned int >("TCoord", iMesh.m_TCoord); GoDBMeshRow mesh_row(m_DBConnector, iMesh.m_Points, coord_min, coord_max, m_ImagingSessionId); mesh_row.SetColor(255, 255, 0, 255, "KishoreMeshColor", m_DBConnector); int mesh_id = mesh_row.SaveInDB(m_DBConnector); std::cout << mesh_id << std::endl; }GoFigure2-v0.9.0/Code/Attic/QGoTabImageView4D.cxx0000644000175000017500000011677211667757442021157 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTabImageView4D.h" #include "QGoImageView3D.h" #include "QGoLUTDialog.h" #include "QGoNavigationDockWidget.h" #include "QGoContourManualSegmentationWidget.h" #ifdef ENABLEVIDEORECORD #include "QGoVideoRecorder.h" #endif #include "SnapshotHelper.h" #include "vtkImageData.h" #include "vtkLookupTable.h" #include "vtkImageAppendComponents.h" #include "vtkContourWidget.h" #include "vtkOrientedGlyphContourRepresentation.h" #include "vtkPolyData.h" #include "vtkProperty.h" #include "vtkImageActorPointPlacer.h" #include #include #include #include #include #include //-------------------------------------------------------------------------- QGoTabImageView4D::QGoTabImageView4D(QWidget *iParent) : QGoTabElementBase(iParent), m_XYZImage(0), m_XYTImage(0), m_BackgroundColor(Qt::black), m_TimePoint(-1), m_ZSlice(-1), m_FirstUpdate(true) { m_Reader1 = itk::MegaCaptureReader::New(); m_Reader2 = itk::MegaCaptureReader::New(); m_XYZImage = vtkSmartPointer< vtkImageData >::New(); m_XYTImage = vtkSmartPointer< vtkImageData >::New(); setupUi(this); for ( int i = 0; i < 3; i++ ) { this->m_ContourRepresentation.push_back( vtkSmartPointer< vtkOrientedGlyphContourRepresentation >::New() ); this->m_ContourRepresentation.back()->GetProperty()->SetColor(0., 1., 1.); this->m_ContourRepresentation.back()->GetLinesProperty()->SetColor(1., 0., 1.); this->m_ContourRepresentation.back()->GetActiveProperty()->SetColor(1., 1., 0.); this->m_ContourWidget.push_back( vtkSmartPointer< vtkContourWidget >::New() ); this->m_ContourWidget.back()->SetPriority(10.0); this->m_ContourWidget.back()->SetInteractor( m_XYZImageView->GetInteractor(i) ); this->m_ContourWidget.back()->Off(); } CreateVisuDockWidget(); CreateManualSegmentationdockWidget(); #ifdef ENABLEVIDEORECORD m_VideoRecorderWidget = new QGoVideoRecorder(this); #endif CreateAllViewActions(); // CreateModeActions(); ReadSettings(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::CreateAllViewActions() { QActionGroup *group = new QActionGroup(this); QAction *OctoViewAction = new QAction(tr("Octo-View"), this); OctoViewAction->setCheckable(true); OctoViewAction->setChecked(true); group->addAction(OctoViewAction); QObject::connect( OctoViewAction, SIGNAL( triggered() ), this, SLOT( Octview() ) ); m_ViewActions.push_back(OctoViewAction); QAction *XYZQuadViewAction = new QAction(tr("Quad-View XYZ"), this); XYZQuadViewAction->setCheckable(true); XYZQuadViewAction->setChecked(true); group->addAction(XYZQuadViewAction); m_ViewActions.push_back(XYZQuadViewAction); QObject::connect( XYZQuadViewAction, SIGNAL( triggered() ), this, SLOT( QuadviewXYZ() ) ); QAction *XYTQuadViewAction = new QAction(tr("Quad-View XYT"), this); XYTQuadViewAction->setCheckable(true); XYTQuadViewAction->setChecked(true); group->addAction(XYTQuadViewAction); m_ViewActions.push_back(XYTQuadViewAction); QObject::connect( XYTQuadViewAction, SIGNAL( triggered() ), this, SLOT( QuadviewXYT() ) ); QAction *FullScreenXYAction = new QAction(tr("Full-Screen XY"), this); FullScreenXYAction->setCheckable(true); group->addAction(FullScreenXYAction); m_ViewActions.push_back(FullScreenXYAction); QObject::connect( FullScreenXYAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewXY() ) ); QAction *FullScreenXZAction = new QAction(tr("Full-Screen XZ"), this); FullScreenXZAction->setCheckable(true); group->addAction(FullScreenXZAction); m_ViewActions.push_back(FullScreenXZAction); QObject::connect( FullScreenXZAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewXZ() ) ); QAction *FullScreenYZAction = new QAction(tr("Full-Screen YZ"), this); FullScreenYZAction->setCheckable(true); group->addAction(FullScreenYZAction); m_ViewActions.push_back(FullScreenYZAction); QObject::connect( FullScreenYZAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewYZ() ) ); QAction *FullScreenXYZAction = new QAction(tr("Full-Screen XYZ"), this); FullScreenXYZAction->setCheckable(true); group->addAction(FullScreenXYZAction); m_ViewActions.push_back(FullScreenXYZAction); QObject::connect( FullScreenXYZAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewXYZ() ) ); // now FullScreen actions related to the XYT view QAction *FullScreenXTAction = new QAction(tr("Full-Screen XT"), this); FullScreenXTAction->setCheckable(true); group->addAction(FullScreenXTAction); m_ViewActions.push_back(FullScreenXTAction); QObject::connect( FullScreenXTAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewXT() ) ); QAction *FullScreenYTAction = new QAction(tr("Full-Screen YT"), this); FullScreenYTAction->setCheckable(true); group->addAction(FullScreenYTAction); m_ViewActions.push_back(FullScreenYTAction); QObject::connect( FullScreenYTAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewYT() ) ); QAction *FullScreenXYTAction = new QAction(tr("Full-Screen XYT"), this); FullScreenXYTAction->setCheckable(true); group->addAction(FullScreenXYTAction); m_ViewActions.push_back(FullScreenXYTAction); QObject::connect( FullScreenXYTAction, SIGNAL( triggered() ), this, SLOT( FullScreenViewXYT() ) ); QAction *separator = new QAction(this); separator->setSeparator(true); m_ViewActions.push_back(separator); QAction *LookupTableAction = new QAction(tr("Lookup Table"), this); LookupTableAction->setStatusTip( tr(" Change the associated lookup table") ); // Here write the connection QObject::connect( LookupTableAction, SIGNAL( triggered() ), this, SLOT( ChangeLookupTable() ) ); m_ViewActions.push_back(LookupTableAction); QAction *ScalarBarAction = new QAction(tr("Display Scalar Bar"), this); ScalarBarAction->setCheckable(true); m_ViewActions.push_back(ScalarBarAction); QObject::connect( ScalarBarAction, SIGNAL( toggled(bool) ), this, SLOT( ShowScalarBar(bool) ) ); QAction *BackgroundColorAction = new QAction(tr("Background Color"), this); m_ViewActions.push_back(BackgroundColorAction); QObject::connect( BackgroundColorAction, SIGNAL( triggered() ), this, SLOT( ChangeBackgroundColor() ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::CreateModeToolBar(QMenu* iMenu, QToolBar* iToolBar) { this->m_ModeToolBar = new QGoToolBarStatus(iToolBar, iMenu, Qt::TopToolBarArea, true, true, this); QActionGroup *group = new QActionGroup(this); //QAction *ManualEditingAction = new QAction(tr("Manual-Editing"), this); //ManualEditingAction->setCheckable(true); //QIcon ManualEditingIcon; //ManualEditingIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/manual-editing.png") ), // QIcon::Normal, QIcon::Off); //ManualEditingAction->setIcon(ManualEditingIcon); //group->addAction(ManualEditingAction); //this->m_ModeActions.push_back(ManualEditingAction); /** \todo implement the manual editing mode*/ //QObject::connect( ManualEditingAction, SIGNAL( triggered() ), // this, SLOT( ManualEditingMode() ) ); QAction *DefaultAction = new QAction(tr("Default"), this); DefaultAction->setCheckable(true); DefaultAction->setChecked(true); /** \todo add an icon for default*/ /* QIcon DefaultIcon; DefaultIcon.addPixmap( QPixmap(QString::fromUtf8(":/fig/xy.png")), QIcon::Normal, QIcon::Off ); DefaultAction->setIcon( DefaultIcon );*/ group->addAction(DefaultAction); this->m_ModeToolBar->m_VectorAction.push_back(DefaultAction); /** \todo implement default mode*/ //QObject::connect( DefaultAction, SIGNAL( triggered() ), // this, SLOT( DefaultMode() ) ); this->m_ToolBarList.push_back(this->m_ModeToolBar); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView4D::CreateVisuDockWidget() { m_NavigationDockWidget = new QGoNavigationDockWidget(this, GoFigure::FOUR_D); QObject::connect( m_NavigationDockWidget, SIGNAL( XSliceChanged(int) ), this, SLOT( SetXSlice(int) ) ); QObject::connect( this, SIGNAL( XSliceChanged(int) ), m_NavigationDockWidget, SLOT( SetXSlice(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( YSliceChanged(int) ), this, SLOT( SetYSlice(int) ) ); QObject::connect( this, SIGNAL( YSliceChanged(int) ), m_NavigationDockWidget, SLOT( SetYSlice(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( ZSliceChanged(int) ), this, SLOT( SetZSlice(int) ) ); QObject::connect( this, SIGNAL( ZSliceChanged(int) ), m_NavigationDockWidget, SLOT( SetZSlice(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( TSliceChanged(int) ), this, SLOT( SetTimePoint(int) ) ); QObject::connect( this, SIGNAL( TimePointChanged(int) ), m_NavigationDockWidget, SLOT( SetTSlice(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( ShowAllChannelsChanged(bool) ), this, SLOT( ShowAllChannels(bool) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( ShowOneChannelChanged(int) ), this, SLOT( ShowOneChannel(int) ) ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView4D::CreateManualSegmentationdockWidget() { m_ManualSegmentationWidget = new QGoContourManualSegmentationWidget(this); QObject::connect( m_ManualSegmentationWidget, SIGNAL( ValidatePressed() ), this, SLOT( ValidateContour() ) ); QObject::connect( m_ManualSegmentationWidget, SIGNAL( ActivateManualSegmentationToggled(bool) ), this, SLOT( ActivateManualSegmentationEditor(bool) ) ); QObject::connect( m_ManualSegmentationWidget, SIGNAL( ContourRepresentationPropertiesChanged() ), this, SLOT( ChangeContourRepresentationProperty() ) ); /// \todo fix it is not a dock widget anymore // this->m_SegmentationActions.push_back( // m_ManualSegmentationWidget->toggleViewAction()); } //------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoTabImageView4D::~QGoTabImageView4D() { if ( m_XYZImageView ) { delete m_XYZImageView; m_XYZImageView = 0; } if ( m_XYTImageView ) { delete m_XYTImageView; m_XYTImageView = 0; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::setupUi(QWidget *iParent) { if ( iParent->objectName().isEmpty() ) { iParent->resize(800, 800); } QList< int > list_size; list_size.push_back(10); list_size.push_back(10); m_XYZImageView = new QGoImageView3D; m_XYZImageView->SetBackgroundColor(m_BackgroundColor); m_XYTImageView = new QGoImageView3D; m_XYTImageView->SetBackgroundColor(m_BackgroundColor); m_Splitter = new QSplitter(Qt::Horizontal, iParent); m_Splitter->addWidget(m_XYZImageView); m_Splitter->addWidget(m_XYTImageView); m_Splitter->setSizes(list_size); m_Splitter->resize(800, 800); QObject::connect( m_XYZImageView, SIGNAL( SliceViewXYChanged(int) ), this, SIGNAL( ZSliceChanged(int) ) ); QObject::connect( m_XYZImageView, SIGNAL( SliceViewXZChanged(int) ), this, SIGNAL( YSliceChanged(int) ) ); QObject::connect( m_XYZImageView, SIGNAL( SliceViewYZChanged(int) ), this, SIGNAL( XSliceChanged(int) ) ); QObject::connect( m_XYTImageView, SIGNAL( SliceViewXYChanged(int) ), this, SIGNAL( TimePointChanged(int) ) ); QObject::connect( m_XYTImageView, SIGNAL( SliceViewXZChanged(int) ), this, SIGNAL( YSliceChanged(int) ) ); QObject::connect( m_XYTImageView, SIGNAL( SliceViewYZChanged(int) ), this, SIGNAL( XSliceChanged(int) ) ); // QObject::connect( m_ImageView, SIGNAL( FullScreenViewChanged( int ) ), // this, SIGNAL( FullScreenViewChanged( int ) ) ); retranslateUi(iParent); QMetaObject::connectSlotsByName(iParent); } // setupUi //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::retranslateUi(QWidget *iParent) { iParent->setWindowTitle( tr("QGoTabImageView4D") ); Q_UNUSED(iParent); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoFigure::TabDimensionType QGoTabImageView4D::GetTabDimensionType() const { return GoFigure::FOUR_D; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::SetMegaCaptureFile( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const GoFigure::FileType & iFileType, const std::string & iHeader) { m_FileType = iFileType; m_FileList = iContainer; m_FirstUpdate = true; m_Reader1->SetInput(m_FileList); m_Reader1->SetMegaCaptureHeader(iHeader); m_Reader1->SetFileType(m_FileType); m_Reader1->SetTimeBased(true); m_Reader1->SetTimePoint(0); m_Reader1->Update(); unsigned int min_z = m_Reader1->GetMinZSlice(); unsigned int max_z = m_Reader1->GetMaxZSlice(); unsigned int zslice = ( min_z + max_z ) / 2; m_Reader2->SetInput(m_FileList); m_Reader2->SetMegaCaptureHeader(iHeader); m_Reader2->SetFileType(m_FileType); m_Reader2->SetTimeBased(false); m_Reader2->SetZSlice(zslice); unsigned int min_ch = m_Reader1->GetMinChannel(); unsigned int max_ch = m_Reader1->GetMaxChannel(); unsigned int NumberOfChannels = max_ch - min_ch + 1; vtkImageData *temp = m_Reader1->GetOutput(min_ch); int extent[6]; temp->GetExtent(extent); m_NavigationDockWidget->SetXMinimumAndMaximum(extent[0], extent[1]); m_NavigationDockWidget->SetYMinimumAndMaximum(extent[2], extent[3]); m_NavigationDockWidget->SetZMinimumAndMaximum(extent[4], extent[5]); unsigned int min_t = m_Reader1->GetMinTimePoint(); unsigned int max_t = m_Reader1->GetMaxTimePoint(); m_NavigationDockWidget->SetTMinimumAndMaximum(min_t, max_t); m_NavigationDockWidget->SetTSlice(0); m_NavigationDockWidget->SetNumberOfChannels(NumberOfChannels); if ( NumberOfChannels > 1 ) { m_NavigationDockWidget->SetChannel(0); m_XYZInternalImages.resize(NumberOfChannels, NULL); m_XYTInternalImages.resize(NumberOfChannels, NULL); for ( unsigned int i = 1; i < NumberOfChannels; i++ ) { m_NavigationDockWidget->SetChannel(i); } } SetTimePoint(0); SetZSlice(zslice); Update(); m_NavigationDockWidget->SetXSlice( ( extent[0] + extent[1] ) / 2 ); m_NavigationDockWidget->SetYSlice( ( extent[2] + extent[3] ) / 2 ); m_NavigationDockWidget->SetZSlice(zslice); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::SetTimePoint(const int & iTimePoint) { if ( iTimePoint == m_TimePoint ) { return; } if ( !m_FileList.empty() ) { unsigned int t = static_cast< unsigned int >( iTimePoint ); if ( ( t < m_Reader1->GetMinTimePoint() ) || ( t > m_Reader1->GetMaxTimePoint() ) ) { return; } else { m_TimePoint = iTimePoint; m_Reader1->SetTimePoint(m_TimePoint); m_Reader1->Update(); unsigned int min_ch = m_Reader1->GetMinChannel(); unsigned int max_ch = m_Reader1->GetMaxChannel(); int NumberOfChannels = max_ch - min_ch + 1; if ( NumberOfChannels > 1 ) { vtkSmartPointer< vtkImageAppendComponents > append_filter = vtkSmartPointer< vtkImageAppendComponents >::New(); for ( unsigned int i = min_ch; i < max_ch; i++ ) { if ( !m_XYZInternalImages[i] ) { m_XYZInternalImages[i] = vtkSmartPointer< vtkImageData >::New(); } m_XYZInternalImages[i]->ShallowCopy( m_Reader1->GetOutput(i) ); append_filter->AddInput(m_XYZInternalImages[i]); } // This is really stupid!!! if ( NumberOfChannels < 3 ) { for ( int i = NumberOfChannels; i < 3; i++ ) { append_filter->AddInput(m_XYZInternalImages[0]); } } append_filter->Update(); m_XYZImage->ShallowCopy( append_filter->GetOutput() ); } else { m_XYZImage->ShallowCopy( m_Reader1->GetOutput(min_ch) ); } if ( !m_FirstUpdate ) { Update(); } emit TimePointChanged(m_TimePoint); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::SetZSlice(const int & iZSlice) { if ( iZSlice == m_ZSlice ) { return; } if ( !m_FileList.empty() ) { unsigned int z = static_cast< unsigned int >( iZSlice ); if ( ( z < m_Reader2->GetMinZSlice() ) || ( z > m_Reader2->GetMaxZSlice() ) ) { return; } else { m_ZSlice = iZSlice; m_Reader2->SetZSlice(m_ZSlice); unsigned int min_ch = m_Reader2->GetMinChannel(); unsigned int max_ch = m_Reader2->GetMaxChannel(); m_Reader2->Update(); int NumberOfChannels = max_ch - min_ch + 1; if ( NumberOfChannels > 1 ) { vtkSmartPointer< vtkImageAppendComponents > append_filter = vtkSmartPointer< vtkImageAppendComponents >::New(); for ( unsigned int i = min_ch; i < max_ch; i++ ) { if ( !m_XYTInternalImages[i] ) { m_XYTInternalImages[i] = vtkSmartPointer< vtkImageData >::New(); } m_XYTInternalImages[i]->ShallowCopy( m_Reader2->GetOutput(i) ); append_filter->AddInput(m_XYTInternalImages[i]); } // This is really stupid!!! if ( NumberOfChannels < 3 ) { for ( int i = NumberOfChannels; i < 3; i++ ) { append_filter->AddInput(m_XYTInternalImages[0]); } } append_filter->Update(); m_XYTImage->ShallowCopy( append_filter->GetOutput() ); } else { m_XYTImage->ShallowCopy( m_Reader2->GetOutput(min_ch) ); } if ( !m_FirstUpdate ) { Update(); } emit ZSliceChanged(m_ZSlice); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::Update() { m_XYZImageView->SetImage(m_XYZImage); m_XYZImageView->Update(); m_XYTImageView->SetImage(m_XYTImage); m_XYTImageView->Update(); m_XYZImageView->SetSliceViewXY(m_ZSlice); m_XYTImageView->SetSliceViewXY(m_TimePoint); for ( int i = 0; i < 3; i++ ) { vtkSmartPointer< vtkImageActorPointPlacer > point_placer = vtkSmartPointer< vtkImageActorPointPlacer >::New(); point_placer->SetImageActor( m_XYZImageView->GetImageActor(i) ); this->m_ContourRepresentation[i]->SetPointPlacer(point_placer); this->m_ContourWidget[i]->SetRepresentation(this->m_ContourRepresentation[i]); } m_FirstUpdate = false; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::ChangeLookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->DeepCopy( QGoLUTDialog::GetLookupTable( this, tr("Choose one look-up table") ) ); m_XYZImageView->SetLookupTable(lut); m_XYTImageView->SetLookupTable(lut); lut->Delete(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::ShowScalarBar(const bool & iShow) { m_XYZImageView->ShowScalarBar(iShow); m_XYTImageView->ShowScalarBar(iShow); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoTabImageView4D::SnapshotViewXY(const GoFigure::FileType & iType, const QString & iBaseName) { return m_XYZImageView->SnapshotViewXY(iType, iBaseName); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoTabImageView4D::SnapshotViewXZ(const GoFigure::FileType & iType, const QString & iBaseName) { return m_XYZImageView->SnapshotViewXZ(iType, iBaseName); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoTabImageView4D::SnapshotViewYZ(const GoFigure::FileType & iType, const QString & iBaseName) { return m_XYZImageView->SnapshotViewYZ(iType, iBaseName); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoTabImageView4D::SnapshotViewXYZ(const GoFigure::FileType & iType, const QString & iBaseName) { return m_XYZImageView->SnapshotViewXYZ(iType, iBaseName); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoTabImageView4D::SnapshotViewXT(const GoFigure::FileType & iType, const QString & iBaseName) { return m_XYTImageView->SnapshotViewXZ(iType, iBaseName); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoTabImageView4D::SnapshotViewYT(const GoFigure::FileType & iType, const QString & iBaseName) { return m_XYTImageView->SnapshotViewYZ(iType, iBaseName); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoTabImageView4D::SnapshotViewXYT(const GoFigure::FileType & iType, const QString & iBaseName) { return m_XYTImageView->SnapshotViewXYZ(iType, iBaseName); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::SetYSlice(const int & iS) { int slice = m_XYZImageView->GetSliceViewXZ(); bool tobesignaled = false; if ( slice != iS ) { m_XYZImageView->SetSliceViewXZ(iS); tobesignaled = true; } slice = m_XYTImageView->GetSliceViewXZ(); if ( slice != iS ) { m_XYTImageView->SetSliceViewXZ(iS); tobesignaled = true; } if ( tobesignaled ) { emit YSliceChanged(iS); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::SetXSlice(const int & iS) { int slice = m_XYZImageView->GetSliceViewYZ(); bool tobesignaled = false; if ( slice != iS ) { m_XYZImageView->SetSliceViewYZ(iS); tobesignaled = true; } slice = m_XYTImageView->GetSliceViewYZ(); if ( slice != iS ) { m_XYTImageView->SetSliceViewYZ(iS); tobesignaled = true; } if ( tobesignaled ) { emit XSliceChanged(iS); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::SetFullScreenView(const int & iS) { if ( iS == 0 ) { m_XYZImageView->show(); m_XYZImageView->SetFullScreenView(iS); m_XYTImageView->show(); m_XYTImageView->SetFullScreenView(iS); } else { if ( iS < 4 ) { m_XYZImageView->show(); m_XYZImageView->SetFullScreenView(iS - 1); m_XYTImageView->hide(); } else { m_XYZImageView->show(); m_XYZImageView->SetFullScreenView(iS - 4); m_XYTImageView->hide(); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::Octview() { m_XYZImageView->show(); m_XYZImageView->SetFullScreenView(0); m_XYTImageView->show(); m_XYTImageView->SetFullScreenView(0); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::QuadviewXYZ() { m_XYZImageView->show(); m_XYZImageView->SetFullScreenView(0); m_XYTImageView->hide(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::QuadviewXYT() { m_XYZImageView->hide(); m_XYTImageView->show(); m_XYTImageView->SetFullScreenView(0); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::FullScreenViewXY() { m_XYZImageView->show(); m_XYZImageView->SetFullScreenView(1); m_XYTImageView->hide(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::FullScreenViewXZ() { m_XYZImageView->show(); m_XYZImageView->SetFullScreenView(2); m_XYTImageView->hide(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::FullScreenViewYZ() { m_XYZImageView->show(); m_XYZImageView->SetFullScreenView(3); m_XYTImageView->hide(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::FullScreenViewXYZ() { m_XYZImageView->show(); m_XYZImageView->SetFullScreenView(4); m_XYTImageView->hide(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::FullScreenViewXT() { m_XYZImageView->hide(); m_XYTImageView->show(); m_XYTImageView->SetFullScreenView(2); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::FullScreenViewYT() { m_XYZImageView->hide(); m_XYTImageView->show(); m_XYTImageView->SetFullScreenView(3); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::FullScreenViewXYT() { m_XYZImageView->hide(); m_XYTImageView->show(); m_XYTImageView->SetFullScreenView(4); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::GetBackgroundColorFromImageViewer() { double r(0.), g(0.), b(0.); m_XYZImageView->GetBackgroundColor(r, g, b); m_BackgroundColor.setRgbF(r, g, b); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabImageView4D::SetBackgroundColorToImageViewer() { m_XYZImageView->SetBackgroundColor(m_BackgroundColor); m_XYTImageView->SetBackgroundColor(m_BackgroundColor); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- std::vector< QAction * > QGoTabImageView4D::ViewActions() { return m_ViewActions; } //-------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView4D::resizeEvent(QResizeEvent *iEvent) { QWidget::resizeEvent(iEvent); m_Splitter->resize( iEvent->size() ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView4D::ShowAllChannels(bool iChecked) { if ( iChecked ) { vtkSmartPointer< vtkImageAppendComponents > append_filter1 = vtkSmartPointer< vtkImageAppendComponents >::New(); vtkSmartPointer< vtkImageAppendComponents > append_filter2 = vtkSmartPointer< vtkImageAppendComponents >::New(); for ( unsigned int i = 0; i < m_XYZInternalImages.size(); i++ ) { append_filter1->AddInput(m_XYZInternalImages[i]); append_filter2->AddInput(m_XYTInternalImages[i]); } // This is really stupid!!! if ( m_XYZInternalImages.size() < 3 ) { for ( size_t i = m_XYZInternalImages.size(); i < 3; i++ ) { append_filter1->AddInput(m_XYZInternalImages[0]); append_filter2->AddInput(m_XYTInternalImages[0]); } } append_filter1->Update(); append_filter2->Update(); m_XYZImage->ShallowCopy( append_filter1->GetOutput() ); m_XYTImage->ShallowCopy( append_filter2->GetOutput() ); Update(); } else { int ch = this->m_NavigationDockWidget->GetCurrentChannel(); if ( ch != -1 ) { m_XYZImage->ShallowCopy(m_XYZInternalImages[ch]); m_XYTImage->ShallowCopy(m_XYTInternalImages[ch]); Update(); } } } //------------------------------------------------------------------------ //------------------------------------------------------------------------- void QGoTabImageView4D::ShowOneChannel(int iChannel) { if ( ( iChannel != -1 ) && ( !m_XYZInternalImages.empty() ) ) { m_XYZImage->ShallowCopy(m_XYZInternalImages[iChannel]); m_XYTImage->ShallowCopy(m_XYTInternalImages[iChannel]); Update(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView4D::ActivateManualSegmentationEditor(const bool & iActivate) { std::vector< vtkSmartPointer< vtkContourWidget > >::iterator it = m_ContourWidget.begin(); while ( it != m_ContourWidget.end() ) { if ( iActivate ) { ( *it )->On(); } else { ( *it )->Off(); } ++it; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView4D::ChangeContourRepresentationProperty() { double linewidth = 0.0; // = m_ManualSegmentationWidget->GetLinesWidth(); QColor linecolor; // = m_ManualSegmentationWidget->GetLinesColor(); QColor nodecolor; // = m_ManualSegmentationWidget->GetNodesColor(); QColor activenodecolor; // = // m_ManualSegmentationWidget->GetActiveNodesColor(); qreal rl, gl, bl; linecolor.getRgbF(&rl, &gl, &bl); qreal rn, gn, bn; nodecolor.getRgbF(&rn, &gn, &bn); qreal ra, ga, ba; activenodecolor.getRgbF(&ra, &ga, &ba); for ( unsigned int i = 0; i < m_ContourRepresentation.size(); i++ ) { m_ContourRepresentation[i]->GetLinesProperty()->SetLineWidth(linewidth); m_ContourRepresentation[i]->GetLinesProperty()->SetColor( static_cast< double >( rl ), static_cast< double >( gl ), static_cast< double >( bl ) ); m_ContourRepresentation[i]->GetProperty()->SetColor( static_cast< double >( rn ), static_cast< double >( gn ), static_cast< double >( bn ) ); m_ContourRepresentation[i]->GetActiveProperty()->SetColor( static_cast< double >( ra ), static_cast< double >( ga ), static_cast< double >( ba ) ); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView4D::ValidateContour() { for ( unsigned int i = 0; i < m_ContourWidget.size(); i++ ) { ValidateContour(i); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView4D::ValidateContour(const int & iId) { vtkPolyData *contour = m_ContourRepresentation[iId]->GetContourRepresentationAsPolyData(); if ( ( contour->GetNumberOfPoints() > 2 ) && ( m_TimePoint >= 0 ) ) { // get color from the dock widget double r(1.), g(1.), b(1.); /// \todo to be fixed! //QColor color; //= m_ManualSegmentationWidget->GetValidatedColor(); //iColor.getRgbF(&r, &g, &b); vtkProperty *contour_property = vtkProperty::New(); contour_property->SetRepresentationToWireframe(); contour_property->SetColor(r, g, b); // Compute Bounding Box double bounds[6]; contour->GetBounds(bounds); std::cout << bounds[0] << " " << bounds[1] << std::endl; std::cout << bounds[2] << " " << bounds[3] << std::endl; std::cout << bounds[4] << " " << bounds[5] << std::endl; // Extract Min and Max from bounds double Min[3] = {0., 0., 0. }; double Max[3] = {0., 0., 0. }; int k = 0; unsigned int i; for ( i = 0; i < 3; ++i ) { Min[i] = bounds[k++]; Max[i] = bounds[k++]; } // Unused? // int* min_idx = this->GetImageCoordinatesFromWorldCoordinates( Min ); // int* max_idx = this->GetImageCoordinatesFromWorldCoordinates( Max ); vtkPolyData *contour_nodes = vtkPolyData::New(); m_ContourRepresentation[iId]->GetNodePolyData(contour_nodes); // get corresponding actor from visualization vtkPolyData *contour_copy = vtkPolyData::New(); contour_copy->ShallowCopy(contour); // std::vector< vtkQuadricLODActor* > contour_actor = std::vector< vtkActor * > contour_actor = this->AddContour(contour_copy, contour_property); // Save contour in database! // { // m_DataBaseTables->SaveContoursFromVisuInDB(min_idx[0], // min_idx[1],min_idx[2],m_TimePoint,max_idx[0], // max_idx[1],max_idx[2], contour_nodes); // } contour_copy->Delete(); contour_property->Delete(); // get meshid from the dock widget (SpinBox) // unsigned int meshid = m_ManualSegmentationWidget->GetMeshId(); // unused? // unsigned int meshid = // this->m_NavigationDockWidget->GetCurrentCollectionID(); // unsigned int timepoint = static_cast< unsigned int >( m_TimePoint ); // bool highlighted = false; // fill the container // for( i = 0; i < contour_actor.size(); i++ ) // { // ContourStructure temp( m_ContourId, contour_actor[i], contour_nodes, // meshid, timepoint, highlighted, r, g, b, i ); // m_ContourContainer.insert( temp ); // } m_ContourId++; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int * QGoTabImageView4D::GetImageCoordinatesFromWorldCoordinates(double iPos[3]) { return m_XYZImageView->GetImageCoordinatesFromWorldCoordinates(iPos); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- // std::vector< vtkQuadricLODActor* > std::vector< vtkActor * > QGoTabImageView4D::AddContour(vtkPolyData *dataset, vtkProperty *iProperty) { // Adding contour in xyt is not straightforward (it is not the same coordinates) // vtkViewImage2D* viewer = this->m_XYTImageView->GetImageViewer( 0 ); // vtkViewImage3D* viewer3D = this->m_XYTImageView->GetImageViewer3D(); // std::vector< vtkQuadricLODActor* > oActorVector = // this->m_XYZImageView->AddContour( iId, dataset, iProperty ); std::vector< vtkActor * > oActorVector = this->m_XYZImageView->AddContour(dataset, iProperty); // viewer->GetRenderer()->AddViewProp( oActorVector[0] ); // viewer->Render(); // viewer3D->GetRenderer()->AddViewProp( oActorVector[3] ); // viewer3D->Render(); return oActorVector; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView4D::ChangeBackgroundColor() { double r(0.), g(0.), b(0.); m_XYZImageView->GetBackgroundColor(r, g, b); m_BackgroundColor.setRgbF(r, g, b); QColor temp = QColorDialog::getColor( m_BackgroundColor, this, tr("Choose Background Color") ); if ( temp != m_BackgroundColor ) { m_BackgroundColor = temp; m_XYZImageView->SetBackgroundColor(m_BackgroundColor); m_XYTImageView->SetBackgroundColor(m_BackgroundColor); } } //------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/Attic/itkLsm3DSerieImport.h0000644000175000017500000000702011667757442021277 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkLsm3DSerieImport_h #define __itkLsm3DSerieImport_h #include #include #include #include "itkLightProcessObject.h" #include #include "itkRegularExpressionSeriesFileNames.h" #include "GoFigureFileInfoMultiIndexContainerHelper.h" // #include "GoFigureFileInfoHelper.h" namespace itk { class ITK_EXPORT Lsm3DSerieImport:public LightProcessObject { public: typedef std::vector< int > IntVectorType; typedef std::vector< std::string > StringVectorType; /** Standard class typedefs. */ typedef Lsm3DSerieImport Self; typedef LightProcessObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro(Lsm3DSerieImport, LightProcessObject); /** Method for creation through the object factory. */ itkNewMacro(Self); void SetFileName(std::string name); GoFigureFileInfoHelperMultiIndexContainer GetOutput(); void Update(void); void SetGroupId(int Uservalue); protected: Lsm3DSerieImport(); ~Lsm3DSerieImport(); void Glob(); void CreateOutput(); private: Lsm3DSerieImport (const Self &); //purposely not implemented void operator=(const Self &); //purposely not implemented IntVectorType m_numGroupStart; IntVectorType m_numGroupLength; int m_GroupId; StringVectorType m_FileNameS; GoFigureFileInfoHelperMultiIndexContainer m_OutputFileList; std::string m_FileName; }; // #ifndef ITK_MANUAL_INSTANTIATION // #include "itkLsm3DSerieImport.txx" // #endif } #endif GoFigure2-v0.9.0/Code/Attic/TrackTextFileImport.cxx0000644000175000017500000003154611667757442021753 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "TrackTextFileImport.h" #include "vtkPolyDataReader.h" #include "vtkPolyData.h" #include "MegaCaptureHeaderReader.h" #include "vtkMySQLDatabase.h" #include "QueryDataBaseHelper.h" #include "GoDBCoordinateRow.h" #include "GoDBMeshRow.h" #include "GoDBTrackRow.h" /** * \brief Constructor */ TrackTextFileImport::TrackTextFileImport(const std::string & iServerName, const std::string & iLogin, const std::string & iPassword, const std::string & iDBName, const unsigned int & iImagingSessionId) : m_ImagingSessionId(iImagingSessionId) { m_DBConnector = OpenDatabaseConnection(iServerName, iLogin, iPassword, iDBName); } /** * \brief Destructor */ TrackTextFileImport:: ~TrackTextFileImport() { m_DBConnector->Delete(); } /** * \brief Set the directory which contains the TrackText files * \param[in] iDir Name of the directory which contains the TrackText files */ void TrackTextFileImport::SetDirectory(const std::string & iDir) { m_Directory = iDir; } /** * \brief Set the name of the TrackText files * \param[in] iFileName Name of the TrackText files */ void TrackTextFileImport::SetFileName(const std::string & iFileName) { m_FileName = iFileName; } /** * \brief Read the TrackTex file */ void TrackTextFileImport::Read() { std::string filename0 = m_Directory; filename0 += m_FileName; std::string line; std::ifstream ifs(filename0.c_str(), std::ifstream::in); if ( ifs.is_open() ) { // getline(ifs, line); //HeaderFile CaltechZebrafishSubsetData.meg std::string word; ifs >> word >> m_MegaCaptureHeaderFile; std::string filename1 = m_Directory; filename1 += m_MegaCaptureHeaderFile; // Read megacapture header MegaCaptureHeaderReader header_reader(filename1); header_reader.Read(); m_NumberOfChannels = header_reader.m_NumberOfChannels; double spacing[3]; spacing[0] = header_reader.m_VoxelSizeX; spacing[1] = header_reader.m_VoxelSizeY; spacing[2] = header_reader.m_VoxelSizeZ; getline(ifs, line); // getline(ifs, line); // NumberOfTracks ifs >> word >> m_NumberOfTracks; getline(ifs, line); for ( unsigned int j = 0; j < m_NumberOfTracks; j++ ) { InternalTrackStructure track; track.m_TrackId = j; std::string points = "0"; points += " "; // getline(ifs, line); // LineageID ifs >> word >> track.m_LineageID; getline(ifs, line); // getline(ifs, line); // NumberOfMeshes 1622 unsigned int numberOfMeshes; ifs >> word >> numberOfMeshes; getline(ifs, line); unsigned int ch; std::vector< InternalMeshStructure > listofmeshes; for ( unsigned int i = 0; i < numberOfMeshes; i++ ) { InternalMeshStructure mesh(m_NumberOfChannels); // Write getline(ifs, line); /// \todo to be removed in the file (too many duplications) // // TrackId 1685 // ifs >> word >> mesh.m_TrackId; // assign j to the mesh TrackID mesh.m_TrackId = j; // TCoord 2 ifs >> word >> mesh.m_TCoord; // Fill the Track structure if ( mesh.m_TCoord < track.m_TMin ) { track.m_TMin = mesh.m_TCoord; } if ( mesh.m_TCoord > track.m_TMax ) { track.m_TMax = mesh.m_TCoord; } getline(ifs, line); // Centroid 89.6544 2.1618 29.8110 std::string centerX; std::string centerY; std::string centerZ; ifs >> word >> centerX >> centerY >> centerZ; getline(ifs, line); // Volume 531.28 ifs >> word >> mesh.m_Volume; std::string filename; std::string filename2 = m_Directory; //Filename 2_1.vtk ifs >> word >> filename; getline(ifs, line); filename2 += filename; // Read filename vtkPolyDataReader *reader = vtkPolyDataReader::New(); reader->SetFileName( filename2.c_str() ); reader->Update(); vtkPolyData *vtk_mesh = reader->GetOutput(); double bounds[6]; vtk_mesh->GetBounds(bounds); mesh.m_XMin = static_cast< unsigned int >( bounds[0] / spacing[0] ); mesh.m_XMax = static_cast< unsigned int >( bounds[1] / spacing[0] ); mesh.m_YMin = static_cast< unsigned int >( bounds[2] / spacing[1] ); mesh.m_YMax = static_cast< unsigned int >( bounds[3] / spacing[1] ); mesh.m_ZMin = static_cast< unsigned int >( bounds[4] / spacing[2] ); mesh.m_ZMax = static_cast< unsigned int >( bounds[5] / spacing[2] ); // Fill the Track Structure if ( mesh.m_XMin < track.m_XMin ) { track.m_XMin = mesh.m_XMin; } if ( mesh.m_XMax > track.m_XMax ) { track.m_XMax = mesh.m_XMax; } if ( mesh.m_YMin < track.m_YMin ) { track.m_YMin = mesh.m_YMin; } if ( mesh.m_YMax > track.m_YMax ) { track.m_YMax = mesh.m_YMax; } if ( mesh.m_ZMin < track.m_ZMin ) { track.m_ZMin = mesh.m_ZMin; } if ( mesh.m_ZMax > track.m_ZMax ) { track.m_ZMax = mesh.m_ZMax; } mesh.m_Points = vtk_mesh; // Re-write the points "string" std::stringstream streamTCoord; std::string stringTCoord; streamTCoord << mesh.m_TCoord; stringTCoord = streamTCoord.str(); points = AddTimePoint(points, centerX, centerY, centerZ, stringTCoord, true); for ( ch = 0; ch < m_NumberOfChannels; ch++ ) { // getline(ifs, line); // Channel 0 getline(ifs, line); // AverageValue 119.68 ifs >> word >> mesh.m_AverageIntensity[ch]; listofmeshes.push_back(mesh); getline(ifs, line); // getline(ifs, line); } // getline(ifs, line); SaveMeshInDataBase(mesh); reader->Delete(); } // getline(ifs, line); // Remove time points in the points "string" track.m_Points = AddTimePoint(points, "", "", "", "", false); cout << "Track to be saved: " << track.m_Points << endl; SaveTrackInDataBase(track); // getline(ifs, line); } } } /** * \brief Save the mesh informations into the database * \param[in] iMesh Name of the mesh structure to be saved */ void TrackTextFileImport::SaveMeshInDataBase(const InternalMeshStructure & iMesh) { GoDBCoordinateRow coord_min; coord_min.SetField< unsigned int >("XCoord", iMesh.m_XMin); coord_min.SetField< unsigned int >("YCoord", iMesh.m_YMin); coord_min.SetField< unsigned int >("ZCoord", iMesh.m_ZMin); coord_min.SetField< unsigned int >("TCoord", iMesh.m_TCoord); GoDBCoordinateRow coord_max; coord_max.SetField< unsigned int >("XCoord", iMesh.m_XMax); coord_max.SetField< unsigned int >("YCoord", iMesh.m_YMax); coord_max.SetField< unsigned int >("ZCoord", iMesh.m_ZMax); coord_max.SetField< unsigned int >("TCoord", iMesh.m_TCoord); GoDBMeshRow mesh_row(m_DBConnector, iMesh.m_Points, coord_min, coord_max, m_ImagingSessionId); mesh_row.SetColor(165, 44, 23, 255, "KishoreMeshColor", m_DBConnector); int mesh_id = mesh_row.SaveInDB(m_DBConnector); std::cout << "Mesh ID: " << mesh_id << std::endl; } /** * \brief Save the track informations into the database * \param[in] iTrack Name of the track structure to be saved */ void TrackTextFileImport::SaveTrackInDataBase(const InternalTrackStructure & iTrack) { GoDBCoordinateRow coord_min; coord_min.SetField< unsigned int >("XCoord", iTrack.m_XMin); coord_min.SetField< unsigned int >("YCoord", iTrack.m_YMin); coord_min.SetField< unsigned int >("ZCoord", iTrack.m_ZMin); coord_min.SetField< unsigned int >("TCoord", iTrack.m_TMin); GoDBCoordinateRow coord_max; coord_max.SetField< unsigned int >("XCoord", iTrack.m_YMax); coord_min.SetField< unsigned int >("YCoord", iTrack.m_YMax); coord_min.SetField< unsigned int >("ZCoord", iTrack.m_ZMax); coord_max.SetField< unsigned int >("TCoord", iTrack.m_TMax); GoDBTrackRow track_row(m_DBConnector, coord_min, coord_max, m_ImagingSessionId, iTrack.m_Points); track_row.SetColor(55, 25, 0, 255, "KishoreTrackColor1", m_DBConnector); int track_id = track_row.SaveInDB(m_DBConnector); std::cout << "Track ID: " << track_id << std::endl; } /** * \brief Add point to the track string the saved in the database * \param[in] iTrackList String in which one point will be added * \param[in] iX String containing the X position of the new point * \param[in] iY String containing the Y position of the new point * \param[in] iZ String containing the Z position of the new point * \param[in] iT String containing the Time position of the new point * \param[in] iTimePoint Bool == "true" if we want the output string to contain time information (iT, which is requiered to add a new point) */ std::string TrackTextFileImport::AddTimePoint(const std::string & iTrackList, const std::string & iX, const std::string & iY, const std::string & iZ, const std::string & iT, bool iTimePoint) { std::stringstream str(iTrackList); std::string numberOfCoordinatesString; str >> numberOfCoordinatesString; unsigned int numberOfCoordinates; numberOfCoordinates = atoi( numberOfCoordinatesString.c_str() ); // Decompose the string into a map std::map< std::string, std::string > mapOfCoordinates; for ( unsigned int i = 0; i < numberOfCoordinates; i++ ) { std::string xOld = ""; std::string yOld = ""; std::string zOld = ""; std::string tOld = ""; std::string xyzOld = ""; str >> xOld >> yOld >> zOld; xyzOld += xOld; xyzOld += " "; xyzOld += yOld; xyzOld += " "; xyzOld += zOld; str >> tOld; mapOfCoordinates[tOld] = xyzOld; } // Add the new current value in the map if ( iTimePoint ) { std::string xyzNew = ""; xyzNew += iX; xyzNew += " "; xyzNew += iY; xyzNew += " "; xyzNew += iZ; mapOfCoordinates[iT] = xyzNew; } // Fill string with the new map std::map< std::string, std::string >::iterator it; std::string outputString = ""; numberOfCoordinates = (int)mapOfCoordinates.size(); std::stringstream numberOfCoordinatesStream; numberOfCoordinatesStream << numberOfCoordinates; numberOfCoordinatesString = numberOfCoordinatesStream.str(); outputString += numberOfCoordinatesString; for ( it = mapOfCoordinates.begin(); it != mapOfCoordinates.end(); it++ ) { outputString += " "; outputString += ( *it ).second; if ( iTimePoint ) { outputString += " "; outputString += ( *it ).first; } } return outputString; }GoFigure2-v0.9.0/Code/Attic/LineageDockWidget.ui0000644000175000017500000000435311667757442021167 0ustar mathieumathieu LineageDockWidget true 0 0 191 154 Lineages Color Coding QFrame::StyledPanel QFrame::Raised Depth Color Code true false Real Color Code true true Qt::Vertical 20 40 GoFigure2-v0.9.0/Code/Attic/itkMultiFileReader.cxx0000644000175000017500000003313411667757442021567 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkMultiFileReader.h" #include "vtkImageAppendComponents.h" #include "vtkImageExtractComponents.h" #include "vtkLSMReader.h" #include "vtkMetaImageReader.h" #include "vtkBMPReader.h" #include "vtkTIFFReader.h" #include "vtkJPEGReader.h" #include "vtkPNGReader.h" namespace itk { //----------------------------------------------------------------------------- MultiFileReader::MultiFileReader() : m_OutputImage(0), m_Dimensionality(0), m_DataScalarType(-1), m_NumberOfChannels(0), m_NumberOfTimePoints(0), m_NumberOfSlices(0), m_UpdateTimePoint(0), m_UpdateZSlice(0), m_UpdateChannel(0), m_MultiChannelImages(false), m_TimeBased(true) { } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- MultiFileReader::~MultiFileReader() { } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MultiFileReader::SetTimePoint(const unsigned int & UserTimePoint) { if ( UserTimePoint <= m_NumberOfTimePoints ) { m_UpdateTimePoint = UserTimePoint; } else { m_UpdateTimePoint = m_NumberOfTimePoints; } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MultiFileReader::SetZDepth(const unsigned int & iZ) { if ( iZ <= m_NumberOfSlices ) { m_UpdateZSlice = iZ; } else { m_UpdateZSlice = m_NumberOfSlices; } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MultiFileReader::SetChannel(const unsigned int & UserChannel) { if ( UserChannel <= m_NumberOfChannels - 1 ) { m_UpdateChannel = UserChannel; } else { m_UpdateChannel = m_NumberOfChannels - 1; } UpdateChannel(); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MultiFileReader::UpdateChannel() { if ( m_UpdateChannel > m_NumberOfChannels ) { m_UpdateChannel = m_NumberOfChannels - 1; } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MultiFileReader::SetInput(const GoFigureFileInfoHelperMultiIndexContainer & iUserFileList) { if ( iUserFileList.empty() ) { return; } m_FileList = iUserFileList; // Get the number of time points GoFigureFileInfoHelperMultiIndexContainer::index< m_TCoord >::type::reverse_iterator r_tm_it = m_FileList.get< m_TCoord >().rbegin(); m_NumberOfTimePoints = ( *r_tm_it ).m_TCoord; // get number of Z slices GoFigureFileInfoHelperMultiIndexContainer::index< m_ZCoord >::type::reverse_iterator r_zs_it = m_FileList.get< m_ZCoord >().rbegin(); m_NumberOfSlices = ( *r_zs_it ).m_ZCoord; // get number of channels from iUserFileList // (note that the real one could be different) GoFigureFileInfoHelperMultiIndexContainer::index< m_Channel >::type::reverse_iterator r_ch_it = m_FileList.get< m_Channel >().rbegin(); m_NumberOfChannels = ( *r_ch_it ).m_Channel; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MultiFileReader::PrintSelf(std::ostream & os, Indent indent) const { os << indent << "Images Dimensionality: " << m_Dimensionality << std::endl; os << indent << "Images Value Type: " << m_DataScalarType << std::endl; os << indent << "Number Of Channels: " << m_NumberOfChannels << std::endl; os << indent << "Number of Time Points: " << m_NumberOfTimePoints << std::endl; os << indent << "Update Time Point: " << m_UpdateTimePoint << std::endl; os << indent << "Update Channel: " << m_UpdateChannel << std::endl; os << indent << "Are Images multichannel? " << m_MultiChannelImages << std::endl; } //----------------------------------------------------------------------------- void MultiFileReader::BuildVolumeFrom2DImages() { // prepare the final output vtkImageAppend *volumeBuilder = vtkImageAppend::New(); volumeBuilder->SetAppendAxis(2); //append along Z std::list< std::string >::iterator endIt = m_UpdateFileList.end(); std::list< std::string >::iterator It = m_UpdateFileList.begin(); int counter = 0; while ( It != endIt ) { switch ( this->m_FileType ) { case JPEG: { AddToVolumeBuilder< vtkJPEGReader >(counter, ( *It ), volumeBuilder); break; } case BMP: { AddToVolumeBuilder< vtkBMPReader >(counter, ( *It ), volumeBuilder); break; } case PNG: { AddToVolumeBuilder< vtkPNGReader >(counter, ( *It ), volumeBuilder); break; } case TIFF: { AddToVolumeBuilder< vtkTIFFReader >(counter, ( *It ), volumeBuilder); break; } case MHA: { AddToVolumeBuilder< vtkMetaImageReader >(counter, ( *It ), volumeBuilder); break; } case LSM: { itkGenericExceptionMacro(<< "stacks of 2D LSM are not supported at this time."); break; } default: { itkGenericExceptionMacro(<< "unsupported type: " << m_FileType << "."); break; } } ++It; ++counter; } volumeBuilder->Update(); vtkImageData *temp_output = volumeBuilder->GetOutput(); m_NumberOfChannels = temp_output->GetNumberOfScalarComponents(); UpdateChannel(); if ( m_MultiChannelImages ) { m_OutputImage = vtkImageData::New(); m_OutputImage->ShallowCopy(temp_output); volumeBuilder->Delete(); } else { vtkImageExtractComponents *extractComp = vtkImageExtractComponents::New(); extractComp->SetComponents(m_UpdateChannel); extractComp->SetInput(temp_output); extractComp->Update(); volumeBuilder->Delete(); m_OutputImage = vtkImageData::New(); m_OutputImage->ShallowCopy( extractComp->GetOutput() ); extractComp->Delete(); } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- vtkImageData * MultiFileReader::GetOutput() const { return m_OutputImage; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MultiFileReader::Update() { if ( ( m_Dimensionality != 2 ) && ( m_Dimensionality != 3 ) ) { std::cerr << "( m_Dimensionality != 2 ) && ( m_Dimensionality != 3 )" << std::endl; return; } else { this->GenerateData(); } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void MultiFileReader::GenerateData() { if ( m_OutputImage ) { m_OutputImage->Delete(); m_OutputImage = 0; } ComputeUpdateFileList(); if ( m_UpdateFileList.empty() ) { std::cout << "Problem: m_UpdateFileList is empty :-/ (after ComputeUpdateFileList)" << std::endl; return; } if ( m_Dimensionality == 2 ) { BuildVolumeFrom2DImages(); } // end of dimensionality == 2 if ( m_Dimensionality == 3 ) { CreateVolumeFromOne3DImageFile(); } } //----------------------------------------------------------------------------- void MultiFileReader::CreateVolumeFromOne3DImageFile() { FileListType::iterator It = m_UpdateFileList.begin(); switch ( this->m_FileType ) { case JPEG: // fallthrough case BMP: // falltrhough case PNG: // fallthrough { itkGenericExceptionMacro(<< "JPEG/BMP/PNG cannot be of dimensionality 3."); break; } case TIFF: { m_OutputImage = vtkImageData::New(); Copy3DImage< vtkTIFFReader >( m_OutputImage, ( *It ).m_Filename.c_str() ); break; } case MHA: { m_OutputImage = vtkImageData::New(); Copy3DImage< vtkMetaImageReader >( m_OutputImage, ( *It ).m_Filename.c_str() ); break; } case LSM: { /// \note this is still the old way to proceed... if ( m_MultiChannelImages ) { vtkImageData *myImage_ch1 = vtkImageData::New(); vtkLSMReader *reader = vtkLSMReader::New(); reader->SetFileName( ( *It ).m_Filename.c_str() ); reader->Update(); int NumberOfChannels = reader->GetNumberOfChannels(); myImage_ch1->ShallowCopy( reader->GetOutput() ); reader->Delete(); if ( ( NumberOfChannels == 1 ) ) { m_OutputImage = myImage_ch1; return; } vtkImageData *myImage_ch2 = vtkImageData::New(); vtkLSMReader *reader2 = vtkLSMReader::New(); reader2->SetFileName( ( *It ).m_Filename.c_str() ); reader2->SetUpdateChannel(1); reader2->Update(); myImage_ch2->ShallowCopy( reader2->GetOutput() ); reader2->Delete(); vtkImageAppendComponents *appendFilter = vtkImageAppendComponents::New(); appendFilter->AddInput(myImage_ch1); appendFilter->AddInput(myImage_ch2); vtkImageData *myImage_ch3 = vtkImageData::New(); if ( NumberOfChannels == 2 ) { myImage_ch3->ShallowCopy(myImage_ch1); } else { vtkLSMReader *reader3 = vtkLSMReader::New(); reader3->SetFileName( ( *It ).m_Filename.c_str() ); reader3->SetUpdateChannel(2); reader3->Update(); myImage_ch3->ShallowCopy( reader3->GetOutput() ); reader3->Delete(); } appendFilter->AddInput(myImage_ch3); appendFilter->Update(); vtkImageData *myImage3 = vtkImageData::New(); myImage3->ShallowCopy( appendFilter->GetOutput() ); appendFilter->Delete(); myImage_ch3->Delete(); myImage_ch2->Delete(); myImage_ch1->Delete(); // if( m_IsProgressBarSet ) // { // m_ProgressBar->setValue( 100 ); // } m_OutputImage = myImage3; } else { vtkLSMReader *reader = vtkLSMReader::New(); reader->SetFileName( ( *It ).m_Filename.c_str() ); reader->SetUpdateChannel(m_UpdateChannel); reader->Update(); m_OutputImage = vtkImageData::New(); m_OutputImage->ShallowCopy( reader->GetOutput() ); reader->Delete(); } break; } default: { itkGenericExceptionMacro(<< "unsupported type: " << this->m_FileType << "."); break; } } m_NumberOfChannels = m_OutputImage->GetNumberOfScalarComponents(); UpdateChannel(); } //----------------------------------------------------------------------------- void MultiFileReader::ComputeUpdateFileList(const unsigned int & iChannel) { if ( m_TimeBased ) { m_UpdateFileList = GetAllFileNamesForGivenTCoordAndChannel(m_FileList, m_UpdateTimePoint, iChannel); } else { m_UpdateFileList = GetAllFileNamesForGivenZCoordPointAndChannel(m_FileList, m_UpdateZSlice, iChannel); } } //----------------------------------------------------------------------------- }GoFigure2-v0.9.0/Code/Attic/itkLsm3DSerieImport.cxx0000644000175000017500000002070111667757442021653 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkLsm3DSerieImport.h" #include "vnl/vnl_math.h" namespace itk { Lsm3DSerieImport::Lsm3DSerieImport() { m_FileName.clear(); m_GroupId = 0; } Lsm3DSerieImport:: ~Lsm3DSerieImport() { } void Lsm3DSerieImport::SetFileName(std::string name) { if ( !m_FileName.empty() && !name.empty() && m_FileName.compare(name) != 0 ) { return; } if ( name.empty() && m_FileName.empty() ) { return; } m_FileName = name; this->Modified(); } GoFigureFileInfoHelperMultiIndexContainer Lsm3DSerieImport::GetOutput() { return this->m_OutputFileList; } void Lsm3DSerieImport::Update(void) { Glob(); CreateOutput(); } void Lsm3DSerieImport::SetGroupId(int Uservalue) { this->m_GroupId = Uservalue; this->Modified(); } void Lsm3DSerieImport::Glob() { m_numGroupStart.clear(); m_numGroupLength.clear(); // glob all jpeg file names std::string unixArchetype = m_FileName; itksys::SystemTools::ConvertToUnixSlashes(unixArchetype); if ( itksys::SystemTools::FileIsDirectory( unixArchetype.c_str() ) ) { return; } // Parse the fileNameName and fileNamePath std::string origFileName = itksys::SystemTools::GetFilenameName( unixArchetype.c_str() ); std::string fileNamePath = itksys::SystemTools::GetFilenamePath( unixArchetype.c_str() ); std::string pathPrefix; // "Clean" the filename by escaping any special characters with backslashes. // This allows us to pass in filenames that include these special characters. std::string fileName; for ( unsigned int j = 0; j < origFileName.length(); j++ ) { char oneChar = origFileName[j]; if ( oneChar == '^' || oneChar == '$' || oneChar == '.' || oneChar == '[' || oneChar == ']' || oneChar == '-' || oneChar == '*' || oneChar == '+' || oneChar == '?' || oneChar == '(' || oneChar == ')' ) { fileName += "\\"; } fileName += oneChar; } // If there is no "/" in the name, the directory is not specified. // In that case, use the default ".". // This is necessary for the RegularExpressionSeriesFileNames. if ( fileNamePath == "" ) { fileNamePath = "."; pathPrefix = "./"; } else { pathPrefix = ""; } std::string regExpString = "([0-9]+)"; int sIndex; // parse and keep it for ouput generation std::string::iterator sit; for ( sit = fileName.begin(); sit < fileName.end(); sit++ ) { // If the element is a number, find its starting index and length. if ( ( *sit ) >= '0' && ( *sit ) <= '9' ) { sIndex = static_cast< int >( sit - fileName.begin() ); m_numGroupStart.push_back(sIndex); // Loop to one past the end of the group of numbers. while ( sit != fileName.end() && ( *sit ) >= '0' && ( *sit ) <= '9' ) { ++sit; } m_numGroupLength.push_back(static_cast< int >( sit - fileName.begin() ) - sIndex); if ( sit == fileName.end() ) { break; } } } // create the regular expression to glob the entire set of file std::string regExpFileName = fileName; IntVectorType::reverse_iterator numGroupLengthItr = m_numGroupLength.rbegin(); IntVectorType::reverse_iterator numGroupStartItr = m_numGroupStart.rbegin(); int NumGroupCounter = 0; while ( numGroupLengthItr != m_numGroupLength.rend() && numGroupStartItr != m_numGroupStart.rend() ) { if ( NumGroupCounter == m_GroupId ) { regExpFileName.replace(*numGroupStartItr, *numGroupLengthItr, regExpString); break; } ++numGroupLengthItr; ++numGroupStartItr; ++NumGroupCounter; } // Include only filenames that exactly match this regular expression. Don't // match filenames that have this string as a substring (ie. that have extra // prefixes or suffixes). regExpFileName = "^" + regExpFileName + "$"; // Use a RegularExpressionSeriesFileNames to find the files to return itk::RegularExpressionSeriesFileNames::Pointer fit = itk::RegularExpressionSeriesFileNames::New(); fit->SetDirectory( fileNamePath.c_str() ); fit->SetRegularExpression( regExpFileName.c_str() ); fit->SetSubMatch(1); fit->NumericSortOn(); m_FileNameS = fit->GetFileNames(); // re parse the indexes and length without the escape caracters for ( sit = origFileName.begin(); sit < origFileName.end(); sit++ ) { // If the element is a number, find its starting index and length. if ( ( *sit ) >= '0' && ( *sit ) <= '9' ) { sIndex = static_cast< int >( sit - origFileName.begin() ); m_numGroupStart.push_back(sIndex); // Loop to one past the end of the group of numbers. while ( sit != origFileName.end() && ( *sit ) >= '0' && ( *sit ) <= '9' ) { ++sit; } m_numGroupLength.push_back(static_cast< int >( sit - origFileName.begin() ) - sIndex); if ( sit == origFileName.end() ) { break; } } } } void Lsm3DSerieImport::CreateOutput() { std::vector< std::string >::iterator nit; for ( nit = m_FileNameS.begin(); nit != m_FileNameS.end(); nit++ ) { GoFigureFileInfoHelper tempInfo; tempInfo.m_Filename = ( *nit ); std::string origFileName = itksys::SystemTools::GetFilenameName( ( *nit ).c_str() ); IntVectorType::reverse_iterator numGroupLengthItr = m_numGroupLength.rbegin(); IntVectorType::reverse_iterator numGroupStartItr = m_numGroupStart.rbegin(); int NumGroupCounter = 0; while ( numGroupLengthItr != m_numGroupLength.rend() && numGroupStartItr != m_numGroupStart.rend() ) { if ( NumGroupCounter == m_GroupId ) { std::string ValueAsString( origFileName, ( *numGroupStartItr ), ( *numGroupLengthItr ) ); tempInfo.m_TCoord = static_cast< unsigned int >( vcl_floor( atof( ValueAsString.c_str() ) ) ); m_OutputFileList.insert(tempInfo); break; } ++numGroupLengthItr; ++numGroupStartItr; ++NumGroupCounter; } // end for each numerical group } // end for each filename m_FileNameS.clear(); // GoFigureFileInfoHelperTimeBasedCompare comparison; // std::sort( m_OutputFileList.begin(), m_OutputFileList.end(), comparison ); #if !defined( ITK_LEAN_AND_MEAN ) && !defined( __BORLANDC__ ) && !defined( NDEBUG ) GoFigureFileInfoHelperMultiIndexContainer::iterator myIt = m_OutputFileList.begin(); while ( myIt != m_OutputFileList.end() ) { itkDebugMacro( << ( *myIt ).m_Filename \ << " " << ( *myIt ).m_Channel \ << " " << ( *myIt ).m_TCoord \ << " " << ( *myIt ).m_ZCoord); myIt++; } #endif } }GoFigure2-v0.9.0/Code/Attic/TrackTextFileImport.h0000644000175000017500000001054211667757442021371 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __TrackTextFileImport_h #define __TrackTextFileImport_h #if defined( WIN32 ) #pragma warning( disable: 4251 ) #endif #include #include #include #include #include "vtkType.h" #include "QGoIOConfigure.h" class vtkPolyData; class vtkMySQLDatabase; class vtkPolyData; class QGOIO_EXPORT TrackTextFileImport { public: TrackTextFileImport(const std::string & iServerName, const std::string & iLogin, const std::string & iPassword, const std::string & iDBName, const unsigned int & iImagingSessionId); ~TrackTextFileImport(); void SetDirectory(const std::string &); void SetFileName(const std::string &); /** * \brief Read the TrackTex file */ void Read(); private: unsigned int m_ImagingSessionId; unsigned int m_NumberOfChannels; unsigned int m_NumberOfTracks; std::string m_MegaCaptureHeaderFile; std::string m_Directory; std::string m_FileName; vtkMySQLDatabase *m_DBConnector; struct InternalMeshStructure { InternalMeshStructure(const unsigned int & iNumberOfChannels): m_AverageIntensity(iNumberOfChannels, 0) {} unsigned int m_TrackId; unsigned int m_TCoord; double m_Volume; unsigned int m_XMin; unsigned int m_XMax; unsigned int m_YMin; unsigned int m_YMax; unsigned int m_ZMin; unsigned int m_ZMax; vtkPolyData *m_Points; std::vector< double > m_AverageIntensity; }; struct InternalTrackStructure { InternalTrackStructure(): m_XMin(VTK_UNSIGNED_INT_MAX), m_XMax(VTK_UNSIGNED_INT_MIN), m_YMin(VTK_UNSIGNED_INT_MAX), m_YMax(VTK_UNSIGNED_INT_MIN), m_ZMin(VTK_UNSIGNED_INT_MAX), m_ZMax(VTK_UNSIGNED_INT_MIN), m_TMin(VTK_UNSIGNED_INT_MAX), m_TMax(VTK_UNSIGNED_INT_MIN){} unsigned int m_LineageID; unsigned int m_TrackId; unsigned int m_XMin; unsigned int m_XMax; unsigned int m_YMin; unsigned int m_YMax; unsigned int m_ZMin; unsigned int m_ZMax; unsigned int m_TMin; unsigned int m_TMax; std::string m_Points; }; std::list< InternalMeshStructure > m_ListOfMeshes; std::list< InternalTrackStructure > m_ListOfTracks; void SaveMeshInDataBase(const InternalMeshStructure & iMesh); void SaveTrackInDataBase(const InternalTrackStructure & iTrack); std::string AddTimePoint(const std::string & iTrackList, const std::string & iX, const std::string & iY, const std::string & iZ, const std::string & iT, bool iTimePoint); }; #endif GoFigure2-v0.9.0/Code/Attic/MeshTextFileImport.h0000644000175000017500000000624111667757442021222 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __MeshTextFileImport_h #define __MeshTextFileImport_h #include #include #include #include "QGoGUILibConfigure.h" class vtkPolyData; class vtkMySQLDatabase; class QGOGUILIB_EXPORT MeshTextFileImport { public: MeshTextFileImport(const std::string & iServerName, const std::string & iLogin, const std::string & iPassword, const std::string & iDBName, const unsigned int & iImagingSessionId); ~MeshTextFileImport(); void SetDirectory(const std::string &); void SetFileName(const std::string &); void Read(); private: unsigned int m_ImagingSessionId; unsigned int m_NumberOfChannels; unsigned int m_NumberOfMeshes; std::string m_MegaCaptureHeaderFile; std::string m_Directory; std::string m_FileName; vtkMySQLDatabase *m_DBConnector; struct InternalMeshStructure { InternalMeshStructure(const unsigned int & iNumberOfChannels): m_AverageIntensity(iNumberOfChannels, 0) {} unsigned int m_TrackId; unsigned int m_TCoord; double m_Volume; unsigned int m_XMin; unsigned int m_XMax; unsigned int m_YMin; unsigned int m_YMax; unsigned int m_ZMin; unsigned int m_ZMax; vtkPolyData *m_Points; std::vector< double > m_AverageIntensity; }; std::list< InternalMeshStructure > m_ListOfMeshes; void SaveMeshInDataBase(const InternalMeshStructure & iMesh); }; #endif GoFigure2-v0.9.0/Code/Attic/SegmentationSeedBaseWidget.ui0000644000175000017500000000431611667757442023052 0ustar mathieumathieu SegmentationSeedBaseWidget 0 0 237 156 0 0 Form Filter Radius 0.100000000000000 0.100000000000000 3.000000000000000 Channel Apply Qt::Vertical 20 6 GoFigure2-v0.9.0/Code/Attic/TrackDockWidget.ui0000644000175000017500000001410211667757442020660 0ustar mathieumathieu TrackDockWidget true 0 0 191 254 Tracks Color Coding QFrame::StyledPanel QFrame::Raised <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" text-decoration: underline;">Element</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" text-decoration: underline;">Radius</span></p></body></html> false false Glyphs Tubes 0.100000000000000 3.000000000000000 0.100000000000000 3.000000000000000 QFrame::StyledPanel QFrame::Raised Time Color code true false Speed Color Code true false Real Color Code true true Qt::Vertical 20 40 GoFigure2-v0.9.0/Code/Attic/itkMultiFileReader.h0000644000175000017500000001375411667757442021222 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkMultiFileReader_h #define __itkMultiFileReader_h #include "itkLightProcessObject.h" #include "vtkJPEGReader.h" #include "vtkImageData.h" #include "vtkImageAppend.h" #include "QGoIOConfigure.h" #include "GoFigureFileInfoMultiIndexContainerHelper.h" namespace itk { /** * \class MultiFileReader * * \brief * Class that implement a reader for a stack of files. Note that the list of files * is supposed to be sorted before using this class. * * files can be of any dimensionality (we expect 2, 3 or 4D) * files can be of the following types: JPG, PNG, BMP, TIFF, MHA, LSM * * \todo Add Support for ProgressEvent * * */ class QGOIO_EXPORT MultiFileReader:public LightProcessObject { public: /** Standard class typedefs. */ typedef MultiFileReader Self; typedef LightProcessObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkNewMacro(Self); itkTypeMacro(MultiFileReader, LightProcessObject); enum FILETYPE { BMP = 0, JPEG, PNG, TIFF, MHA, LSM }; /** \brief set the time point you want to extract and load in memory the corresponding XYZ volume. */ void SetTimePoint(const int & UserTimePoint); /** \brief set the z slice you want to extract and load in memory the corresponding XYT volume. */ void SetZDepth(const int & iZ); /** \brief */ itkBooleanMacro(TimeBased); itkSetMacro(TimeBased, bool); /** \brief set the channel you want to extract and load in memory. -1 for all channels. */ void SetChannel(const unsigned int & UserChannel); void UpdateChannel(); /** \brief set the input as a GoFigure format file list */ void SetInput(GoFigureFileInfoHelperMultiIndexContainer UserFileList); /** \brief */ itkSetMacro(FileType, FILETYPE); /** \brief */ itkSetMacro(Dimensionality, int); itkGetConstMacro(Dimensionality, int); itkGetConstMacro(NumberOfTimePoints, int); itkGetConstMacro(NumberOfSlices, int); itkGetConstMacro(NumberOfChannels, int); /** \brief */ itkSetMacro(MultiChannelImages, bool); itkBooleanMacro(MultiChannelImages); /** \brief */ vtkImageData * GetOutput() const; // Fake It. The output is not of itkDataObject type // so pipeline mechanism would not work. void Update(); // void SetProgressBar( QProgressBar* PB ); /** \brief Mandatory PrintSelf */ void PrintSelf(std::ostream & os, Indent indent) const; protected: MultiFileReader(); virtual ~MultiFileReader(); private: void ComputeUpdateFileList(); MultiFileReader(const Self &); //purposely not implemented void operator=(const Self &); //purposely not implemented vtkImageData * m_OutputImage; GoFigureFileInfoHelperMultiIndexContainer m_FileList; std::list< std::string > m_UpdateFileList; // FileListType m_UpdateFileList; FILETYPE m_FileType; // suppose same file format for all files int m_Dimensionality; // suppose same dimensionality for all files int m_DataScalarType; // suppose same type for all files unsigned int m_NumberOfChannels; // OfScalarComponents; unsigned int m_NumberOfTimePoints; unsigned int m_NumberOfSlices; unsigned int m_UpdateTimePoint; unsigned int m_UpdateZSlice; unsigned int m_UpdateChannel; bool m_MultiChannelImages; bool m_TimeBased; // QProgressBar* m_ProgressBar; // bool m_IsProgressBarSet; virtual void GenerateData(); template< class TReader > void Copy3DImage(vtkImageData *ioImage, const std::string & iFileName) { typedef TReader ReaderType; ReaderType *reader = ReaderType::New(); reader->SetFileName( iFileName.c_str() ); reader->SetFileDimensionality(3); reader->Update(); ioImage->ShallowCopy( reader->GetOutput() ); reader->Delete(); } void BuildVolumeFrom2DImages(); void CreateVolumeFromOne3DImageFile(); }; } // end of namespace itk #endif GoFigure2-v0.9.0/Code/Attic/QGoTabImageView4D.h0000644000175000017500000001570611667757442020577 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTabImageView4D_h #define __QGoTabImageView4D_h #include "QGoTabElementBase.h" class QGoPrintDatabase; class QGoImageView3D; class QGoNavigationDockWidget; class QGoContourManualSegmentationWidget; #ifdef ENABLEVIDEORECORD class QGoVideoRecorder; #endif class vtkContourWidget; class vtkOrientedGlyphContourRepresentation; // class vtkQuadricLODActor; class vtkActor; class vtkProperty; class vtkPolyData; #include "vtkSmartPointer.h" #include "itkMegaCaptureReader.h" #include "GoFigureFileInfoMultiIndexContainerHelper.h" #include "QGoGUILibConfigure.h" #include #include /** \class QGoTabImageView4D \brief \example GUI/lib/qgotabimageview4d.cxx */ class QGOGUILIB_EXPORT QGoTabImageView4D:public QGoTabElementBase { Q_OBJECT public: QGoTabImageView4D(QWidget *parent = 0); virtual ~QGoTabImageView4D(); typedef QGoTabElementBase::QGoDockWidgetStatusPair QGoDockWidgetStatusPair; GoFigure::TabDimensionType GetTabDimensionType() const; void SetMegaCaptureFile( const GoFigureFileInfoHelperMultiIndexContainer & iContainer, const GoFigure::FileType & iFileType, const std::string & iHeader); virtual void Update(); void setupUi(QWidget *parent); void retranslateUi(QWidget *parent); virtual std::vector< QAction * > ViewActions(); virtual void WriteSettings() {} virtual void ReadSettings() {} virtual void ValidateContour(const int & iId); QGoPrintDatabase *m_DataBaseTables; void CreateModeToolBar(QMenu* iMenu, QToolBar* iToolBar); signals: void TimePointChanged(int TimePoint); void ZSliceChanged(int ZSlice); void YSliceChanged(int YSlice); void XSliceChanged(int XSlice); void FullScreenViewChanged(int FullScreen); public slots: void SetTimePoint(const int &); void SetZSlice(const int &); void SetYSlice(const int &); void SetXSlice(const int &); QString SnapshotViewXY( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xy-") ); QString SnapshotViewXZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xz-") ); QString SnapshotViewYZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-yz-") ); QString SnapshotViewXYZ( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xyz-") ); QString SnapshotViewXT( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xt-") ); QString SnapshotViewYT( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-yt-") ); QString SnapshotViewXYT( const GoFigure::FileType & iType, const QString & iBaseName = QString("snapshot-xyt-") ); void SetFullScreenView(const int & iS); void Octview(); void QuadviewXYZ(); void QuadviewXYT(); void FullScreenViewXY(); void FullScreenViewXZ(); void FullScreenViewYZ(); void FullScreenViewXYZ(); void FullScreenViewXT(); void FullScreenViewYT(); void FullScreenViewXYT(); void ChangeLookupTable(); void ShowScalarBar(const bool &); void ChangeBackgroundColor(); void ShowAllChannels(bool iChecked); void ShowOneChannel(int iChannel); void ActivateManualSegmentationEditor(const bool & iActivate); void ValidateContour(); void ChangeContourRepresentationProperty(); protected: QSplitter * m_Splitter; QGoImageView3D * m_XYZImageView; QGoImageView3D * m_XYTImageView; vtkSmartPointer< vtkImageData > m_XYZImage; vtkSmartPointer< vtkImageData > m_XYTImage; std::vector< vtkSmartPointer< vtkImageData > > m_XYZInternalImages; std::vector< vtkSmartPointer< vtkImageData > > m_XYTInternalImages; QColor m_BackgroundColor; int m_TimePoint; int m_ZSlice; unsigned int m_ContourId; itk::MegaCaptureReader::Pointer m_Reader1; itk::MegaCaptureReader::Pointer m_Reader2; GoFigureFileInfoHelperMultiIndexContainer m_FileList; GoFigure::FileType m_FileType; bool m_FirstUpdate; std::vector< QAction * > m_ViewActions; QGoNavigationDockWidget * m_NavigationDockWidget; QGoContourManualSegmentationWidget *m_ManualSegmentationWidget; #ifdef ENABLEVIDEORECORD QGoVideoRecorder *m_VideoRecorderWidget; #endif std::vector< vtkSmartPointer< vtkContourWidget > > m_ContourWidget; std::vector< vtkSmartPointer< vtkOrientedGlyphContourRepresentation > > m_ContourRepresentation; void CreateAllViewActions(); void CreateVisuDockWidget(); void CreateManualSegmentationdockWidget(); void GetBackgroundColorFromImageViewer(); void SetBackgroundColorToImageViewer(); // std::vector< vtkQuadricLODActor* > std::vector< vtkActor * > AddContour(vtkPolyData *dataset, vtkProperty *property = NULL); int *GetImageCoordinatesFromWorldCoordinates(double pos[3]); virtual void resizeEvent(QResizeEvent *event); }; #endif GoFigure2-v0.9.0/Code/ExternalCode/0000755000175000017500000000000011667757442016623 5ustar mathieumathieuGoFigure2-v0.9.0/Code/ExternalCode/itkQt/0000755000175000017500000000000011667757442017717 5ustar mathieumathieuGoFigure2-v0.9.0/Code/ExternalCode/itkQt/itkQtConfigure.h.in0000644000175000017500000000060511667757442023434 0ustar mathieumathieu#ifndef __itkQtConfigure_h #define __itkQtConfigure_h #include "vtkConfigure.h" #include /* Whether we are building shared libraries. */ #if defined ( WIN32 ) && defined ( GOFIGURE2_BUILD_SHARED_LIBS ) #if defined ( itkQt_EXPORT ) #define IKTQT_EXPORT __declspec(dllexport) #else #define IKTQT_EXPORT __declspec(dllimport) #endif #else #define IKTQT_EXPORT #endif #endifGoFigure2-v0.9.0/Code/ExternalCode/itkQt/itkQtProgressBar.h0000644000175000017500000000637511667757442023351 0ustar mathieumathieu/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkQtProgressBar.h,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkQtProgressBar_h #define __itkQtProgressBar_h #include #include "itkCommand.h" #include "itkQtConfigure.h" namespace itk { class IKTQT_EXPORT QtProgressBar : public ::QProgressBar { public: /** Command Class invoked for button redraw */ typedef itk::MemberCommand< QtProgressBar > RedrawCommandType; /** Constructor */ explicit QtProgressBar(QWidget *parent = 0); /** Get Command */ RedrawCommandType * GetRedrawCommand(void) const; /** Manage a Progress event */ void ProcessEvent(itk::Object *caller, const itk::EventObject & event); void ConstProcessEvent(const itk::Object *caller, const itk::EventObject & event); /** Manage a Progress event */ void Observe(itk::Object *caller); private: RedrawCommandType::Pointer m_RedrawCommand; }; } // end of namespace #endif GoFigure2-v0.9.0/Code/ExternalCode/itkQt/CMakeLists.txt0000644000175000017500000000276511667757442022471 0ustar mathieumathieuIF( WIN32 ) IF( NOT CYGWIN ) IF( NOT MINGW ) IF( BUILD_SHARED_LIBS ) ADD_DEFINITIONS( -DitkQt_EXPORT ) ENDIF( BUILD_SHARED_LIBS ) ENDIF( NOT MINGW ) ENDIF( NOT CYGWIN ) ENDIF( WIN32 ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/itkQtConfigure.h.in ${CMAKE_CURRENT_BINARY_DIR}/itkQtConfigure.h @ONLY IMMEDIATE ) QT4_WRAP_CPP( itkQtAdaptor_MOC itkQtAdaptor.h ) ADD_LIBRARY( itkQt itkQtProgressBar.cxx itkQtProgressDialog.cxx itkQtAdaptor.h ${itkQtAdaptor_MOC} ) TARGET_LINK_LIBRARIES( itkQt ${ITK_LIBRARIES} ${QT_LIBRARIES} ) SET_TARGET_PROPERTIES( itkQt PROPERTIES VERSION ${GOFIGURE2_LIB_VERSION} SOVERSION ${GOFIGURE2_LIB_VERSION} ) # Runtime INSTALL( TARGETS itkQt EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} NAMELINK_SKIP COMPONENT Libraries ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries ) # Development INSTALL( TARGETS itkQt EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} NAMELINK_ONLY COMPONENT Libraries ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries ) FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE( GLOB __binary_file_h "${CMAKE_CURRENT_BINARY_DIR}/*.h" ) INSTALL( FILES ${__source_file_h} ${__binary_file_h} DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Code/ExternalCode/itkQt/itkQtProgressDialog.cxx0000644000175000017500000001007011667757442024402 0ustar mathieumathieu/*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkProcessObject.h" #include "itkQtProgressDialog.h" namespace itk { /** Constructor */ QtProgressDialog ::QtProgressDialog( QWidget * iParent, Qt::WindowFlags f ) : QProgressDialog(iParent, f ) { m_RedrawCommand = RedrawCommandType::New(); m_RedrawCommand->SetCallbackFunction(this, &QtProgressDialog::ProcessEvent); m_RedrawCommand->SetCallbackFunction(this, &QtProgressDialog::ConstProcessEvent); this->setMinimum(0); this->setMaximum(100); } QtProgressDialog ::QtProgressDialog( const QString & labelText, const QString & cancelButtonText, int minimum, int maximum, QWidget * iParent, Qt::WindowFlags f ) : QProgressDialog( labelText, cancelButtonText, minimum, maximum, iParent, f ) { m_RedrawCommand = RedrawCommandType::New(); m_RedrawCommand->SetCallbackFunction(this, &QtProgressDialog::ProcessEvent); m_RedrawCommand->SetCallbackFunction(this, &QtProgressDialog::ConstProcessEvent); } /** Get Command */ QtProgressDialog::RedrawCommandType * QtProgressDialog::GetRedrawCommand() const { return m_RedrawCommand.GetPointer(); } /** Manage a Progress event */ void QtProgressDialog::ProcessEvent( itk::Object *caller, const itk::EventObject & iEvent ) { if ( typeid( itk::ProgressEvent ) == typeid( iEvent ) ) { itk::ProcessObject::Pointer process = dynamic_cast< itk::ProcessObject * >( caller ); const int tempvalue = static_cast< int >( process->GetProgress() * static_cast< float >( this->maximum() ) ); this->setValue(tempvalue); } } void QtProgressDialog::ConstProcessEvent( const itk::Object *caller, const itk::EventObject & iEvent) { if ( typeid( itk::ProgressEvent ) == typeid( iEvent ) ) { itk::ProcessObject::ConstPointer process = dynamic_cast< const itk::ProcessObject * >( caller ); const int temp_value = static_cast< int >( process->GetProgress() * static_cast< float >( this->maximum() ) ); this->setValue(temp_value); } } /** Manage a Progress event */ void QtProgressDialog::Observe(itk::Object *caller) { caller->AddObserver( itk::ProgressEvent(), m_RedrawCommand.GetPointer() ); } } // end namespace fltk GoFigure2-v0.9.0/Code/ExternalCode/itkQt/itkQtProgressDialog.h0000644000175000017500000000576511667757442024046 0ustar mathieumathieu /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkQtProgressDialog_h #define __itkQtProgressDialog_h #include #include "itkCommand.h" #include "itkQtConfigure.h" namespace itk { class IKTQT_EXPORT QtProgressDialog : public ::QProgressDialog { public: /** Command Class invoked for button redraw */ typedef itk::MemberCommand< QtProgressDialog > RedrawCommandType; /** Constructor */ explicit QtProgressDialog( QWidget * parent = 0, Qt::WindowFlags f = 0 ); explicit QtProgressDialog( const QString & labelText, const QString & cancelButtonText, int minimum, int maximum, QWidget * parent = 0, Qt::WindowFlags f = 0 ); /** Get Command */ RedrawCommandType * GetRedrawCommand(void) const; /** Manage a Progress event */ void ProcessEvent(itk::Object *caller, const itk::EventObject & event); void ConstProcessEvent(const itk::Object *caller, const itk::EventObject & event); /** Manage a Progress event */ void Observe(itk::Object *caller); private: Q_DISABLE_COPY( QtProgressDialog ); RedrawCommandType::Pointer m_RedrawCommand; }; } // end of namespace #endif GoFigure2-v0.9.0/Code/ExternalCode/itkQt/itkQtAdaptor.h0000644000175000017500000001255611667757442022510 0ustar mathieumathieu/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkQtAdaptor.h,v $ Language: C++ Date: $Date: 2002-09-13 14:32:40 $ Version: $Revision: 1.4 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkQtAdaptor_h #define __itkQtAdaptor_h #include #include "itkObject.h" #include "itkObjectFactory.h" #include "itkCommand.h" #include "itkQtConfigure.h" namespace itk { /** Helper class that interface with Qt Signals and Slots */ class IKTQT_EXPORT QtTranslator:public QObject { Q_OBJECT public: QtTranslator() {} virtual ~QtTranslator() {} signals: void Signal(); public slots: virtual void Slot() {} virtual void Slot(int) {} virtual void Slot(double) {} }; /** Helper class that interface Methods with Qt Slots */ template< typename T > class IKTQT_EXPORT QtSlotAdaptor:public QtTranslator { typedef void ( T::*TMemberFunctionVoidPointer )(); typedef void ( T::*TMemberFunctionIntPointer )(int); typedef void ( T::*TMemberFunctionDoublePointer )(double); public: QtSlotAdaptor():m_MemberFunctionVoid(0), m_MemberFunctionInt(0), m_MemberFunctionDouble(0) {} virtual ~QtSlotAdaptor() {} /** Specify the callback function. */ void SetCallbackFunction(T *object, TMemberFunctionVoidPointer memberFunction) { m_This = object; m_MemberFunctionVoid = memberFunction; } /** Specify the callback function. */ void SetCallbackFunction(T *object, TMemberFunctionIntPointer memberFunction) { m_This = object; m_MemberFunctionInt = memberFunction; } /** Specify the callback function. */ void SetCallbackFunction(T *object, TMemberFunctionDoublePointer memberFunction) { m_This = object; m_MemberFunctionDouble = memberFunction; } /** Slot to be connected to Qt Signals. */ void Slot() { if ( m_MemberFunctionVoid ) { ( ( *m_This ).*( m_MemberFunctionVoid ) )( ); } } /** Slot to be connected to Qt Signals. */ void Slot(int value) { if ( m_MemberFunctionInt ) { ( ( *m_This ).*( m_MemberFunctionInt ) )( value ); } } /** Slot to be connected to Qt Signals. */ void Slot(double value) { if ( m_MemberFunctionDouble ) { ( ( *m_This ).*( m_MemberFunctionDouble ) )( value ); } } protected: T * m_This; TMemberFunctionVoidPointer m_MemberFunctionVoid; TMemberFunctionIntPointer m_MemberFunctionInt; TMemberFunctionDoublePointer m_MemberFunctionDouble; }; /** Helper class that interface Observers with Qt Signals */ class IKTQT_EXPORT QtSignalAdaptor:public QtTranslator { typedef SimpleMemberCommand< QtSignalAdaptor > CommandType; public: QtSignalAdaptor() { m_Command = CommandType::New(); m_Command->SetCallbackFunction(this, &QtSignalAdaptor::EmitSignal); } virtual ~QtSignalAdaptor() {} CommandType * GetCommand() { return m_Command; } void EmitSignal() { emit Signal(); } private: CommandType::Pointer m_Command; }; } // end namespace #endif GoFigure2-v0.9.0/Code/ExternalCode/itkQt/itkQtProgressBar.cxx0000644000175000017500000001042011667757442023706 0ustar mathieumathieu/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkQtProgressBar.cxx,v $ Language: C++ Date: $Date: 2002-09-13 14:32:01 $ Version: $Revision: 1.3 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkProcessObject.h" #include "itkQtProgressBar.h" namespace itk { /** Constructor */ QtProgressBar::QtProgressBar(QWidget *iParent) : QProgressBar(iParent) { m_RedrawCommand = RedrawCommandType::New(); m_RedrawCommand->SetCallbackFunction(this, &QtProgressBar::ProcessEvent); m_RedrawCommand->SetCallbackFunction(this, &QtProgressBar::ConstProcessEvent); this->setMinimum(0); this->setMaximum(100); this->reset(); } /** Get Command */ QtProgressBar::RedrawCommandType * QtProgressBar::GetRedrawCommand(void) const { return m_RedrawCommand.GetPointer(); } /** Manage a Progress event */ void QtProgressBar::ProcessEvent(itk::Object *caller, const itk::EventObject & iEvent) { if ( typeid( itk::ProgressEvent ) == typeid( iEvent ) ) { ::itk::ProcessObject::Pointer process = dynamic_cast< itk::ProcessObject * >( caller ); const int tempvalue = static_cast< int >( process->GetProgress() * static_cast< float >( this->maximum() ) ); std::cout << "New Value : " << tempvalue << std::endl; this->setValue(tempvalue); } } void QtProgressBar::ConstProcessEvent(const itk::Object *caller, const itk::EventObject & iEvent) { if ( typeid( itk::ProgressEvent ) == typeid( iEvent ) ) { itk::ProcessObject::ConstPointer process = dynamic_cast< const itk::ProcessObject * >( caller ); const int temp_value = static_cast< int >( process->GetProgress() * static_cast< float >( this->maximum() ) ); std::cout << "New Value : " << temp_value << std::endl; this->setValue(temp_value); } } /** Manage a Progress event */ void QtProgressBar::Observe(itk::Object *caller) { caller->AddObserver( itk::ProgressEvent(), m_RedrawCommand.GetPointer() ); } } // end namespace fltkGoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/0000755000175000017500000000000011667757442020061 5ustar mathieumathieuGoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/0000755000175000017500000000000011667757442023431 5ustar mathieumathieuGoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkInteractorStyleImage3D.cxx0000644000175000017500000003402611667757442031174 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkInteractorStyleImage3D.h" #include #include #include "vtkRenderer.h" #include "vtkProperty.h" #include "vtkViewImage3DCommand.h" #include // For picking #include "vtkAbstractPropPicker.h" #include "vtkAssemblyPath.h" vtkCxxRevisionMacro (vtkInteractorStyleImage3D, "$Revision: 1 $"); vtkStandardNewMacro (vtkInteractorStyleImage3D); //---------------------------------------------------------------------------- vtkInteractorStyleImage3D::vtkInteractorStyleImage3D() { this->m_Mode = InteractionTypeDefault; m_State = false; } //---------------------------------------------------------------------------- vtkInteractorStyleImage3D:: ~vtkInteractorStyleImage3D() { } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::OnMouseMove() { switch ( this->State ) { case VTKIS_PICK3D: HighlightCurrentActor(); break; } this->Superclass::OnMouseMove(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::OnLeftButtonDown() { switch ( this->m_Mode ) { case InteractionTypeZoom: this->InvokeEvent(vtkViewImage3DCommand::ZoomEvent); this->Superclass::OnRightButtonDown(); break; case InteractionTypePan: this->InvokeEvent(vtkViewImage3DCommand::PanEvent); this->Superclass::OnMiddleButtonDown(); break; case InteractionTypeMeshPicking: this->SetCurrentProp(this->CurrentProp); this->InvokeEvent(vtkViewImage3DCommand::MeshPickingEvent); this->State = VTKIS_NONE; this->Superclass::OnLeftButtonDown(); break; default: this->Superclass::OnLeftButtonDown(); break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::OnLeftButtonUp() { switch ( this->m_Mode ) { case InteractionTypeZoom: this->Superclass::OnRightButtonUp(); break; case InteractionTypePan: this->Superclass::OnMiddleButtonUp(); break; case InteractionTypeMeshPicking: this->State = VTKIS_NONE; this->StartPick(); break; default: this->Superclass::OnLeftButtonUp(); break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::OnRightButtonDown() { switch ( this->m_Mode ) { case InteractionTypePan: this->Superclass::OnMiddleButtonDown(); break; case InteractionTypeMeshPicking: this->State = VTKIS_NONE; this->Superclass::OnRightButtonDown(); break; default: this->Superclass::OnRightButtonDown(); break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::OnRightButtonUp() { switch ( this->m_Mode ) { case InteractionTypePan: this->Superclass::OnMiddleButtonUp(); break; case InteractionTypeMeshPicking: this->State = VTKIS_NONE; this->StartPick(); break; default: this->Superclass::OnRightButtonUp(); break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::OnMiddleButtonDown() { switch ( this->m_Mode ) { case InteractionTypeZoom: this->Superclass::OnRightButtonDown(); break; case InteractionTypeMeshPicking: this->State = VTKIS_NONE; this->Superclass::OnMiddleButtonDown(); break; default: this->Superclass::OnMiddleButtonDown(); break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::OnMiddleButtonUp() { switch ( this->m_Mode ) { case InteractionTypeZoom: this->Superclass::OnRightButtonUp(); break; case InteractionTypeMeshPicking: this->State = VTKIS_NONE; this->StartPick(); break; default: this->Superclass::OnMiddleButtonUp(); break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::OnChar() { vtkRenderWindowInteractor *rwi = this->Interactor; if ( ( rwi->GetKeyCode() == 'w' ) || ( rwi->GetKeyCode() == 'W' ) ) { vtkActorCollection *ac; vtkActor *anActor, *aPart; vtkAssemblyPath *path; this->FindPokedRenderer(rwi->GetEventPosition()[0], rwi->GetEventPosition()[1]); if(this->CurrentRenderer!=0) { ac = this->CurrentRenderer->GetActors(); vtkCollectionSimpleIterator ait; for (ac->InitTraversal(ait); (anActor = ac->GetNextActor(ait)); ) { for (anActor->InitPathTraversal(); (path=anActor->GetNextPath()); ) { // make sure we don't modify the planes actors if ( path != NULL ) { std::vector< vtkProp3D * >::iterator it2 = m_PlanesActors.begin(); while(it2!=m_PlanesActors.end()) { if(path && dynamic_cast(*it2) == path->GetLastNode()->GetViewProp()) { path = NULL; } ++it2; } } // go on if target is not a plane if(path) { aPart=static_cast(path->GetLastNode()->GetViewProp()); aPart->GetProperty()->SetRepresentationToWireframe(); } } } } else { vtkWarningMacro(<<"no current renderer on the interactor style."); } rwi->Render(); return; } else if ( ( rwi->GetKeyCode() == 's' ) || ( rwi->GetKeyCode() == 'S' ) ) { vtkActorCollection *ac; vtkActor *anActor, *aPart; vtkAssemblyPath *path; this->FindPokedRenderer(rwi->GetEventPosition()[0], rwi->GetEventPosition()[1]); if(this->CurrentRenderer!=0) { ac = this->CurrentRenderer->GetActors(); vtkCollectionSimpleIterator ait; for (ac->InitTraversal(ait); (anActor = ac->GetNextActor(ait)); ) { for (anActor->InitPathTraversal(); (path=anActor->GetNextPath()); ) { // make sure we don't modify the planes actors if ( path != NULL ) { std::vector< vtkProp3D * >::iterator it2 = m_PlanesActors.begin(); while(it2!=m_PlanesActors.end()) { if(path && dynamic_cast(*it2) == path->GetLastNode()->GetViewProp()) { path = NULL; } ++it2; } } // go on if target is not a plane if(path) { aPart=static_cast(path->GetLastNode()->GetViewProp()); aPart->GetProperty()->SetRepresentationToSurface(); } } } } else { vtkWarningMacro(<<"no current renderer on the interactor style."); } rwi->Render(); return; } this->Superclass::OnChar(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::SetCurrentProp(vtkProp *iCurrent) { this->m_CurrentProp = iCurrent; } //---------------------------------------------------------------------------- vtkProp * vtkInteractorStyleImage3D::GetCurrentProp() { return this->m_CurrentProp; } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::SetCurrentState(bool iState) { m_State = iState; } //---------------------------------------------------------------------------- bool vtkInteractorStyleImage3D::GetCurrentState() { return m_State; } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::StartPick() { if ( this->State != VTKIS_NONE ) { return; } this->StartState(VTKIS_PICK3D); this->InvokeEvent(vtkCommand::StartPickEvent, this); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::HighlightCurrentActor() { vtkRenderWindowInteractor *rwi = this->Interactor; if ( this->CurrentRenderer != 0 ) { vtkAssemblyPath *path = NULL; int * eventPos = rwi->GetEventPosition(); this->FindPokedRenderer(eventPos[0], eventPos[1]); rwi->StartPickCallback(); vtkAbstractPropPicker *picker = vtkAbstractPropPicker::SafeDownCast( rwi->GetPicker() ); if ( picker != NULL ) { picker->Pick(eventPos[0], eventPos[1], 0.0, this->CurrentRenderer); path = picker->GetPath(); } // check if item does does not belong to phantom[] if ( path != NULL ) { std::vector< vtkProp3D * >::iterator it2 = m_PlanesActors.begin(); while(it2!=m_PlanesActors.end()) { if(path && dynamic_cast(*it2) == path->GetFirstNode()->GetViewProp()) { path = NULL; } ++it2; } } if ( path == NULL ) { this->HighlightProp(NULL); this->PropPicked = 0; } else { this->HighlightProp( path->GetFirstNode()->GetViewProp() ); this->PropPicked = 1; } rwi->EndPickCallback(); } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::EnablePickMode() { this->State = VTKIS_NONE; this->m_Mode = InteractionTypeMeshPicking; this->StartPick(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::EnableZoomMode() { this->State = VTKIS_NONE; this->m_Mode = InteractionTypeZoom; } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::EnablePanMode() { this->State = VTKIS_NONE; this->m_Mode = InteractionTypePan; } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D::EnableDefaultMode() { this->State = VTKIS_NONE; this->m_Mode = InteractionTypeDefault; } //---------------------------------------------------------------------------- void vtkInteractorStyleImage3D:: SetPlanesActors( std::vector< vtkProp3D * > iBounds) { this->m_PlanesActors = iBounds; } //---------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2DCollection.cxx0000644000175000017500000005232411667757442030767 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkViewImage2DCollection.h" #include "vtkSmartPointer.h" #include "vtkCamera.h" #include "vtkCommand.h" #include "vtkImageActor.h" #include "vtkImageData.h" #include "vtkImageMapToWindowLevelColors.h" #include "vtkInteractorStyleImage.h" #include "vtkObjectFactory.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkRendererCollection.h" #include "vtkMatrix4x4.h" #include "vtkScalarBarActor.h" #include "vtkOrientationAnnotation.h" #include "vtkCornerAnnotation.h" #include "vtkTextProperty.h" #include "vtkLookupTable.h" #include "vtkMath.h" #include "vtkPlane.h" #include "vtkCutter.h" // #include "vtkQuadricLODActor.h" #include "vtkActor.h" #include "vtkPolyDataMapper.h" #include "vtkDataSetCollection.h" #include "vtkPoints.h" #include "vtkIdList.h" #include "vtkOutlineSource.h" #include "vtkMatrixToLinearTransform.h" #include "vtkPointData.h" #include "vtkUnsignedCharArray.h" #include "vtkIntArray.h" #include "vtkImageAccumulate.h" #include "vtkProperty.h" #include "vtkViewImage2DCommand.h" #include "vtkViewImage2DCollectionCommand.h" #include "vtkInteractorStyleImage2D.h" #include "vtkCellPicker.h" #include #include #include vtkCxxRevisionMacro(vtkViewImage2DCollection, "$Revision: 490 $"); vtkStandardNewMacro(vtkViewImage2DCollection); //---------------------------------------------------------------------------- vtkViewImage2DCollection::vtkViewImage2DCollection() : ExtraRenderWindow(0) { this->Command = vtkViewImage2DCollectionCommand::New(); this->Command->SetCollection(this); } //---------------------------------------------------------------------------- vtkViewImage2DCollection::~vtkViewImage2DCollection() { this->Command->Delete(); int n = this->GetNumberOfItems(); for ( int i = 0; i < n*n; i++ ) { PlanesActors[i]->Delete(); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::InitializeAllObservers() { this->InitTraversal(); vtkViewImage2D *a = this->GetNextItem(); while ( a ) { vtkInteractorStyle *style = a->GetInteractorStyle(); style->RemoveObservers(vtkViewImage2DCommand::SyncViewsEvent); style->RemoveObservers(vtkViewImage2DCommand::ResetViewerEvent); style->RemoveObservers(vtkViewImage2DCommand::RequestedPositionEvent); style->AddObserver(vtkViewImage2DCommand::SyncViewsEvent, this->Command); style->AddObserver(vtkViewImage2DCommand::ZoomEvent, this->Command); style->AddObserver(vtkViewImage2DCommand::PanEvent, this->Command); style->AddObserver(vtkViewImage2DCommand::RequestedPositionEvent, this->Command); style->AddObserver(vtkViewImage2DCommand::ResetViewerEvent, this->Command); style->AddObserver(vtkViewImage2DCommand::ContourPickingEvent, this->Command); style->AddObserver(vtkViewImage2DCommand::MeshPickingEvent, this->Command); style->AddObserver(vtkCommand::StartWindowLevelEvent, this->Command); style->AddObserver(vtkCommand::ResetWindowLevelEvent, this->Command); style->AddObserver(vtkCommand::WindowLevelEvent, this->Command); a = this->GetNextItem(); } } //---------------------------------------------------------------------------- // Add an object to the list. Does not prevent duplicate entries. void vtkViewImage2DCollection::AddItem(vtkViewImage2D *a) { this->Superclass::AddItem (a); } //---------------------------------------------------------------------------- // Remove an object from the list. Removes the first object found, not // all occurrences. If no object found, list is unaffected. See warning // in description of RemoveItem(int). void vtkViewImage2DCollection::RemoveItem(vtkViewImage2D *a) { this->Superclass::RemoveItem (a); } //---------------------------------------------------------------------------- // Remove all objects from the list. void vtkViewImage2DCollection::RemoveAllItems() { this->Superclass::RemoveAllItems(); } //---------------------------------------------------------------------------- // Replace the i'th item in the collection with a void vtkViewImage2DCollection::ReplaceItem(int i, vtkViewImage2D *a) { this->Superclass::ReplaceItem(i, a); } //---------------------------------------------------------------------------- // Remove the i'th item in the list. // Be careful if using this function during traversal of the list using // GetNextItemAsObject (or GetNextItem in derived class). The list WILL // be shortened if a valid index is given! If this->Current is equal to the // element being removed, have it point to then next element in the list. void vtkViewImage2DCollection::RemoveItem(int i) { this->Superclass::RemoveItem (i); } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::Initialize() { vtkSmartPointer< vtkProperty > plane_property = vtkSmartPointer< vtkProperty >::New(); plane_property->SetRepresentationToWireframe(); int n = this->GetNumberOfItems(); for ( int i = 0; i < n; i++ ) { for ( int j = 0; j < n; j++ ) { vtkActor *temp = this->GetItem(j)->AddDataSet( this->GetItem(i)->GetSlicePlane(), plane_property, ( i != j ), true); //store all slice actors this->PlanesActors.push_back(dynamic_cast(temp)); } } for ( int i = 0; i < n; i++ ) { //store image actors this->PlanesActors.push_back( dynamic_cast(this->GetItem(i)->GetImageActor())); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SyncSetBackground(double *rgb) { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item->SetBackground(rgb); item = this->GetNextItem(); } if ( this->ExtraRenderWindow ) { vtkRenderer *ren = this->ExtraRenderWindow->GetRenderers()->GetFirstRenderer(); ren->SetBackground(rgb); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SyncRender(void) { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item->Render(); item = this->GetNextItem(); } if ( this->ExtraRenderWindow ) { this->ExtraRenderWindow->Render(); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SyncRender(vtkViewImage2D *iV) { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { if ( item != iV ) { item->Render(); } item = this->GetNextItem(); } if ( this->ExtraRenderWindow ) { this->ExtraRenderWindow->Render(); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SyncReset(void) { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item->Reset(); item = this->GetNextItem(); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SyncResetWindowLevel(void) { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item->ResetWindowLevel(); item = this->GetNextItem(); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SyncUpdateWindowLevel(void) { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item->UpdateWindowLevel(); item = this->GetNextItem(); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SyncPan() { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item = this->GetNextItem(); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SyncSetZoomAndParallelScale(double Zoom, double ParallelScale) { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); double t = ParallelScale / Zoom; while ( item ) { item->SetZoom(Zoom); item->GetRenderer()->GetActiveCamera()->SetParallelScale(t); if ( item->GetInteractorStyle()->GetInteractor()->GetLightFollowCamera() ) { item->GetRenderer()->UpdateLightsGeometryToFollowCamera(); } item->Render(); item = this->GetNextItem(); } } //---------------------------------------------------------------------------- /** * \brief Set the visibility of the slice plane actors * \param[in] iVisibility true to see the actors, false to hide the actors */ void vtkViewImage2DCollection::SetSplinePlaneActorsVisibility(bool iVisibility) { // vtkstd::vector::iterator std::vector< vtkProp3D * >::iterator PlanesActorsIterator = PlanesActors.begin(); while ( PlanesActorsIterator != PlanesActors.end() ) { ( *PlanesActorsIterator )->SetVisibility(iVisibility); ++PlanesActorsIterator; } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SyncResetCamera(void) { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item->ResetCamera (); item = this->GetNextItem(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SyncStart(void) { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item->GetInteractor()->Start(); item = this->GetNextItem(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SetLinkSliceMove(unsigned int v) { this->LinkSliceMove = v; this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { vtkInteractorStyle *style = item->GetInteractorStyle(); if ( v ) { if ( !style->HasObserver (vtkViewImage2DCommand::SyncViewsEvent, this->Command) ) { style->AddObserver (vtkViewImage2DCommand::SyncViewsEvent, this->Command); } } else { style->RemoveObservers (vtkViewImage2DCommand::SyncViewsEvent, this->Command); } item = this->GetNextItem(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SetLinkColorWindowLevel(unsigned int v) { this->LinkColorWindowLevel = v; this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { vtkInteractorStyle *style = item->GetInteractorStyle(); if ( v ) { if ( !style->HasObserver (vtkCommand::WindowLevelEvent, this->Command) ) { style->AddObserver (vtkCommand::WindowLevelEvent, this->Command); } } else { style->RemoveObservers (vtkCommand::WindowLevelEvent, this->Command); } item = this->GetNextItem(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SetLinkResetWindowLevel(unsigned int v) { this->LinkResetWindowLevel = v; this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { vtkInteractorStyle *style = item->GetInteractorStyle(); if ( v ) { if ( !style->HasObserver(vtkCommand::ResetWindowLevelEvent, this->Command) ) { style->AddObserver (vtkCommand::ResetWindowLevelEvent, this->Command); } } else { style->RemoveObservers (vtkCommand::ResetWindowLevelEvent, this->Command); } item = this->GetNextItem(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SetLinkResetViewer(unsigned int v) { this->LinkResetViewer = v; this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { vtkInteractorStyle *style = item->GetInteractorStyle(); if ( v ) { if ( !style->HasObserver (vtkViewImage2DCommand::ResetViewerEvent, this->Command) ) { style->AddObserver (vtkViewImage2DCommand::ResetViewerEvent, this->Command); } } else { style->RemoveObservers (vtkViewImage2DCommand::ResetViewerEvent, this->Command); } } item = this->GetNextItem(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SetLinkRequestedPosition(unsigned int v) { this->LinkRequestedPosition = v; this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { vtkInteractorStyle *style = item->GetInteractorStyle(); if ( v ) { if ( !style->HasObserver (vtkViewImage2DCommand::RequestedPositionEvent, this->Command) ) { style->AddObserver (vtkViewImage2DCommand::RequestedPositionEvent, this->Command); } } else { style->RemoveObservers (vtkViewImage2DCommand::RequestedPositionEvent, this->Command); } item = this->GetNextItem(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SetLinkCamera(unsigned int v) { this->LinkCamera = v; this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { vtkInteractorStyle *style = item->GetInteractorStyle(); if ( v ) { if ( !style->HasObserver(vtkViewImage2DCommand::CameraMoveEvent, this->Command) ) { item->GetInteractorStyle()->AddObserver(vtkViewImage2DCommand::CameraMoveEvent, this->Command); } } else { style->RemoveObservers(vtkViewImage2DCommand::CameraMoveEvent, this->Command); } item = this->GetNextItem(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SetLinkPosition(unsigned int v) { this->LinkPosition = v; this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { vtkInteractorStyle *style = item->GetInteractorStyle(); if ( v ) { if ( !style->HasObserver(vtkViewImage2DCommand::DefaultMoveEvent, this->Command) ) { style->AddObserver(vtkViewImage2DCommand::DefaultMoveEvent, this->Command); } else { style->RemoveObservers(vtkViewImage2DCommand::DefaultMoveEvent, this->Command); } } item = this->GetNextItem(); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SetShowAxes(unsigned int v) { std::cout << "in show axe-nothing here" << std::endl; // unused argument v (void)v; /*this->ShowAxes = v; for (int i=0; iGetNumberOfItems(); i++) { vtkViewImage2D* Vi = vtkViewImage2D::SafeDownCast (this->GetItem (i)); for (int j=0; jGetNumberOfItems(); j++) { vtkViewImage2D* Vj = vtkViewImage2D::SafeDownCast (this->GetItem (j)); if (Vi && Vj) if (i != j) { vtkActor* a = Vi->GetDataSetActor (Vj->GetSlicePlane()); a->SetVisibility (this->ShowAxes); } } }*/ } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::EnableDefaultInteractionMode() { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item->SetDefaultInteractionStyle(); item = this->GetNextItem(); } /*if (this->ExtraRenderWindow) { this->ExtraRenderWindow->GetInteractor()->GetInteractorStyle()->EnableDefaultMode(); }*/ } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::EnableZoomInteractionMode() { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item->SetZoomInteractionStyle(); item = this->GetNextItem(); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::EnablePanInteractionMode() { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item->SetPanInteractionStyle(); item = this->GetNextItem(); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::EnableContourPickingMode() { this->InitTraversal(); vtkViewImage2D *item = this->GetNextItem(); while ( item ) { item->SetPickInteractionStyle(); item = this->GetNextItem(); } } //---------------------------------------------------------------------------- void vtkViewImage2DCollection::SynchronizeViews( bool iSynchronize) { this->Command->SynchronizeViews(iSynchronize); if( iSynchronize ) { this->SyncResetCamera(); this->SyncRender(); } } //---------------------------------------------------------------------------- std::vector< vtkProp3D * > vtkViewImage2DCollection:: GetPlanesActors() { return this->PlanesActors; } //---------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2DCollectionCommand.cxx0000644000175000017500000001547311667757442032272 0ustar mathieumathieu/*========================================================================= Author: $Author:$ // Author of last commit Version: $Rev:$ // Revision of last commit Date: $Date:$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkViewImage2DCollectionCommand.h" #include "vtkInteractorStyleImage2D.h" #include "vtkViewImage2DCommand.h" #include "vtkRenderer.h" #include "vtkCamera.h" #include "vtkMath.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkCellPicker.h" #include "vtkViewImage2DCollection.h" //-------------------------------------------------------------------------- vtkViewImage2DCollectionCommand::vtkViewImage2DCollectionCommand() { m_SynchronizeViews = true; } //-------------------------------------------------------------------------- vtkViewImage2DCollectionCommand:: ~vtkViewImage2DCollectionCommand() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void vtkViewImage2DCollectionCommand::SetCollection(vtkViewImage2DCollection *p) { this->Collection = p; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkViewImage2DCollectionCommand * vtkViewImage2DCollectionCommand::New() { return new vtkViewImage2DCollectionCommand; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- vtkViewImage2DCollection * vtkViewImage2DCollectionCommand::GetCollection() { return this->Collection; } //-------------------------------------------------------------------------- void vtkViewImage2DCollectionCommand::SynchronizeViews( bool iSynchronizeViews) { m_SynchronizeViews = iSynchronizeViews; } //-------------------------------------------------------------------------- void vtkViewImage2DCollectionCommand::Execute( vtkObject *caller, unsigned long event, void *vtkNotUsed(callData) ) { if ( !this->Collection ) { return; } if( !m_SynchronizeViews ) { return; } if ( event == vtkCommand::EndInteractionEvent ) { this->Collection->SyncRender(); return; } vtkInteractorStyleImage2D *isi = vtkInteractorStyleImage2D::SafeDownCast(caller); this->GetCollection()->InitTraversal(); vtkViewImage2D *v = this->GetCollection()->GetNextItem(); vtkViewImage2D *viewer = NULL; while ( v ) { if ( isi == v->GetInteractorStyle() ) { viewer = v; break; } v = this->GetCollection()->GetNextItem(); } if ( !isi || !viewer || !viewer->GetInput() ) { return; } // Reset if ( event == vtkCommand::ResetWindowLevelEvent ) { this->Collection->SyncResetWindowLevel(); this->Collection->SyncRender(); return; } // Reset if ( event == vtkViewImage2DCommand::ResetViewerEvent ) { this->Collection->SyncReset(); this->Collection->SyncRender(); return; } // Adjust the window level here if ( event == vtkCommand::WindowLevelEvent ) { this->Collection->SyncSetColorWindow( viewer->GetColorWindow() ); this->Collection->SyncSetColorLevel( viewer->GetColorLevel() ); this->Collection->SyncRender(); } // Move if ( event == vtkViewImage2DCommand::SyncViewsEvent ) { this->Collection->SyncRender(); } if ( event == vtkViewImage2DCommand::ZoomEvent ) { double z = viewer->GetZoom(); double parallel_scale = viewer->GetRenderer()->GetActiveCamera()->GetParallelScale(); this->Collection->SyncSetZoomAndParallelScale(z, parallel_scale); } if ( event == vtkViewImage2DCommand::PanEvent ) { double motion[3]; viewer->GetCameraMotionVector(motion); this->GetCollection()->InitTraversal(); v = this->GetCollection()->GetNextItem(); double focal[3], pos[3], n[3]; double dot = 0., u; while ( v ) { if ( v != viewer ) { v->GetCameraFocalAndPosition(focal, pos); v->GetRenderer()->GetActiveCamera()->GetViewPlaneNormal(n); dot = vtkMath::Dot(n, motion); for ( int dim = 0; dim < 3; dim++ ) { u = motion[dim] - dot * n[dim]; focal[dim] += u; pos[dim] += u; } v->SetCameraFocalAndPosition(focal, pos); if ( v->GetInteractorStyle()->GetInteractor()->GetLightFollowCamera() ) { v->GetRenderer()->UpdateLightsGeometryToFollowCamera(); } } v->Render(); v = this->GetCollection()->GetNextItem(); } } // Position requested if ( event == vtkViewImage2DCommand::RequestedPositionEvent ) { double *position = viewer->GetWorldCoordinatesFromDisplayPosition ( isi->GetRequestedPosition () ); this->Collection->SyncSetWorldCoordinates(position); this->Collection->SyncRender(); } } GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkFillImageWithPolyData.cxx0000644000175000017500000004171511667757442031035 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkFillImageWithPolyData.h" #include "vtkImageData.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkStreamingDemandDrivenPipeline.h" #include "vtkPoints.h" #include "vtkMath.h" // extern int vtkrint(double a); vtkCxxRevisionMacro (vtkFillImageWithPolyData, "$Revision: 490 $"); vtkStandardNewMacro (vtkFillImageWithPolyData); vtkFillImageWithPolyData::vtkFillImageWithPolyData() { this->PolyData = 0; this->InsidePixelValue = 1.0; this->ExtractionDirection = 0; } vtkFillImageWithPolyData::~vtkFillImageWithPolyData() { if ( this->PolyData ) { this->PolyData->Delete(); } } //---------------------------------------------------------------------------- // The output extent is the intersection. int vtkFillImageWithPolyData::RequestInformation( vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector) { (void)inputVector; // get the info objects vtkInformation *outInfo = outputVector->GetInformationObject(0); // copy the polydata bounding box into bbox if ( this->PolyData ) { this->PolyData->GetBounds (BBox); } vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_UNSIGNED_CHAR, 1); return 1; } void vtkFillImageWithPolyData::PrintSelf(ostream & os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); if ( this->PolyData ) { os << indent << "PolyData: \n"; os << indent << *PolyData << endl; } } //---------------------------------------------------------------------------- // This templated function executes the filter for any type of data. template< class T > void vtkFillImageWithPolyDataExecuteZ(vtkFillImageWithPolyData *self, int ext[6], vtkImageData *inData, T *in1Ptr, vtkImageData *outData, unsigned char *outPtr, int id, int slice, double bbox[6]) { int idx0, idx1, idx2; vtkIdType in1Inc0, in1Inc1, in1Inc2; vtkIdType outInc0, outInc1, outInc2; unsigned long count = 0; unsigned long target; // numC = outData->GetNumberOfScalarComponents(); // pixSize = numC * static_cast< int >( sizeof( T ) ); // Get information to march through data inData->GetContinuousIncrements(ext, in1Inc0, in1Inc1, in1Inc2); outData->GetContinuousIncrements(ext, outInc0, outInc1, outInc2); int num0 = ext[1] - ext[0] + 1; int num1 = ext[3] - ext[2] + 1; int num2 = ext[5] - ext[4] + 1; double outVal = self->GetInsidePixelValue(); vtkPoints *points = self->GetPolyData()->GetPoints(); vtkIdType numP = self->GetPolyData()->GetNumberOfPoints(); double *spacing = inData->GetSpacing(); double *origin = inData->GetOrigin(); target = (unsigned long)( num2 * num1 / 50.0 ); target++; // Loop through ouput pixels for ( idx2 = ext[4]; idx2 < ext[4] + num2; ++idx2 ) { for ( idx1 = ext[2]; !self->AbortExecute && idx1 < ext[2] + num1; ++idx1 ) { if ( !id ) { if ( !( count % target ) ) { self->UpdateProgress( static_cast< double >( count ) / ( 50.0 * static_cast< double >( target ) ) ); } count++; } for ( idx0 = ext[0]; idx0 < ext[0] + num0; ++idx0 ) { double val = 0.0; if ( idx2 == slice ) { double x = idx0 * spacing[0] + origin[0]; double y = idx1 * spacing[1] + origin[1]; if ( x >= bbox[0] && x <= bbox[1] && y >= bbox[2] && y <= bbox[3] ) { double angle = 0; for ( int i = 0; i < numP; i++ ) { double p1[3], p2[3], dp1[2], dp2[2]; points->GetPoint (i, p1); points->GetPoint ( ( i + 1 ) % numP, p2 ); dp1[0] = p1[0] - x; dp1[1] = p1[1] - y; dp2[0] = p2[0] - x; dp2[1] = p2[1] - y; angle += self->Angle2D (dp1, dp2); } if ( fabs (angle) >= vtkMath::Pi() ) { val = outVal; } } } *outPtr = (unsigned char)( val ); ++outPtr; in1Ptr += in1Inc0; } in1Ptr += in1Inc1; outPtr += outInc1; } in1Ptr += in1Inc2; outPtr += outInc2; } } //---------------------------------------------------------------------------- // This templated function executes the filter for any type of data. template< class T > void vtkFillImageWithPolyDataExecuteY(vtkFillImageWithPolyData *self, int ext[6], vtkImageData *inData, T *in1Ptr, vtkImageData *outData, unsigned char *outPtr, int id, int slice, double bbox[6]) { int idx0, idx1, idx2; vtkIdType in1Inc0, in1Inc1, in1Inc2; vtkIdType outInc0, outInc1, outInc2; unsigned long count = 0; unsigned long target; // numC = outData->GetNumberOfScalarComponents(); // int pixSize = numC * static_cast(sizeof(T)); // Get information to march through data inData->GetContinuousIncrements(ext, in1Inc0, in1Inc1, in1Inc2); outData->GetContinuousIncrements(ext, outInc0, outInc1, outInc2); int num0 = ext[1] - ext[0] + 1; int num1 = ext[3] - ext[2] + 1; int num2 = ext[5] - ext[4] + 1; vtkPoints *points = self->GetPolyData()->GetPoints(); vtkIdType numP = self->GetPolyData()->GetNumberOfPoints(); double *spacing = inData->GetSpacing(); double *origin = inData->GetOrigin(); target = (unsigned long)( num2 * num1 / 50.0 ); target++; // Loop through ouput pixels for ( idx2 = ext[4]; idx2 < ext[4] + num2; ++idx2 ) { for ( idx1 = ext[2]; !self->AbortExecute && idx1 < ext[2] + num1; ++idx1 ) { if ( !id ) { if ( !( count % target ) ) { self->UpdateProgress( static_cast< double >( count ) / ( 50.0 * static_cast< double >( target ) ) ); } count++; } for ( idx0 = ext[0]; idx0 < ext[0] + num0; ++idx0 ) { double val = 0.0; if ( idx1 == slice ) { double angle = 0; double x = idx0 * spacing[0] + origin[0]; double y = idx2 * spacing[2] + origin[2]; if ( x >= bbox[0] && x <= bbox[1] && y >= bbox[4] && y <= bbox[5] ) { for ( int i = 0; i < numP; i++ ) { double p1[3], p2[3], dp1[2], dp2[2]; points->GetPoint (i, p1); points->GetPoint ( ( i + 1 ) % numP, p2 ); dp1[0] = p1[0] - x; dp1[1] = p1[2] - y; dp2[0] = p2[0] - x; dp2[1] = p2[2] - y; angle += self->Angle2D (dp1, dp2); } if ( fabs (angle) >= vtkMath::Pi() ) { val = self->GetInsidePixelValue(); } } } *outPtr = (unsigned char)( val ); ++outPtr; in1Ptr += in1Inc0; } in1Ptr += in1Inc1; outPtr += outInc1; } in1Ptr += in1Inc2; outPtr += outInc2; } } //---------------------------------------------------------------------------- // This templated function executes the filter for any type of data. template< class T > void vtkFillImageWithPolyDataExecuteX(vtkFillImageWithPolyData *self, int ext[6], vtkImageData *inData, T *in1Ptr, vtkImageData *outData, unsigned char *outPtr, int id, int slice, double bbox[6]) { int num0, num1, num2; int idx0, idx1, idx2; vtkIdType in1Inc0, in1Inc1, in1Inc2; vtkIdType outInc0, outInc1, outInc2; unsigned long count = 0; unsigned long target; // numC = outData->GetNumberOfScalarComponents(); // pixSize = numC * static_cast< int >( sizeof( T ) ); // Get information to march through data inData->GetContinuousIncrements(ext, in1Inc0, in1Inc1, in1Inc2); outData->GetContinuousIncrements(ext, outInc0, outInc1, outInc2); num0 = ext[1] - ext[0] + 1; num1 = ext[3] - ext[2] + 1; num2 = ext[5] - ext[4] + 1; //get the polydata bounding box //double bbox[6]; //self->GetPolyData()->GetBounds (bbox); vtkPoints *points = self->GetPolyData()->GetPoints(); vtkIdType numP = self->GetPolyData()->GetNumberOfPoints(); double *spacing = inData->GetSpacing(); double *origin = inData->GetOrigin(); target = (unsigned long)( num2 * num1 / 50.0 ); target++; // Loop through ouput pixels for ( idx2 = ext[4]; idx2 < ext[4] + num2; ++idx2 ) { for ( idx1 = ext[2]; !self->AbortExecute && idx1 < ext[2] + num1; ++idx1 ) { if ( !id ) { if ( !( count % target ) ) { self->UpdateProgress( static_cast< double >( count ) / ( 50.0 * static_cast< double >( target ) ) ); } count++; } for ( idx0 = ext[0]; idx0 < ext[0] + num0; ++idx0 ) { double val = 0.0; if ( idx0 == slice ) { double angle = 0; double x = idx1 * spacing[1] + origin[1]; double y = idx2 * spacing[2] + origin[2]; if ( x >= bbox[2] && x <= bbox[3] && y >= bbox[4] && y <= bbox[5] ) { for ( int i = 0; i < numP; i++ ) { double p1[3], p2[3], dp1[2], dp2[2]; points->GetPoint (i, p1); points->GetPoint ( ( i + 1 ) % numP, p2 ); dp1[0] = p1[1] - x; dp1[1] = p1[2] - y; dp2[0] = p2[1] - x; dp2[1] = p2[2] - y; angle += self->Angle2D (dp1, dp2); } if ( fabs (angle) >= vtkMath::Pi() ) { val = self->GetInsidePixelValue(); } } } *outPtr = (unsigned char)( val ); ++outPtr; in1Ptr += in1Inc0; } in1Ptr += in1Inc1; outPtr += outInc1; } in1Ptr += in1Inc2; outPtr += outInc2; } } //---------------------------------------------------------------------------- // This method is passed a input and output Datas, and executes the filter // algorithm to fill the output from the inputs. // It just executes a switch statement to call the correct function for // the Datas data types. void vtkFillImageWithPolyData::ThreadedRequestData( vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *vtkNotUsed(outputVector), vtkImageData ***inData, vtkImageData **outData, int outExt[6], int id) { void *inPtr1; void *outPtr; if ( !PolyData ) { vtkErrorMacro("PolyData not set"); return; } if ( PolyData->GetNumberOfPoints() < 3 ) { vtkErrorMacro("PolyData must have more than 2 points."); return; } // check for the orientation and slice to draw the ROI int slice = 0; double *spacing = inData[0][0]->GetSpacing(); double *origin = inData[0][0]->GetOrigin(); vtkPoints *points = PolyData->GetPoints(); double pt[3]; points->GetPoint (0, pt); if ( ExtractionDirection > 2 || ExtractionDirection < 0 ) { vtkErrorMacro("Dont know extraction direction."); } else { // slice = int( vtkrint ( (pt[0]-origin[0])/spacing[0] )); slice = static_cast< int >( ( pt[ExtractionDirection] - origin[ExtractionDirection] ) / spacing[ExtractionDirection] ); } inPtr1 = inData[0][0]->GetScalarPointerForExtent(outExt); outPtr = outData[0]->GetScalarPointerForExtent(outExt); if ( ExtractionDirection == 2 ) { switch ( inData[0][0]->GetScalarType() ) { vtkTemplateMacro( vtkFillImageWithPolyDataExecuteZ(this, outExt, inData[0][0], (VTK_TT *)( inPtr1 ), outData[0], (unsigned char *)( outPtr ), id, slice, BBox) ); default: vtkErrorMacro(<< "Execute: Unknown ScalarType"); return; } } else { if ( ExtractionDirection == 1 ) { switch ( inData[0][0]->GetScalarType() ) { vtkTemplateMacro( vtkFillImageWithPolyDataExecuteY(this, outExt, inData[0][0], (VTK_TT *)( inPtr1 ), outData[0], (unsigned char *)( outPtr ), id, slice, BBox) ); default: vtkErrorMacro(<< "Execute: Unknown ScalarType"); return; } } else { switch ( inData[0][0]->GetScalarType() ) { vtkTemplateMacro( vtkFillImageWithPolyDataExecuteX(this, outExt, inData[0][0], (VTK_TT *)( inPtr1 ), outData[0], (unsigned char *)( outPtr ), id, slice, BBox) ); default: vtkErrorMacro(<< "Execute: Unknown ScalarType"); return; } } } } double vtkFillImageWithPolyData::Angle2D(const double dp1[2], const double dp2[2]) { double dt, t1, t2; t1 = atan2 (dp1[0], dp1[1]); t2 = atan2 (dp2[0], dp2[1]); dt = t2 - t1; while ( dt > vtkMath::Pi() ) { dt -= 2. * static_cast< double >( vtkMath::Pi() ); } while ( dt < -vtkMath::Pi() ) { dt += 2. * static_cast< double >( vtkMath::Pi() ); } return dt; } GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkOrientationAnnotation.cxx0000644000175000017500000001230311667757442031227 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkOrientationAnnotation.h" #include "vtkObjectFactory.h" #include "vtkTextProperty.h" #include "vtkTextMapper.h" //---------------------------------------------------------------------------- vtkStandardNewMacro(vtkOrientationAnnotation); vtkCxxRevisionMacro(vtkOrientationAnnotation, "$Revision: 490 $"); //---------------------------------------------------------------------------- vtkOrientationAnnotation::vtkOrientationAnnotation() { } //---------------------------------------------------------------------------- vtkOrientationAnnotation::~vtkOrientationAnnotation() { } //---------------------------------------------------------------------------- void vtkOrientationAnnotation::SetTextActorsPosition(int vsize[2]) { this->TextActor[2]->SetPosition(5, vsize[1] / 2); this->TextActor[3]->SetPosition(vsize[0] / 2, 5); this->TextActor[0]->SetPosition(vsize[0] - 5, vsize[1] / 2); this->TextActor[1]->SetPosition(vsize[0] / 2, vsize[1] - 5); } //---------------------------------------------------------------------------- void vtkOrientationAnnotation::SetTextActorsJustification() { vtkTextProperty *tprop = this->TextMapper[2]->GetTextProperty(); tprop->SetJustificationToLeft(); tprop->SetVerticalJustificationToCentered(); tprop = this->TextMapper[3]->GetTextProperty(); tprop->SetJustificationToCentered(); tprop->SetVerticalJustificationToBottom(); tprop = this->TextMapper[0]->GetTextProperty(); tprop->SetJustificationToRight(); tprop->SetVerticalJustificationToCentered(); tprop = this->TextMapper[1]->GetTextProperty(); tprop->SetJustificationToCentered(); tprop->SetVerticalJustificationToTop(); }GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage.cxx0000644000175000017500000005107411667757442026566 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkViewImage.h" #include "vtkInformation.h" #include "vtkSmartPointer.h" #include "vtkCamera.h" #include "vtkCommand.h" #include "vtkImageActor.h" #include "vtkImageData.h" #include "vtkImageMapToWindowLevelColors.h" #include "vtkInteractorStyleImage.h" #include "vtkObjectFactory.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkMatrix4x4.h" #include "vtkScalarBarActor.h" #include "vtkOrientationAnnotation.h" #include "vtkCornerAnnotation.h" #include "vtkTextProperty.h" #include "vtkLookupTable.h" #include "vtkMath.h" #include "vtkPlane.h" #include "vtkCutter.h" #include "vtkProperty.h" #include "vtkActor.h" #include "vtkPolyDataMapper.h" #include "vtkPoints.h" #include "vtkIdList.h" #include "vtkOutlineSource.h" #include "vtkMatrixToLinearTransform.h" #include "vtkPointData.h" #include "vtkUnsignedCharArray.h" #include "vtkIntArray.h" #include "vtkImageAccumulate.h" #include "vtkInteractorStyleImage.h" #include #include vtkCxxRevisionMacro(vtkViewImage, "$Revision: 546 $"); //vtkStandardNewMacro(vtkViewImage); //---------------------------------------------------------------------------- vtkViewImage::vtkViewImage() { this->OrientationMatrix = vtkMatrix4x4::New(); this->CornerAnnotation = vtkCornerAnnotation::New(); this->TextProperty = vtkTextProperty::New(); this->LookupTable = vtkLookupTable::New(); this->ScalarBarActor = vtkScalarBarActor::New(); this->OrientationTransform = vtkMatrixToLinearTransform::New(); this->OrientationMatrix->Identity(); this->CornerAnnotation->SetNonlinearFontScaleFactor (0.35); this->CornerAnnotation->SetTextProperty (this->TextProperty); this->ScalarBarActor->GetLabelTextProperty()->BoldOff(); this->ScalarBarActor->GetLabelTextProperty()->ItalicOff(); this->ScalarBarActor->SetNumberOfLabels (3); this->ScalarBarActor->SetWidth (0.1); this->ScalarBarActor->SetHeight (0.5); this->ScalarBarActor->SetPosition (0.9, 0.3); this->LookupTable->SetTableRange (0, 1); this->LookupTable->SetSaturationRange (0, 0); this->LookupTable->SetHueRange (0, 0); this->LookupTable->SetValueRange (0, 1); this->LookupTable->Build(); this->ShowAnnotations = true; this->ShowScalarBar = true; this->OrientationTransform->SetInput (this->OrientationMatrix); this->ScalarBarActor->SetLookupTable (this->LookupTable); this->Renderer->AddViewProp (this->CornerAnnotation); this->Renderer->AddViewProp (this->ScalarBarActor); this->IntersectionLineWidth = 1.; this->IsColor = false; this->Window = -1; this->Level = -1; // default DirectionAnnotation this->DirectionAnnotationMatrix[0][0] = "R"; this->DirectionAnnotationMatrix[0][1] = "L"; this->DirectionAnnotationMatrix[1][0] = "A"; this->DirectionAnnotationMatrix[1][1] = "P"; this->DirectionAnnotationMatrix[2][0] = "V"; this->DirectionAnnotationMatrix[2][1] = "D"; } //---------------------------------------------------------------------------- void vtkViewImage::SetInput(vtkImageData *in) { if ( in ) { Superclass::SetInput(in); this->IsColor = ( in->GetNumberOfScalarComponents() > 1 ); //multi channel if ( this->IsColor ) { this->ImageActor->SetInput(this->WindowLevel->GetOutput()); this->WindowLevel->SetLookupTable(NULL); // because of rescaling int type = in->GetScalarSize(); double threshold = pow((double)2, (int)8*type) - 1; // reset window level in viewer! this->WindowLevel->SetWindow(threshold); this->WindowLevel->SetLevel(threshold/2); this->ShowScalarBar = false; this->ScalarBarActor->SetVisibility(this->ShowScalarBar); } // single channel else { this->ImageActor->SetInput(this->WindowLevel->GetOutput()); this->WindowLevel->SetLookupTable(this->LookupTable); this->WindowLevel->SetWindow(this->LookupTable->GetRange()[1] - this->LookupTable->GetRange()[0]); this->WindowLevel->SetLevel(this->LookupTable->GetRange()[0] + (this->LookupTable->GetRange()[1]-this->LookupTable->GetRange()[0])/2); this->SetWindow(this->LookupTable->GetRange()[0]); this->SetLevel(this->LookupTable->GetRange()[1]); } } } //---------------------------------------------------------------------------- vtkViewImage::~vtkViewImage() { this->OrientationTransform->SetInput(NULL); if ( this->OrientationMatrix ) { this->OrientationMatrix->Delete(); } this->OrientationTransform->Delete(); this->TextProperty->Delete(); this->CornerAnnotation->Delete(); this->LookupTable->Delete(); this->ScalarBarActor->Delete(); } //---------------------------------------------------------------------------- void vtkViewImage::SetOrientationMatrix(vtkMatrix4x4 *matrix) { vtkSetObjectMacro2Body(OrientationMatrix, vtkMatrix4x4, matrix); this->ImageActor->SetUserMatrix(this->OrientationMatrix); this->OrientationTransform->SetInput(this->OrientationMatrix); this->UpdateOrientation(); } //---------------------------------------------------------------------------- void vtkViewImage::SetLookupTable(vtkLookupTable *lookuptable) { if ( lookuptable ) { vtkSetObjectMacro2Body(LookupTable, vtkLookupTable, lookuptable); this->WindowLevel->SetLookupTable(this->LookupTable); this->ScalarBarActor->SetLookupTable(this->LookupTable); } else { this->ShowScalarBar = false; this->ScalarBarActor->SetVisibility(this->ShowScalarBar); } } //---------------------------------------------------------------------------- void vtkViewImage::SetTextProperty(vtkTextProperty *textproperty) { vtkSetObjectMacro2Body (TextProperty, vtkTextProperty, textproperty); this->CornerAnnotation->SetTextProperty (this->TextProperty); } //---------------------------------------------------------------------------- void vtkViewImage::SetColorWindow(double s) { double t = s; if ( t < 0. ) { t = 1.; } Superclass::SetColorWindow(t); if ( !this->IsColor ) { double level = this->GetColorLevel(); t *= 0.5; double v_min = level - t; double v_max = level + t; this->LookupTable->SetRange (v_min, v_max); } else { this->ShowScalarBar = false; this->ScalarBarActor->SetVisibility(this->ShowScalarBar); } } //---------------------------------------------------------------------------- void vtkViewImage::SetColorLevel(double s) { Superclass::SetColorLevel(s); if ( !this->IsColor ) { double t = 0.5 * this->GetColorWindow(); double v_min = s - t; double v_max = s + t; this->LookupTable->SetRange(v_min, v_max); } else { this->ShowScalarBar = false; this->ScalarBarActor->SetVisibility(this->ShowScalarBar); } } //---------------------------------------------------------------------------- void vtkViewImage::SetWorldCoordinates(const double & x, const double & y, const double & z) { double pos[3] = { x, y, z }; this->SetWorldCoordinates(pos); } //---------------------------------------------------------------------------- double vtkViewImage::GetValueAtPosition(double worldcoordinates[3], int component) { // by default, value = 0.0 double value = 0.0; if ( !this->GetInput() ) { return value; } int *indices = this->GetImageCoordinatesFromWorldCoordinates(worldcoordinates); vtkImageData *input = this->GetInput(); int *extent = input->GetWholeExtent(); if ( !( ( indices[0] < extent[0] ) || ( indices[0] > extent[1] ) || ( indices[1] < extent[2] ) || ( indices[1] > extent[3] ) || ( indices[2] < extent[4] ) || ( indices[2] > extent[5] ) ) ) { value = input->GetScalarComponentAsDouble(indices[0], indices[1], indices[2], component); } // have to free the indices array allocated by // GetImageCoordinatesFromWorldCoordinates delete[] indices; return value; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- double * vtkViewImage::GetWorldCoordinatesFromImageCoordinates(int indices[3]) { vtkImageData *input = this->GetInput(); if ( !input ) { double *nullpos = new double[3]; nullpos[0] = 0.; nullpos[1] = 0.; nullpos[2] = 0.; return nullpos; } // Get information double *spacing = input->GetSpacing(); double *origin = input->GetOrigin(); double unorientedposition[4]; for ( unsigned int i = 0; i < 3; i++ ) { unorientedposition[i] = origin[i] + spacing[i] * indices[i]; } unorientedposition[3] = 1; // apply orientation matrix double *position = new double[4]; this->GetOrientationMatrix()->MultiplyPoint(unorientedposition, position); return position; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /// NOTE indices has to be erased int * vtkViewImage::GetImageCoordinatesFromWorldCoordinates(double position[3]) { vtkImageData *input = this->GetInput(); if ( !input ) { int *nullpos = new int[3]; nullpos[0] = 0; nullpos[1] = 0; nullpos[2] = 0; return nullpos; } // Get information double unorientedposition[4] = { position[0], position[1], position[2], 1 }; double spacing[4] = { input->GetSpacing()[0], input->GetSpacing()[1], input->GetSpacing()[2], 0 }; double origin[4] = { input->GetOrigin()[0], input->GetOrigin()[1], input->GetOrigin()[2], 1 }; // apply inverted orientation matrix to the world-coordinate position vtkSmartPointer< vtkMatrix4x4 > inverse = vtkSmartPointer< vtkMatrix4x4 >::New(); vtkMatrix4x4::Invert (this->GetOrientationMatrix(), inverse); inverse->MultiplyPoint (unorientedposition, unorientedposition); int *indices = new int[3]; for ( unsigned int i = 0; i < 3; i++ ) { if ( fabs (spacing[i]) > 1e-5 ) { indices[i] = vtkMath::Round( ( unorientedposition[i] - origin[i] ) / spacing[i] ); } else { indices[i] = 0; } } return indices; } //---------------------------------------------------------------------------- void vtkViewImage::SetBackground(double rgb[3]) { if ( this->Renderer ) { this->Renderer->SetBackground(rgb); } } //---------------------------------------------------------------------------- void vtkViewImage::SetBackground(const double & r, const double & g, const double & b) { if ( this->Renderer ) { this->Renderer->SetBackground(r, g, b); } } //---------------------------------------------------------------------------- double * vtkViewImage::GetBackground() { if ( this->Renderer ) { return this->Renderer->GetBackground(); } else { return NULL; } } //---------------------------------------------------------------------------- void vtkViewImage::ResetWindowLevel(void) { vtkImageData *input = this->GetInput(); if ( !input ) { return; } if ( !this->IsColor ) { double *range = input->GetScalarRange(); double window = range[1] - range[0]; double level = 0.5 * ( range[1] + range[0] ); this->SetColorWindow(window); this->SetColorLevel(level); } } //---------------------------------------------------------------------------- void vtkViewImage::UpdateWindowLevel(void) { if (this->IsColor) return; if ( LookupTable ) { double *range = LookupTable->GetRange(); double window = range[1] - range[0]; double level = 0.5 * ( range[1] + range[0] ); this->SetColorWindow(window); this->SetColorLevel(level); } else { this->SetColorWindow(0); this->SetColorLevel(0); } } //---------------------------------------------------------------------------- void vtkViewImage::ResetCamera(void) { if ( this->Renderer ) { this->Renderer->ResetCamera(); } } //---------------------------------------------------------------------------- void vtkViewImage::Reset(void) { this->Update(); this->ResetWindowLevel(); this->ResetCamera(); } //---------------------------------------------------------------------------- void vtkViewImage::Enable(void) { this->Interactor->Enable(); } //---------------------------------------------------------------------------- void vtkViewImage::Disable(void) { this->Interactor->Disable(); } //---------------------------------------------------------------------------- bool vtkViewImage::GetEnabled(void) { return ( this->Interactor->GetEnabled() == 1 ); } //---------------------------------------------------------------------------- void vtkViewImage::SetShowScalarBar(const bool & val) { if ( !this->IsColor ) { this->ShowScalarBar = val; this->ScalarBarActor->SetVisibility(val); } else { this->ShowScalarBar = false; this->ScalarBarActor->SetVisibility(this->ShowScalarBar); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage::Render() { if ( this->RenderWindow && !this->RenderWindow->GetNeverRendered() ) { if ( this->FirstRender ) { this->ResetCamera(); this->FirstRender = 0; } } if ( this->GetInput() ) { this->RenderWindow->Render(); } } //---------------------------------------------------------------------------- vtkRenderWindowInteractor * vtkViewImage::GetInteractor() { return this->Interactor; } //---------------------------------------------------------------------------- vtkRenderWindowInteractor * vtkViewImage::GetRenderWindowInteractor() { if ( this->GetRenderWindow() ) { return this->GetRenderWindow()->GetInteractor(); } else { return static_cast< vtkRenderWindowInteractor * >( 0x0 ); } } //---------------------------------------------------------------------------- void vtkViewImage::SetCameraPosition(double *arg) { if ( this->Renderer ) { vtkCamera *cam = this->Renderer->GetActiveCamera(); if ( cam ) { cam->SetPosition (arg); } } } double * vtkViewImage::GetCameraPosition(void) { if ( this->Renderer ) { vtkCamera *cam = this->Renderer->GetActiveCamera(); if ( cam ) { return cam->GetPosition (); } } return static_cast< double * >( 0x0 ); } //---------------------------------------------------------------------------- void vtkViewImage::SetCameraFocalPoint(double *arg) { if ( this->Renderer ) { vtkCamera *cam = this->Renderer->GetActiveCamera(); if ( cam ) { cam->SetFocalPoint (arg); } } } //---------------------------------------------------------------------------- double * vtkViewImage::GetCameraFocalPoint(void) { if ( this->Renderer ) { vtkCamera *cam = this->Renderer->GetActiveCamera(); if ( cam ) { return cam->GetFocalPoint (); } } return static_cast< double * >( 0x0 ); } //---------------------------------------------------------------------------- void vtkViewImage::SetCameraViewUp(double *arg) { if ( this->Renderer ) { vtkCamera *cam = this->Renderer->GetActiveCamera(); if ( cam ) { cam->SetViewUp (arg); } } } //---------------------------------------------------------------------------- double * vtkViewImage::GetCameraViewUp(void) { if ( this->Renderer ) { vtkCamera *cam = this->Renderer->GetActiveCamera(); if ( cam ) { return cam->GetViewUp(); } } return static_cast< double * >( 0x0 ); } //---------------------------------------------------------------------------- void vtkViewImage::SetCameraParallelScale(double arg) { if ( this->Renderer ) { vtkCamera *cam = this->Renderer->GetActiveCamera(); if ( cam ) { cam->SetParallelScale (arg); } } } //---------------------------------------------------------------------------- double vtkViewImage::GetCameraParallelScale(void) { if ( this->Renderer ) { vtkCamera *cam = this->Renderer->GetActiveCamera(); if ( cam ) { return cam->GetParallelScale(); } } return 0.; } //---------------------------------------------------------------------------- void vtkViewImage::SetShowAnnotations(const int & iShowAnnotations) { this->ShowAnnotations = iShowAnnotations; this->CornerAnnotation->SetVisibility (iShowAnnotations); } //---------------------------------------------------------------------------- void vtkViewImage::SetWindow(double iWindow) { this->Window = iWindow; } //---------------------------------------------------------------------------- double vtkViewImage::GetWindow() { return this->Window; } //---------------------------------------------------------------------------- void vtkViewImage::SetLevel(double iLevel) { this->Level = iLevel; } //---------------------------------------------------------------------------- double vtkViewImage::GetLevel() { return this->Level; } GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkPlaneCutter.h0000644000175000017500000001002711667757442026555 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkPlaneCutter_h #define __vtkPlaneCutter_h #include "vtkCutter.h" #include "vtkInformation.h" #include "vtkInformationVector.h" class vtkPlaneCutter : public vtkCutter { public: vtkTypeMacro(vtkPlaneCutter,vtkCutter); static vtkPlaneCutter *New(); protected: vtkPlaneCutter(vtkImplicitFunction *cf=NULL) : vtkCutter(cf) {} virtual ~vtkPlaneCutter() {} virtual int RequestData( vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) { vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); // get the input and output vtkDataSet *input = vtkDataSet::SafeDownCast( inInfo->Get(vtkDataObject::DATA_OBJECT())); if (!this->CutFunction) { vtkErrorMacro("No cut function specified"); return 0; } if ( input->GetNumberOfPoints() < 1 ) { return 1; } double bounds[6]; input->GetBounds( bounds ); double pt[8][3]; int k = 0; pt[k][0] = bounds[0]; pt[k][1] = bounds[2]; pt[k++][2] = bounds[4]; pt[k][0] = bounds[1]; pt[k][1] = bounds[2]; pt[k++][2] = bounds[4]; pt[k][0] = bounds[0]; pt[k][1] = bounds[3]; pt[k++][2] = bounds[4]; pt[k][0] = bounds[0]; pt[k][1] = bounds[3]; pt[k++][2] = bounds[4]; pt[k][0] = bounds[0]; pt[k][1] = bounds[2]; pt[k++][2] = bounds[5]; pt[k][0] = bounds[1]; pt[k][1] = bounds[2]; pt[k++][2] = bounds[5]; pt[k][0] = bounds[0]; pt[k][1] = bounds[3]; pt[k++][2] = bounds[5]; pt[k][0] = bounds[1]; pt[k][1] = bounds[3]; pt[k++][2] = bounds[5]; bool sign0 = ( this->CutFunction->FunctionValue( pt[0] ) > 0. ); bool intersect = false; for( unsigned int i = 1; ( i < 8 ) && ( !intersect ); i++ ) { bool sign = ( this->CutFunction->FunctionValue( pt[i] ) >= 0. ); if( sign != sign0 ) { intersect = true; } } if( intersect ) { return vtkCutter::RequestData( request, inputVector, outputVector ); } else { return 1; } } private: vtkPlaneCutter(const vtkPlaneCutter&); void operator = (const vtkPlaneCutter&); }; vtkStandardNewMacro(vtkPlaneCutter); #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2DCommand.cxx0000644000175000017500000003361311667757442030252 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifdef _MSC_VER # pragma warning (disable : 4018) #endif #include #include #include #include #include #include #include #include #include #include #include "vtkViewImage2D.h" #include "vtkInteractorStyleImage2D.h" #include "vtkViewImage2DCommand.h" #include "vtkInteractorStyleImage2D.h" #include #include //---------------------------------------------------------------------------- vtkViewImage2DCommand::vtkViewImage2DCommand() : Viewer(0) { } //---------------------------------------------------------------------------- void vtkViewImage2DCommand::Execute( vtkObject *caller, unsigned long event, void *vtkNotUsed(callData) ) { vtkInteractorStyleImage2D *isi = static_cast< vtkInteractorStyleImage2D * >( caller ); if ( !isi || !this->Viewer || !this->Viewer->GetInput() ) { return; } // Reset if ( event == vtkCommand::ResetWindowLevelEvent ) { this->Viewer->ResetWindowLevel(); this->Viewer->Render(); return; } // Reset if ( event == vtkViewImage2DCommand::ResetViewerEvent ) { this->Viewer->Reset(); this->Viewer->Render(); return; } // Start if ( event == vtkCommand::StartWindowLevelEvent ) { //no since it is min an max now...! this->InitialWindow = this->Viewer->GetLevel() - this->Viewer->GetWindow(); this->InitialLevel = this->Viewer->GetLevel() - this->InitialWindow/2; return; } // Adjust the window level here if ( event == vtkCommand::WindowLevelEvent ) { this->Windowing(isi); return; } if ( event == vtkViewImage2DCommand::MeshPickingEvent ) { //std::cout << "Mesh pick single" << std::endl; } if ( event == vtkCommand::KeyPressEvent ) { vtkRenderWindowInteractor *rwi = this->Viewer->GetRenderWindow()->GetInteractor(); if ( rwi->GetKeyCode() == 't' ) { this->Viewer->SetViewOrientation ( ( this->Viewer->GetViewOrientation() + 1 ) % 3); this->Viewer->Render(); } else if ( rwi->GetKeyCode() == 'i' ) { this->Viewer->SetInterpolate ( ( this->Viewer->GetInterpolate() + 1 ) % 2 ); this->Viewer->Render(); } return; } if ( event == vtkViewImage2DCommand::EndSliceMoveEvent ) { int step = isi->GetSliceStep(); this->Viewer->SetSlice (this->Viewer->GetSlice() + step); PrintInformation(); } if ( event == vtkViewImage2DCommand::ZoomEvent ) { this->Zooming(); } if ( event == vtkViewImage2DCommand::PanEvent ) { this->Panning(); } // Move // Position Value requested if ( event == vtkViewImage2DCommand::InteractionEvent ) { PrintInformation(); } // Position requested if ( event == vtkViewImage2DCommand::RequestedPositionEvent ) { double *position = this->Viewer->GetWorldCoordinatesFromDisplayPosition ( isi->GetRequestedPosition () ); this->Viewer->SetWorldCoordinates(position); this->Viewer->Render(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCommand::Windowing(vtkInteractorStyleImage2D *isi) { // don't do the window level if the image has more than 1 channel if ( this->Viewer->GetIsColor() ) { return; } int * size = this->Viewer->GetRenderWindow()->GetSize(); double window = this->InitialWindow; double level = this->InitialLevel; // Compute normalized delta double dx = 4.0 * ( isi->GetWindowLevelCurrentPosition()[0] - isi->GetWindowLevelStartPosition()[0] ) / size[0]; double dy = 4.0 * ( isi->GetWindowLevelStartPosition()[1] - isi->GetWindowLevelCurrentPosition()[1] ) / size[1]; // Scale by current values if ( fabs(window) > 0.01 ) { dy = dy * window; } else { dy = dy * ( window < 0 ? -0.01 : 0.01 ); } if ( fabs(level) > 0.01 ) { dx = dx * level; } else { dx = dx * ( level < 0 ? -0.01 : 0.01 ); } // Abs so that direction does not flip if ( window < 0.0 ) { dy = -1 * dy; } if ( level < 0.0 ) { dx = -1 * dx; } // Compute new window level double newWindow = window - dy; double newLevel = level + dx; // Stay away from zero and really if ( fabs(newWindow) < 0.01 ) { newWindow = 0.01 * ( newWindow < 0 ? -1 : 1 ); } if ( fabs(newLevel) < 0.01 ) { newLevel = 0.01 * ( newLevel < 0 ? -1 : 1 ); } // compute new window double min = 0.0; if(newLevel - newWindow /2 > 0) min = newLevel - newWindow /2; double max = this->Viewer->GetInput()->GetScalarRange()[1]; if(newLevel + newWindow /2 < this->Viewer->GetInput()->GetScalarRange()[1]) max = newLevel + newWindow /2; // can happen if we move too fast if(min > max - 2) return; this->Viewer->SetWindow(min); this->Viewer->SetLevel(max); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCommand::PrintInformation() { vtkRenderWindowInteractor *rwi = this->Viewer->GetRenderWindow()->GetInteractor(); double *pos = this->Viewer->GetWorldCoordinatesFromDisplayPosition ( rwi->GetLastEventPosition () ); int *idx = this->Viewer->GetImageCoordinatesFromWorldCoordinates(pos); int dims[3]; this->Viewer->GetInput()->GetDimensions(dims); double spacing[3]; this->Viewer->GetInput()->GetSpacing(spacing); std::ostringstream os; /// \todo dims and spacing must be computed from the orientation of the /// image. os << "Size: " << "[ " << dims[0] << " x " << dims[1] << " x " << dims[2] << " ]" << std::endl; os << "Pixel Size: " << "[ " << spacing[0] << " x " << spacing[1] << " x " << spacing[2] << " ] um" << std::endl; os << "Slice: " << this->Viewer->GetSlice() << " / " << this->Viewer->GetSliceMax() - this->Viewer->GetSliceMin() << std::endl; this->Viewer->GetCornerAnnotation()->SetText ( 2, os.str().c_str() ); std::ostringstream os2; os2 << "Location: " << "[ " << pos[0] << " ; " << pos[1] << " ; " << pos[2] << " ] um" << std::endl; os2 << "Index: " << "[ " << idx[0] << " ; " << idx[1] << " ; " << idx[2] << " ]" << std::endl; if ( !this->Viewer->GetIsColor() ) { os2 << "Value : " << this->Viewer->GetValueAtPosition (pos); } // one display value for single channel images /* * \todo Nicolas- show channel value if we look at a multi channel image */ /*else { os2 << "Value : ["; for ( int i = 0; i < 3; i++ ) { os2 << this->Viewer->GetValueAtPosition (pos, i) << ", "; } os2 << "]"; }*/ this->Viewer->GetCornerAnnotation()->SetText ( 3, os2.str().c_str() ); this->Viewer->Render(); // GetImageCoordinatesFromWorldCoordinates gives a pointer // to allocated but not managed memory : have to cleanup : delete[] idx; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCommand::Zooming() { vtkRenderWindowInteractor *rwi = this->Viewer->GetRenderWindow()->GetInteractor(); rwi->FindPokedRenderer(rwi->GetEventPosition()[0], rwi->GetEventPosition()[1]); vtkRenderer *ren = this->Viewer->GetRenderer(); int *size = ren->GetSize(); int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1]; double factor = 10. * static_cast< double >( dy ) / static_cast< double >( size[1] ); double z = pow(static_cast< double >( 1.1 ), factor); this->Viewer->SetZoom(z); double parallel_scale = this->Viewer->GetRenderer()->GetActiveCamera()->GetParallelScale(); if(parallel_scale == factor) { std::cout << "are equal" << std::endl;} double t = parallel_scale / z; this->Viewer->GetRenderer()->GetActiveCamera()->SetParallelScale(t); // ??? if ( this->Viewer->GetInteractorStyle()->GetInteractor()->GetLightFollowCamera() ) { this->Viewer->GetRenderer()->UpdateLightsGeometryToFollowCamera(); } // item->Render(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2DCommand::Panning() { vtkRenderWindowInteractor *rwi = this->Viewer->GetRenderWindow()->GetInteractor(); double ViewFocus[4], focalDepth, ViewPoint[3]; double NewPickPoint[4], OldPickPoint[4], MotionVector[3]; // Calculate the focal depth since we'll be using it a lot vtkRenderer *ren = this->Viewer->GetRenderer(); vtkCamera * camera = ren->GetActiveCamera(); camera->GetFocalPoint(ViewFocus); vtkInteractorObserver::ComputeWorldToDisplay(ren, ViewFocus[0], ViewFocus[1], ViewFocus[2], ViewFocus); focalDepth = ViewFocus[2]; vtkInteractorObserver::ComputeDisplayToWorld(ren, rwi->GetEventPosition()[0], rwi->GetEventPosition()[1], focalDepth, NewPickPoint); vtkInteractorObserver::ComputeDisplayToWorld(ren, rwi->GetLastEventPosition()[0], rwi->GetLastEventPosition()[1], focalDepth, OldPickPoint); // Camera motion is reversed MotionVector[0] = OldPickPoint[0] - NewPickPoint[0]; MotionVector[1] = OldPickPoint[1] - NewPickPoint[1]; MotionVector[2] = OldPickPoint[2] - NewPickPoint[2]; // Get the current focal point and position camera->GetFocalPoint(ViewFocus); camera->GetPosition(ViewPoint); camera->SetFocalPoint(MotionVector[0] + ViewFocus[0], MotionVector[1] + ViewFocus[1], MotionVector[2] + ViewFocus[2]); camera->SetPosition(MotionVector[0] + ViewPoint[0], MotionVector[1] + ViewPoint[1], MotionVector[2] + ViewPoint[2]); this->Viewer->SetCameraMotionVector(MotionVector); } GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkInteractorStyleImage2D.cxx0000644000175000017500000005112611667757442031173 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkInteractorStyleImage2D.h" #include "vtkAbstractPropPicker.h" #include "vtkAssemblyPath.h" #include "vtkMath.h" #include "vtkObjectFactory.h" #include "vtkRenderWindowInteractor.h" #include #include #include #include #include "vtkProperty.h" #include "vtkViewImage2DCommand.h" vtkCxxRevisionMacro (vtkInteractorStyleImage2D, "$Revision: 490 $"); vtkStandardNewMacro (vtkInteractorStyleImage2D); //---------------------------------------------------------------------------- vtkInteractorStyleImage2D::vtkInteractorStyleImage2D() { this->SliceStep = 0; this->RequestedPosition = new int[2]; this->RequestedPosition[0] = this->RequestedPosition[1] = 0; this->m_LeftButtonDown = false; this->m_SynchronizeViews = true; this->m_Mode = InteractionTypeDefault; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- vtkInteractorStyleImage2D:: ~vtkInteractorStyleImage2D() { delete[] this->RequestedPosition; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnMouseMove() { this->DefaultMoveAction(); switch ( this->State ) { case VTKIS_PAN: this->InvokeEvent(vtkViewImage2DCommand::PanEvent); break; // USEFUL.... case VTKIS_SPIN: case VTKIS_ROTATE: case VTKIS_DOLLY: case VTKIS_ZOOM: this->InvokeEvent(vtkViewImage2DCommand::ZoomEvent); break; case VTKIS_FORWARDFLY: case VTKIS_REVERSEFLY: this->InvokeEvent(vtkViewImage2DCommand::CameraMoveEvent, this); break; case VTKIS_PICK: HighlightCurrentActor(); break; default: this->Superclass::OnMouseMove(); break; } //Update image information (pixel position and value) this->InvokeEvent(vtkViewImage2DCommand::InteractionEvent, this); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnLeftButtonDown() { int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->m_LeftButtonDown = true; this->FindPokedRenderer(x, y); if ( this->Interactor->GetRepeatCount() ) { this->RequestedPosition[0] = x; this->RequestedPosition[1] = y; this->InvokeEvent (vtkViewImage2DCommand::RequestedPositionEvent); return; } switch ( this->m_Mode ) { case InteractionTypeZoom: this->InvokeEvent(vtkViewImage2DCommand::ZoomEvent); this->Superclass::OnRightButtonDown(); break; case InteractionTypePan: this->InvokeEvent(vtkViewImage2DCommand::PanEvent); this->Superclass::OnMiddleButtonDown(); break; case InteractionTypeContourPicking: this->InvokeEvent(vtkViewImage2DCommand::ContourPickingEvent); break; default: break; } // Call parent to handle all other states and perform additional work this->Superclass::OnLeftButtonDown(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnLeftButtonUp() { this->m_LeftButtonDown = false; switch ( this->m_Mode ) { case InteractionTypeZoom: this->Superclass::OnRightButtonDown(); break; case InteractionTypePan: this->Superclass::OnMiddleButtonDown(); break; default: break; } // Call parent to handle all other states and perform additional work this->Superclass::OnLeftButtonUp(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnMiddleButtonDown() { int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); switch ( this->m_Mode ) { case InteractionTypeWindowLevel: this->Superclass::OnLeftButtonDown(); break; case InteractionTypeZoom: this->InvokeEvent(vtkViewImage2DCommand::ZoomEvent); this->Superclass::OnRightButtonDown(); break; case InteractionTypeContourPicking: this->State = VTKIS_NONE; break; default: break; } // Call parent to handle all other states and perform additional work this->Superclass::OnMiddleButtonDown(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnMiddleButtonUp() { switch ( this->m_Mode ) { case InteractionTypeZoom: this->Superclass::OnRightButtonUp(); break; case InteractionTypeContourPicking: this->State = VTKIS_NONE; this->Superclass::StartPick(); return; default: break; } // Call parent to handle all other states and perform additional work this->Superclass::OnMiddleButtonUp(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnRightButtonDown() { //change state to zoom switch ( this->m_Mode ) { case InteractionTypePan: this->InvokeEvent(vtkViewImage2DCommand::PanEvent); this->Superclass::OnMiddleButtonDown(); break; case InteractionTypeWindowLevel: this->Superclass::OnLeftButtonDown(); break; case InteractionTypeContourPicking: this->State = VTKIS_NONE; break; default: break; } // Call parent to handle all other states and perform additional work this->Superclass::OnRightButtonDown(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnRightButtonUp() { switch ( this->m_Mode ) { case InteractionTypePan: this->Superclass::OnMiddleButtonUp(); break; case InteractionTypeWindowLevel: this->Superclass::OnLeftButtonUp(); break; case InteractionTypeContourPicking: this->State = VTKIS_NONE; this->Superclass::StartPick(); return; default: break; } // Call parent to handle all other states and perform additional work this->Superclass::OnRightButtonUp(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnMouseWheelForward() { int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); if ( !this->CurrentRenderer ) { return; } switch ( this->m_Mode ) { case InteractionTypeDefault: this->StartSliceMove(); this->SliceStep = static_cast< int >( this->MouseWheelMotionFactor ); this->SliceMove(); this->EndSliceMove(); break; case InteractionTypeContourPicking: this->StartSliceMove(); this->SliceStep = static_cast< int >( this->MouseWheelMotionFactor ); this->SliceMove(); this->EndSliceMove(); break; default: break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnMouseWheelBackward() { int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); if ( !this->CurrentRenderer ) { return; } switch ( this->m_Mode ) { case InteractionTypeDefault: this->StartSliceMove(); this->SliceStep = static_cast< int >( -this->MouseWheelMotionFactor ); this->SliceMove(); this->EndSliceMove(); break; case InteractionTypeContourPicking: this->StartSliceMove(); this->SliceStep = static_cast< int >( -this->MouseWheelMotionFactor ); this->SliceMove(); this->EndSliceMove(); break; default: break; } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnChar() { vtkRenderWindowInteractor *rwi = this->Interactor; if ( !strcmp (rwi->GetKeySym(), "Up") ) { this->SliceStep = 1; this->StartSliceMove(); this->SliceStep = static_cast< int >( -this->MouseWheelMotionFactor ); this->SliceMove(); this->EndSliceMove(); } else if ( !strcmp (rwi->GetKeySym(), "Down") ) { this->SliceStep = -1; this->StartSliceMove(); this->SliceMove(); this->EndSliceMove(); } else if ( ( rwi->GetKeyCode() == 'r' ) || ( rwi->GetKeyCode() == 'R' ) ) { this->InvokeEvent (vtkViewImage2DCommand::ResetWindowLevelEvent, this); } else if ( ( rwi->GetKeyCode() == 'o' ) || ( rwi->GetKeyCode() == 'O' ) ) { this->InvokeEvent (vtkViewImage2DCommand::ResetViewerEvent, this); } else if ( ( rwi->GetKeyCode() == 'w' ) || ( rwi->GetKeyCode() == 'W' ) ) { vtkActorCollection *ac; vtkActor *anActor, *aPart; vtkAssemblyPath *path; this->FindPokedRenderer(rwi->GetEventPosition()[0], rwi->GetEventPosition()[1]); if(this->CurrentRenderer!=0) { ac = this->CurrentRenderer->GetActors(); vtkCollectionSimpleIterator ait; for (ac->InitTraversal(ait); (anActor = ac->GetNextActor(ait)); ) { for (anActor->InitPathTraversal(); (path=anActor->GetNextPath()); ) { // make sure we don't modify the planes actors if ( path != NULL ) { std::vector< vtkProp3D * >::iterator it2 = m_PlanesActors.begin(); while(it2!=m_PlanesActors.end()) { if(path && dynamic_cast(*it2) == path->GetLastNode()->GetViewProp()) { path = NULL; } ++it2; } } // go on if target is not a plane if(path) { aPart=static_cast(path->GetLastNode()->GetViewProp()); aPart->GetProperty()->SetRepresentationToWireframe(); } } } } else { vtkWarningMacro(<<"no current renderer on the interactor style."); } rwi->Render(); return; } else if ( ( rwi->GetKeyCode() == 's' ) || ( rwi->GetKeyCode() == 'S' ) ) { vtkActorCollection *ac; vtkActor *anActor, *aPart; vtkAssemblyPath *path; this->FindPokedRenderer(rwi->GetEventPosition()[0], rwi->GetEventPosition()[1]); if(this->CurrentRenderer!=0) { ac = this->CurrentRenderer->GetActors(); vtkCollectionSimpleIterator ait; for (ac->InitTraversal(ait); (anActor = ac->GetNextActor(ait)); ) { for (anActor->InitPathTraversal(); (path=anActor->GetNextPath()); ) { // make sure we don't modify the planes actors if ( path != NULL ) { std::vector< vtkProp3D * >::iterator it2 = m_PlanesActors.begin(); while(it2!=m_PlanesActors.end()) { if(path && dynamic_cast(*it2) == path->GetLastNode()->GetViewProp()) { path = NULL; } ++it2; } } // go on if target is not a plane if(path) { aPart=static_cast(path->GetLastNode()->GetViewProp()); aPart->GetProperty()->SetRepresentationToSurface(); } } } } else { vtkWarningMacro(<<"no current renderer on the interactor style."); } rwi->Render(); return; } this->Superclass::OnChar(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnKeyUp() { vtkRenderWindowInteractor *rwi = this->Interactor; if ( !strcmp (rwi->GetKeySym(), "Up") ) { this->SliceStep = 1; this->StartSliceMove(); this->SliceMove(); this->EndSliceMove(); } else if ( !strcmp (rwi->GetKeySym(), "Down") ) { this->SliceStep = -1; this->StartSliceMove(); this->SliceMove(); this->EndSliceMove(); } else if ( !strcmp (rwi->GetKeySym(), "o") ) { this->InvokeEvent (vtkViewImage2DCommand::ResetViewerEvent, this); } else if ( !strcmp (rwi->GetKeySym(), "r") ) { this->InvokeEvent (vtkViewImage2DCommand::ResetWindowLevelEvent, this); } this->Superclass::OnKeyUp(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnKeyPress() { this->Superclass::OnKeyPress(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnKeyRelease() { this->Superclass::OnKeyRelease(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::StartSliceMove() { if ( ( this->State != VTKIS_NONE ) && ( this->State != VTKIS_PICK ) ) { return; } this->StartState(VTKIS_SLICE_MOVE); this->InvokeEvent(vtkViewImage2DCommand::StartSliceMoveEvent, this); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::EndSliceMove() { if ( this->State != VTKIS_SLICE_MOVE ) { return; } this->StopState(); this->InvokeEvent(vtkViewImage2DCommand::EndSliceMoveEvent, this); // Call one more time to update views... if(m_SynchronizeViews) { this->InvokeEvent(vtkViewImage2DCommand::SyncViewsEvent, this); } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::SliceMove() { if ( this->State != VTKIS_SLICE_MOVE ) { return; } if(m_SynchronizeViews) { this->InvokeEvent(vtkViewImage2DCommand::SyncViewsEvent, this); } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::OnKeyDown(void) { // Apparently there is a problem here. // The event vtkCommand::CharEvent and vtkCommand::KeyPressEvent seem // to mix between each other. // tackled by calling the charevent // (supposed to be called at any keyboard event) this->OnChar(); this->Superclass::OnKeyDown(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::DefaultMoveAction() { this->InvokeEvent (vtkViewImage2DCommand::DefaultMoveEvent, this); } //---------------------------------------------------------------------------- vtkProp * vtkInteractorStyleImage2D::GetCurrentProp() { return this->CurrentProp; } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::HighlightCurrentActor() { vtkRenderWindowInteractor *rwi = this->Interactor; if ( this->CurrentRenderer != 0 ) { vtkAssemblyPath *path = NULL; int * eventPos = rwi->GetEventPosition(); this->FindPokedRenderer(eventPos[0], eventPos[1]); rwi->StartPickCallback(); vtkAbstractPropPicker *picker = vtkAbstractPropPicker::SafeDownCast( rwi->GetPicker() ); if ( picker != NULL ) { picker->Pick(eventPos[0], eventPos[1], 0.0, this->CurrentRenderer); path = picker->GetPath(); } // make sure we don't modify the planes actors if ( path != NULL ) { std::vector< vtkProp3D * >::iterator it2 = m_PlanesActors.begin(); while(it2!=m_PlanesActors.end()) { if(path && dynamic_cast(*it2) == path->GetFirstNode()->GetViewProp()) { path = NULL; } ++it2; } } if ( path == NULL ) { this->HighlightProp(NULL); this->PropPicked = 0; } else { this->HighlightProp( path->GetFirstNode()->GetViewProp() ); this->PropPicked = 1; } rwi->EndPickCallback(); } } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::SetDefaultMode() { this->State = VTKIS_NONE; this->m_Mode = InteractionTypeDefault; } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::SetZoomMode() { this->State = VTKIS_NONE; this->m_Mode = InteractionTypeZoom; } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::SetPanMode() { this->State = VTKIS_NONE; this->m_Mode = InteractionTypePan; } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::SetPickMode() { this->State = VTKIS_NONE; this->m_Mode = InteractionTypeContourPicking; this->Superclass::StartPick(); } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D::SynchronizeViews( bool iSynchronize) { m_SynchronizeViews = iSynchronize; } //---------------------------------------------------------------------------- void vtkInteractorStyleImage2D:: SetPlanesActors( std::vector< vtkProp3D * > iBounds) { this->m_PlanesActors= iBounds; } //---------------------------------------------------------------------------- GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkImage3DCroppingBoxCallback.h0000644000175000017500000001147211667757442031335 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _vtk_Image3DCroppingBoxCallback_h_ #define _vtk_Image3DCroppingBoxCallback_h_ #include #include #include #include #include "MegaVTK2Configure.h" /** * \class vtkImage3DCroppingBoxCallback * \brief Callback to be called by the box widget to render only what is inside the box widget. * \ingroup MegaVTK */ class VTK_RENDERINGADDON2_EXPORT vtkImage3DCroppingBoxCallback: public vtkCommand { public: /* * \brief Convenient method to access the constructor */ static vtkImage3DCroppingBoxCallback * New() { return new vtkImage3DCroppingBoxCallback; } virtual void Execute(vtkObject *caller, unsigned long, void *); /* * \brief Set the volume mapper * \param[in] mapper Volume mapper */ void SetVolumeMapper(vtkVolumeMapper *mapper) { this->VolumeMapper = mapper; } /* * \brief Get the volume mapper * \return A pointer to the volume mapper */ vtkVolumeMapper * GetVolumeMapper(void) const { return this->VolumeMapper; } protected: vtkImage3DCroppingBoxCallback():VolumeMapper(0) {} ~vtkImage3DCroppingBoxCallback(){} private: /* * \brief Pointer to the volume mapper */ vtkVolumeMapper *VolumeMapper; }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkOrientationAnnotation.h0000644000175000017500000001200611667757442030654 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ // .NAME vtkOrientationAnnotation - text annotation in four corners // .SECTION Description // This is an annotation object that manages four text actors / mappers // to provide annotation in the four corners of a viewport // // .SECTION See Also // vtkActor2D vtkTextMapper #ifndef __vtkOrientationAnnotation_h #define __vtkOrientationAnnotation_h #include "vtkCornerAnnotation.h" #include "MegaVTK2Configure.h" /** * \class vtkOrientationAnnotation * \brief Text annotation in four corners * \ingroup MegaVTK */ class VTK_RENDERINGADDON2_EXPORT vtkOrientationAnnotation: public vtkCornerAnnotation { public: vtkTypeRevisionMacro(vtkOrientationAnnotation, vtkCornerAnnotation); /** * \brief Convenient method to access the constructor. * Instantiate object with a rectangle in normaled view coordinates * of (0.2,0.85, 0.8, 0.95). */ static vtkOrientationAnnotation * New(); protected: vtkOrientationAnnotation(); ~vtkOrientationAnnotation(); // Description: // Set text actor positions given a viewport size and justification virtual void SetTextActorsPosition(int vsize[2]); virtual void SetTextActorsJustification(); private: vtkOrientationAnnotation(const vtkOrientationAnnotation &); // Not // implemented. void operator=(const vtkOrientationAnnotation &); // Not // implemented. }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3D.h0000644000175000017500000002467011667757442026404 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _vtkViewImage3D_h_ #define _vtkViewImage3D_h_ #include "vtkViewImage.h" #include "MegaVTK2Configure.h" #include "vtkInteractorStyleImage3D.h" #include #include #include #include #include "vtkOrientedBoxWidget.h" #include #include #include #include "vtkImage3DCroppingBoxCallback.h" #include #include // For the picked/unpicked actors #include #include "vtkProp3D.h" class vtkViewImage3DCommand; class vtkSmartVolumeMapper; class vtkVolume; class vtkImageActor; class vtkAxes; class vtkDataSet3DCroppingPlaneCallback; class vtkTubeFilter; class vtkAnnotatedCubeActor; class vtkOrientationMarkerWidget; class vtkAxesActor; class vtkViewImage2D; class vtkScalarsToColors; class vtkColorTransferFunction; class ImageActorCallback; class vtkPlanes; /** * \class vtkViewImage3D * \ingroup MegaVTK * \brief Basic class to handle items such as images and polydatas * visualization in 3D */ class VTK_RENDERINGADDON2_EXPORT vtkViewImage3D:public vtkViewImage { public: /** * \brief Convenient method to access the constructor. */ static vtkViewImage3D * New(); vtkTypeRevisionMacro(vtkViewImage3D, vtkViewImage); // Description: // Render the resulting image. virtual void Render(void); /** Add a dataset to the view (has to be subclass of vtkPointSet). The dataset will be cut through the implicit slice plane (GetImplicitSlicePlane()). This results in a loss of dimensionality, i.e. tetrahedron will be displayed as triangles, triangles as lines, lines as points. A vtkProperty of the dataset can be specified. */ // virtual vtkQuadricLODActor* virtual vtkActor * AddDataSet(vtkDataSet *dataset, vtkProperty *property = NULL, const bool & intersection = true, const bool & iDataVisibility = false); /** Set/Get the current slice to display (depending on the orientation this can be in X, Y or Z). */ virtual void SetSlice(int s){ (void)s; } virtual void SetSliceOrientation(int orientation){ (void)orientation; } // Description: // Update the display extent manually so that the proper slice for the // given orientation is displayed. It will also try to set a // reasonable camera clipping range. // This method is called automatically when the Input is changed, but // most of the time the input of this class is likely to remain the same, // i.e. connected to the output of a filter, or an image reader. When the // input of this filter or reader itself is changed, an error message might // be displayed since the current display extent is probably outside // the new whole extent. Calling this method will ensure that the display // extent is reset properly. virtual void UpdateDisplayExtent(){} virtual void Add2DPhantom( const unsigned int & i, vtkImageActor *input, vtkPolyData *in_bounds = NULL); virtual void SetOrientationMatrix(vtkMatrix4x4 *matrix); /* * \brief Set volume rendering on */ void SetVolumeRenderingOn(const std::vector& iImages, const std::vector& iOpacities); /* * \brief Set volume rendering off */ void SetVolumeRenderingOff(); /* * \brief Set TriPlanar rendering on */ void SetTriPlanarRenderingOn(); /* * \brief Set TriPlanar rendering off */ void SetTriPlanarRenderingOff(); /** * \brief Set the cube visibility * \param[in] a true: visible, false: not visible * */ void SetCubeVisibility(const bool & a) { if ( this->Interactor ) { this->Marker->SetEnabled (a); } } /** * \brief Get the cube visibility * \return true: visible, false: not visible * */ bool GetCubeVisibility(void) { return ( this->Marker->GetEnabled() == 1 ); } vtkBooleanMacro (CubeVisibility, int); /** * \brief Set the shade * \param[in] a true: enable, false: disable * */ void SetShade(const bool & a) { this->VolumeProperty->SetShade (a); } /** * \brief Get the shade * \return a true: enable, false: disable * */ bool GetShade(void) { return ( this->VolumeProperty->GetShade() == 1 ); } vtkBooleanMacro (Shade, int); /** Get volume actor */ vtkGetObjectMacro (VolumeActor, vtkVolume); //vtkGetObjectMacro (PlaneWidget, vtkPlaneWidget); vtkGetObjectMacro (VolumeProperty, vtkVolumeProperty); //vtkGetObjectMacro (BoxWidget, vtkOrientedBoxWidget); virtual void SetWorldCoordinates(double pos[3]) { (void)pos; } /** * \brief Set the bounds actors visibility * \param iVisibility true: visible, false: not visible * */ void SetBoundsActorsVisibility(bool iVisibility); /** * \brief Get the interactor style for the vtkViewImage3D * \return pointer to the current vtkInteractorStyleImage3D * */ vtkInteractorStyleImage3D * GetInteractorStyle3D(); vtkGetObjectMacro (Command, vtkViewImage3DCommand); /** * \brief Compute the distance between 2 points * \param[in] n double pointer to the first point (double[3]) * \param[in] origin double pointer to the second point (double[3]) * */ void ComputeDistances(double *n, double *origin); /** * \brief Compute the disctance from the actors to the surface * \param[in] planes vtkPlanes pointer to the surface of interest * */ void ComputeDistancesToSquare(vtkPlanes *planes); std::vector< vtkProp3D * > GetPlanesActors(); protected: vtkViewImage3D(); ~vtkViewImage3D(); // Description: virtual void InstallPipeline(); virtual void UpdateOrientation(){} virtual void SetupWidgets(); void CleanVolumeRenderingVectors(); // texture mapper in 3D vtkSmartVolumeMapper *SmartVolumeMapper3D; // volume property vtkVolumeProperty *VolumeProperty; // volume actor vtkVolume *VolumeActor; std::vector m_VolumeActors; std::vector m_VolumeMappers; std::vector m_VolumeProperties; // image 3D cropping box callback vtkImage3DCroppingBoxCallback *Callback; std::vector< vtkImageActor * > Phantom; std::vector< ImageActorCallback * > PhantomCallback; std::vector< vtkActor * > BoundsActor; // box widget //vtkOrientedBoxWidget* BoxWidget; // vtkPlane widget // vtkPlaneWidget* PlaneWidget; // annotated cube actor vtkAnnotatedCubeActor * Cube; vtkOrientationMarkerWidget *Marker; /** Access to the command of the viewer. This instance is in charge of observing the interactorstyle (GetInteractorStyle()) and update things accordingly in the view (i.e. the slice number when moving slice). */ vtkViewImage3DCommand * Command; vtkInteractorStyleImage3D *InteractorStyle3D; }; #endif /* _vtkViewImage3D_h_ */ GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3DCommand.cxx0000644000175000017500000001051411667757442030246 0ustar mathieumathieu/*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkViewImage3DCommand.h" #include "vtkViewImage3D.h" #include "vtkPolyData.h" #include "vtkOrientedBoxWidget.h" #include "vtkImplicitPlaneWidget.h" #include "vtkPlanes.h" #include "vtkPlane.h" //---------------------------------------------------------------------------- vtkViewImage3DCommand::vtkViewImage3DCommand() { } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- vtkViewImage3DCommand:: ~vtkViewImage3DCommand() { } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- vtkViewImage3DCommand * vtkViewImage3DCommand::New() { return new vtkViewImage3DCommand; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage3DCommand::Execute(vtkObject *caller, unsigned long event, void *callData) { (void)callData; if ( m_PlaneWidget == static_cast< vtkImplicitPlaneWidget * >( caller ) ) { if ( event == vtkCommand::InteractionEvent ) { double *n = m_PlaneWidget->GetNormal(); double *origin = m_PlaneWidget->GetOrigin(); m_vtkViewImage3D->ComputeDistances(n, origin); return; } } else if ( m_BoxWidget == static_cast< vtkOrientedBoxWidget * >( caller ) ) { vtkPlanes *planes = vtkPlanes::New(); m_BoxWidget->GetPlanes(planes); m_vtkViewImage3D->ComputeDistancesToSquare(planes); return; } else { return; } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage3DCommand::SetVtkImageView3D(vtkViewImage3D *iViewImage3D) { if ( iViewImage3D ) { m_vtkViewImage3D = iViewImage3D; } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage3DCommand::SetPlaneWidget(vtkImplicitPlaneWidget *iPlaneWidget) { m_PlaneWidget = iPlaneWidget; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage3DCommand::SetBoxWidget(vtkOrientedBoxWidget *iBoxWidget) { m_BoxWidget = iBoxWidget; } //----------------------------------------------------------------------------GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkImage3DImagePlaneCallback.h0000644000175000017500000001215011667757442031077 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _vtk_Image3DImagePlaneCallback_h_ #define _vtk_Image3DImagePlaneCallback_h_ #include #include #include #include "MegaVTK2Configure.h" class vtkViewImage2D; /** * \class vtkImage3DImagePlaneCallback * \brief TO BE FILLED * \ingroup MegaVTK */ class VTK_RENDERINGADDON2_EXPORT vtkImage3DImagePlaneCallback:public vtkCommand { public: /* * \brief Convenient method to access the constructor */ static vtkImage3DImagePlaneCallback * New() { return new vtkImage3DImagePlaneCallback; } virtual void Execute(vtkObject *caller, unsigned long, void *); /* * \brief TO BE FILLED * \return A pointer to the resliced vtkImageData */ vtkImageData * GetOutput(void) const { return this->Reslice->GetOutput(); } // Reset the input of the reslice filter virtual void Reset(void) { this->Reslice->SetInput (NULL); } /* * \brief TO BE FILLED * \return A pointer to the reslice filter */ vtkImageReslice * GetReslice() { return this->Reslice; } /* * \brief Get the orientation matrix to extract the data * \return A pointer to a vtkMatrix4x4 */ vtkMatrix4x4 * GetMatrix() { return this->ResliceAxes; } protected: vtkImage3DImagePlaneCallback() { this->Reslice = vtkImageReslice::New(); this->ResliceAxes = vtkMatrix4x4::New(); } ~vtkImage3DImagePlaneCallback() { this->Reslice->Delete(); this->ResliceAxes->Delete(); } private: vtkImageReslice *Reslice; vtkMatrix4x4 * ResliceAxes; }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkImageBlendWithMask.cxx0000644000175000017500000002670611667757442030354 0ustar mathieumathieu/*========================================================================= Program: vtkINRIA3D Module: $Id: vtkImageBlendWithMask.cxx 477 2007-11-20 17:46:10Z filus $ Language: C++ Author: $Author: arnaudgelas $ Date: $Date: 2009-07-31 14:33:39 -0400 (Fri, 31 Jul 2009) $ Version: $Revision: 490 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkImageBlendWithMask.h" #include "vtkImageData.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkStreamingDemandDrivenPipeline.h" vtkCxxRevisionMacro (vtkImageBlendWithMask, "$Revision: 490 $"); vtkStandardNewMacro (vtkImageBlendWithMask); vtkImageBlendWithMask::vtkImageBlendWithMask() { LookupTable = 0; this->SetNumberOfInputPorts (2); } vtkImageBlendWithMask::~vtkImageBlendWithMask() { if ( LookupTable ) { LookupTable->Delete(); } } //---------------------------------------------------------------------------- void vtkImageBlendWithMask::SetImageInput(vtkImageData *in) { this->SetInput1(in); } //---------------------------------------------------------------------------- void vtkImageBlendWithMask::SetMaskInput(vtkImageData *in) { this->SetInput2(in); } //---------------------------------------------------------------------------- // The output extent is the intersection. int vtkImageBlendWithMask::RequestInformation( vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector) { // get the info objects vtkInformation *outInfo = outputVector->GetInformationObject(0); vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); vtkInformation *inInfo2 = inputVector[1]->GetInformationObject(0); int ext[6], ext2[6], idx; inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), ext); inInfo2->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), ext2); for ( idx = 0; idx < 3; ++idx ) { if ( ext2[idx * 2] > ext[idx * 2] ) { ext[idx * 2] = ext2[idx * 2]; } if ( ext2[idx * 2 + 1] < ext[idx * 2 + 1] ) { ext[idx * 2 + 1] = ext2[idx * 2 + 1]; } } outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), ext, 6); return 1; } void vtkImageBlendWithMask::PrintSelf(ostream & os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); if ( LookupTable ) { os << indent << "LookupTable: \n"; os << indent << *LookupTable << endl; } } //---------------------------------------------------------------------------- // This templated function executes the filter for any type of data. template< class T > void vtkImageBlendWithMaskExecute(vtkImageBlendWithMask *self, int ext[6], vtkImageData *in1Data, T *in1Ptr, vtkImageData *in2Data, T *in2Ptr, vtkImageData *outData, T *outPtr, int id) { int num0, num1, num2, numC, numM; int idx0, idx1, idx2, idxC; vtkIdType in1Inc0, in1Inc1, in1Inc2; vtkIdType in2Inc0, in2Inc1, in2Inc2; vtkIdType outInc0, outInc1, outInc2; double maskAlpha, oneMinusMaskAlpha; unsigned long count = 0; unsigned long target; numC = outData->GetNumberOfScalarComponents(); unsigned long pixSize = numC * sizeof( T ); maskAlpha = 0.5; oneMinusMaskAlpha = 0.5; numM = in2Data->GetNumberOfScalarComponents(); // Get information to march through data in1Data->GetContinuousIncrements(ext, in1Inc0, in1Inc1, in1Inc2); in2Data->GetContinuousIncrements(ext, in2Inc0, in2Inc1, in2Inc2); outData->GetContinuousIncrements(ext, outInc0, outInc1, outInc2); num0 = ext[1] - ext[0] + 1; num1 = ext[3] - ext[2] + 1; num2 = ext[5] - ext[4] + 1; target = (unsigned long)( num2 * num1 / 50.0 ); target++; // Loop through ouput pixels for ( idx2 = 0; idx2 < num2; ++idx2 ) { for ( idx1 = 0; !self->AbortExecute && idx1 < num1; ++idx1 ) { if ( !id ) { if ( !( count % target ) ) { self->UpdateProgress( static_cast< double >( count ) / ( 50.0 * static_cast< double >( target ) ) ); } count++; } for ( idx0 = 0; idx0 < num0; ++idx0 ) { if ( int(*in2Ptr) == 0 ) { memcpy (outPtr, in1Ptr, pixSize); in1Ptr += numC; outPtr += numC; } else { double color[4]; self->GetLookupTable()->GetTableValue ( (int)( *in2Ptr ), color ); maskAlpha = color[3]; oneMinusMaskAlpha = 1.0 - maskAlpha; for ( idxC = 0; idxC < numC; idxC++ ) { *outPtr = (T)( (int)( *in1Ptr ) * oneMinusMaskAlpha + (int)( color[idxC] * 255.0 ) * maskAlpha ); ++outPtr; ++in1Ptr; } } in2Ptr += numM; } in1Ptr += in1Inc1; in2Ptr += in2Inc1; outPtr += outInc1; } in1Ptr += in1Inc2; in2Ptr += in2Inc2; outPtr += outInc2; } } //---------------------------------------------------------------------------- // This method is passed a input and output Datas, and executes the filter // algorithm to fill the output from the inputs. // It just executes a switch statement to call the correct function for // the Datas data types. void vtkImageBlendWithMask::ThreadedRequestData( vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *vtkNotUsed(outputVector), vtkImageData ***inData, vtkImageData **outData, int outExt[6], int id) { void *inPtr1; void *inPtr2; void *outPtr; int * tExt; if ( !LookupTable ) { vtkErrorMacro("LookupTable not set"); return; } vtkImageData *mask = vtkImageData::SafeDownCast (inData[1][0]); if ( !mask ) { vtkErrorMacro("Mask is not set"); return; } inPtr1 = inData[0][0]->GetScalarPointerForExtent(outExt); inPtr2 = inData[1][0]->GetScalarPointerForExtent(outExt); outPtr = outData[0]->GetScalarPointerForExtent(outExt); tExt = inData[1][0]->GetExtent(); if ( tExt[0] > outExt[0] || tExt[1] < outExt[1] || tExt[2] > outExt[2] || tExt[3] < outExt[3] || tExt[4] > outExt[4] || tExt[5] < outExt[5] ) { vtkErrorMacro("Mask extent not large enough"); return; } /* if (inData[1][0]->GetNumberOfScalarComponents() != 1) { vtkErrorMacro("Mask can have one component"); }*/ if ( inData[0][0]->GetScalarType() != outData[0]->GetScalarType() || inData[0][0]->GetScalarType() != VTK_UNSIGNED_CHAR || ( inData[0][0]->GetNumberOfScalarComponents() != 3 && inData[0][0]->GetNumberOfScalarComponents() != 4 ) /*inData[1][0]->GetScalarType() != VTK_UNSIGNED_CHAR*/ ) { vtkErrorMacro( << "Execute: image ScalarType (" << inData[0][0]->GetScalarType() << ") must match out ScalarType (" << outData[0]->GetScalarType() << "), and mask scalar type (" << inData[1][0]->GetScalarType() << ") must be unsigned char." << "Number of input components: " << inData[0][0]->GetNumberOfScalarComponents() ); return; } switch ( inData[0][0]->GetScalarType() ) { vtkTemplateMacro( vtkImageBlendWithMaskExecute(this, outExt, inData[0][0], (VTK_TT *)( inPtr1 ), //inData[1][0],(unsigned char *)(inPtr2), inData[1][0], (VTK_TT *)( inPtr2 ), outData[0], (VTK_TT *)( outPtr ), id) ); default: vtkErrorMacro(<< "Execute: Unknown ScalarType"); return; } }GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkFillImageWithPolyData.h0000644000175000017500000001436311667757442030461 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkFillImageWithPolyData_h #define __vtkFillImageWithPolyData_h #include "vtkThreadedImageAlgorithm.h" #include #include "MegaVTK2Configure.h" /** * \class vtkFillImageWithPolyData * \brief TO BE FILLED * \ingroup MegaVTK */ class VTK_RENDERINGADDON2_EXPORT vtkFillImageWithPolyData: public vtkThreadedImageAlgorithm { public: /** * \brief Convenient method to access the constructor */ static vtkFillImageWithPolyData * New(); vtkTypeRevisionMacro (vtkFillImageWithPolyData, vtkThreadedImageAlgorithm); void PrintSelf(ostream & os, vtkIndent indent); /** * \brief Set the Polydata */ vtkSetObjectMacro (PolyData, vtkPolyData); /** * \brief Get the Polydata */ vtkGetObjectMacro (PolyData, vtkPolyData); /** * \brief Set the value of the pixel inside */ vtkSetMacro (InsidePixelValue, double); /** * \brief Get the value of the pixel inside */ vtkGetMacro (InsidePixelValue, double); /** * \brief Set the direction of extraction. * 0: X, 1: Y, 2: Z */ vtkSetMacro (ExtractionDirection, int); /** * \brief Set the direction of extraction. * 0: X, 1: Y, 2: Z */ vtkGetMacro (ExtractionDirection, int); /** * \brief Compute the angle between the 2 input points. * \param[in] dp1 Position of the first point. * \param[in] dp2 Position of the second point. * \return The angle between the 2 input points. */ double Angle2D(const double dp1[2], const double dp2[2]); protected: /** * \fn vtkFillImageWithPolyData::vtkFillImageWithPolyData() * \brief Constructor */ vtkFillImageWithPolyData(); /** * \brief Destructor */ ~vtkFillImageWithPolyData(); virtual int RequestInformation (vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector); virtual void ThreadedRequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *vtkNotUsed(outputVector), vtkImageData ***inData, vtkImageData **outData, int extent[6], int threadId); private: /** * \overload vtkFillImageWithPolyData::vtkFillImageWithPolyData(const vtkFillImageWithPolyData &) * \brief Constructor */ vtkFillImageWithPolyData (const vtkFillImageWithPolyData &); void operator=(const vtkFillImageWithPolyData &); vtkPolyData *PolyData; double InsidePixelValue; int ExtractionDirection; double BBox[6]; }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkPolylineDecimation.cxx0000644000175000017500000002021611667757442030473 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkPolylineDecimation.h" #include "vtkDoubleArray.h" #include "vtkLine.h" #include "vtkMath.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkLine.h" #include "vtkPolyData.h" #include "vtkPoints.h" #include "vtkCellArray.h" #include "vtkPointData.h" #include "vtkCellData.h" #include #include #include vtkCxxRevisionMacro(vtkPolylineDecimation, "$Revision: 1.1 $"); vtkStandardNewMacro(vtkPolylineDecimation); //--------------------------------------------------------------------- // Create object with specified reduction of 90%. vtkPolylineDecimation::vtkPolylineDecimation() { this->TargetReduction = 0.90; this->Closed = true; this->PriorityQueue = vtkPriorityQueue::New(); } //--------------------------------------------------------------------- vtkPolylineDecimation::~vtkPolylineDecimation() { this->PriorityQueue->Delete(); } double vtkPolylineDecimation::ComputeError(vtkPolyData *input, int prev, int id, int next) { vtkPoints *inputPoints = input->GetPoints(); double x1[3], x[3], x2[3]; inputPoints->GetPoint(prev, x1); inputPoints->GetPoint(id, x); inputPoints->GetPoint(next, x2); if ( vtkMath::Distance2BetweenPoints(x1, x2) == 0.0 ) { return 0.0; } else { return vtkLine::DistanceToLine(x, x1, x2); } } //--------------------------------------------------------------------- // Reduce the number of points in a set of polylines // int vtkPolylineDecimation::RequestData( vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector) { // get the info objects vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); vtkInformation *outInfo = outputVector->GetInformationObject(0); // get the input and ouptut vtkPolyData *input = vtkPolyData::SafeDownCast( inInfo->Get( vtkDataObject::DATA_OBJECT() ) ); vtkPolyData *output = vtkPolyData::SafeDownCast( outInfo->Get( vtkDataObject::DATA_OBJECT() ) ); vtkCellArray *inputLines = input->GetLines(); vtkPoints * inputPoints = input->GetPoints(); if ( !inputLines || !inputPoints ) { return 1; } vtkIdType numLines = inputLines->GetNumberOfCells(); vtkIdType numPts = inputPoints->GetNumberOfPoints(); if ( numLines < 1 || numPts < 1 ) { return 1; } // Allocate memory and prepare for data processing vtkPoints * newPts = vtkPoints::New(); vtkCellArray *newLines = vtkCellArray::New(); newLines->Allocate(numLines, 2); vtkPointData *inPD = input->GetPointData(); vtkPointData *outPD = output->GetPointData(); vtkCellData * inCD = input->GetCellData(); vtkCellData * outCD = output->GetCellData(); outPD->CopyAllocate(inPD); outCD->CopyAllocate(inCD); // Loop over all polylines, decimating each independently vtkIdType i, cellId = 0, newId; double error; for ( i = 0; i < numPts; i++ ) { this->VertexErrorMap[i] = 0.; } for ( i = 0; i < numPts; i++ ) { error = ComputeError( input, GetPrev(i), i, GetNext(i) ); this->VertexErrorMap[i] = error; this->PriorityQueue->Insert(error, i); } //for all points in polyline // Now process structures, // deleting points until the decimation target is met. vtkIdType currentNumPts = this->PriorityQueue->GetNumberOfItems(); while ( 1.0 - ( static_cast< double >( currentNumPts ) / static_cast< double >( numPts ) ) < this->TargetReduction && currentNumPts > 2 ) { i = this->PriorityQueue->Pop(); currentNumPts--; UpdateError(input, i); this->VertexErrorMap.erase(i); } // What's left over is now spit out as a new polyline newId = newLines->InsertNextCell(currentNumPts + 1); outCD->CopyData(inCD, cellId, newId); for ( std::map< int, double >::iterator it = this->VertexErrorMap.begin(); it != this->VertexErrorMap.end(); ++it ) { newId = newPts->InsertNextPoint( inputPoints->GetPoint(it->first) ); newLines->InsertCellPoint(newId); outPD->CopyData(inPD, it->first, newId); } if ( this->Closed ) { newId = newPts->InsertNextPoint( newPts->GetPoint(0) ); newLines->InsertCellPoint(0); outPD->CopyData(inPD, this->VertexErrorMap.begin()->first, newId); } // Clean up in preparation for the next line this->PriorityQueue->Reset(); // Create output and clean up output->SetPoints(newPts); output->SetLines(newLines); newLines->Delete(); newPts->Delete(); return 1; } //--------------------------------------------------------------------- int vtkPolylineDecimation::GetPrev(const int & iId) { std::map< int, double >::iterator it = this->VertexErrorMap.find(iId); if ( it == this->VertexErrorMap.begin() ) { if ( this->Closed ) { it = this->VertexErrorMap.end(); --it; return it->first; } else { return iId; } } else { --it; return it->first; } } //--------------------------------------------------------------------- int vtkPolylineDecimation::GetNext(const int & iId) { std::map< int, double >::iterator it = this->VertexErrorMap.find(iId); std::map< int, double >::iterator end_it = this->VertexErrorMap.end(); --end_it; if ( it == end_it ) { if ( this->Closed ) { return this->VertexErrorMap.begin()->first; } else { return iId; } } else { ++it; return it->first; } } //--------------------------------------------------------------------- void vtkPolylineDecimation::UpdateError(vtkPolyData *input, const int & iId) { int prev = GetPrev(iId); int prev_prev = GetPrev(prev); int next = GetNext(iId); int next_next = GetNext(next); double prev_error = ComputeError(input, prev_prev, prev, next); this->VertexErrorMap[prev] = prev_error; this->PriorityQueue->DeleteId(prev); this->PriorityQueue->Insert(prev_error, prev); double next_error = ComputeError(input, prev, next, next_next); this->VertexErrorMap[next] = next_error; this->PriorityQueue->DeleteId(next); this->PriorityQueue->Insert(next_error, next); } //--------------------------------------------------------------------- void vtkPolylineDecimation::PrintSelf(ostream & os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "Target Reduction: " << this->TargetReduction << "\n"; } GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/CMakeLists.txt0000644000175000017500000000367111667757442026200 0ustar mathieumathieu#Define sources SET( vtkRenderingAddOn_SRCS2 vtkFillImageWithPolyData.cxx vtkImage3DCroppingBoxCallback.cxx vtkImage3DImagePlaneCallback.cxx vtkImageBlendWithMask.cxx vtkInteractorStyleImage2D.cxx vtkInteractorStyleImage3D.cxx vtkLookupTableManager.cxx vtkOrientationAnnotation.cxx vtkOrientedBoxWidget.cxx vtkPolylineDecimation.cxx vtkViewImage.cxx vtkViewImage2D.cxx vtkViewImage2DCollection.cxx vtkViewImage2DCollectionCommand.cxx vtkViewImage2DCommand.cxx vtkViewImage3D.cxx vtkViewImage3DCommand.cxx ) INCLUDE_DIRECTORIES( BEFORE ${MEGAVTK2_BINARY_DIR} ${MEGAVTK2_BINARY_DIR}/vtkRenderingAddOn ) ADD_LIBRARY( vtkRenderingAddOn2 ${vtkRenderingAddOn_SRCS2} ) SET(vtkRenderingAddOn_LIBS2 vtkCommon vtkRendering vtkWidgets vtkVolumeRendering vtkHybrid vtkImaging ) TARGET_LINK_LIBRARIES( vtkRenderingAddOn2 ${vtkRenderingAddOn_LIBS2} ) SET_TARGET_PROPERTIES( vtkRenderingAddOn2 PROPERTIES VERSION ${GOFIGURE2_LIB_VERSION} SOVERSION ${GOFIGURE2_LIB_VERSION} ) # Runtime INSTALL( TARGETS vtkRenderingAddOn2 EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} NAMELINK_SKIP COMPONENT Libraries ) # Development INSTALL( TARGETS vtkRenderingAddOn2 EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries NAMELINK_ONLY ) FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE( GLOB __source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/*.txx" ) FILE( GLOB __lut_file_h "${CMAKE_CURRENT_SOURCE_DIR}/lut/*.h" ) INSTALL( FILES ${__source_file_h} ${__source_file_txx} ${__lut_file_h} DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2D.h0000644000175000017500000004715611667757442026407 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _vtkViewImage2D_h_ #define _vtkViewImage2D_h_ #include "vtkViewImage.h" #include "MegaVTK2Configure.h" #include #include #include "vtkTransform.h" #include "vtkImageActor.h" #include "vtkInteractorStyleImage2D.h" #include "vtkSmartPointer.h" class vtkPlane; class vtkViewImage2DCommand; class vtkTransform; class vtkInteractorStyle; class vtkInteractorStyleRubberBandZoom; class vtkOrientationAnnotation; class vtkPointHandleRepresentation2D; class vtkCursor2D; class vtkCellPicker; class vtkActor; // class vtkQuadricLODActor; /** * \class vtkViewImage2D * \ingroup MegaVTK * \brief Basic class to handle 2D/3D items such as images and polydatas * visualization in 2D */ class VTK_RENDERINGADDON2_EXPORT vtkViewImage2D:public vtkViewImage { public: /** * \brief Convenient method to access the constructor. */ static vtkViewImage2D * New(); vtkTypeRevisionMacro(vtkViewImage2D, vtkViewImage); /** \brief The orientation of the view is a abstract representation of the object we are looking at. It results from the acquisition plane. Setting the View Orientation by calling SetViewOrientation() will imply the view to set its inner "slice" orientation. (slice orientation == 2 means plane of acquisition.) \note The view orientations defined here are orthogonal to the normal basis in the scanner. A very interesting improvement would be to define "oblique" view orientations for cardiac imaging, something like: VIEW_ORIENTATION_SHORT_AXIS, VIEW_ORIENTATION_LONG_AXIS, and VIEW_ORIENTATION_FOUR_CHAMBER could define the different views that are usually used in cardiac imaging. From this user-input information, the idea would be to evaluate which slice orientation does correspond to the requested view. This can be done by evaluating the dot product between the axis of acquisition and a pre-defined oblique axis that "should" correspond to the requested orientation... **/ //BTX enum { VIEW_ORIENTATION_SAGITTAL = 0, VIEW_ORIENTATION_CORONAL = 1, VIEW_ORIENTATION_AXIAL = 2 }; //ETX /** Description: **/ //BTX enum { VIEW_CONVENTION_RADIOLOGICAL = 0, VIEW_CONVENTION_NEUROLOGICAL = 1 }; //ETX /** Description: These types describe the behaviour of the interactor style. */ //BTX enum { INTERACTOR_STYLE_NAVIGATION = 0, INTERACTOR_STYLE_RUBBER_ZOOM }; //ETX enum ORIENTATION { XY = 0, XZ = 1, YZ = 2 }; /** * \brief Get the polydata representing the Slice Plane * * The SlicePlane instance (GetSlicePlane()) is the polygonal * square corresponding to the slice plane, * it is updated each time the slice changes, * and is color-coded according to conventions */ vtkGetObjectMacro(SlicePlane, vtkPolyData); /** * \brief Get the orientation annotation. * This annotation describes the orientation of the slice plane, * according to the rule * Right(R)-Left(L) Anterior(A)-Posterior(P) Inferior(I)-Superior(S) */ vtkGetObjectMacro(OrientationAnnotation, vtkOrientationAnnotation); /** * \brief The world is not always what we think it is ... * Use this method to move the viewer slice such that the position * (in world coordinates) given by the arguments is contained by * the slice plane. If the given position is outside the bounds * of the image, then the slice will be as close as possible. */ virtual void SetWorldCoordinates(double pos[3]); /** * \brief Set/Get the current slice to display (depending on the orientation * this can be in X, Y or Z). */ virtual void SetSlice(int s); /** * \brief Get the view orientation * \return 0: radiological, 1: anatomic * * Instead of setting the slice orientation to an axis (YZ - XZ - XY), * you can force the view to be axial (foot-head), coronal (front-back), * or sagittal (left-right). It will just use the OrientationMatrix * (GetOrientationMatrix()) to check which slice orientation to pick. */ vtkGetMacro(ViewOrientation, int); virtual void SetViewOrientation(int orientation); virtual void SetOrientationMatrix(vtkMatrix4x4 *matrix); /** * \brief Get the view orientation * \return 0: sagittal, 1: coronal, 2: axial * * The ViewConvention instance explains where to place the camera around * the patient. Default behaviour is Radiological convention, meaning * we respectively look at the patient from his feet, his face and his left * ear. * For Neurological convention, we respectively look from the top of his head, * the the back of his head, and his left ear. */ vtkGetMacro(ViewConvention, int); virtual void SetViewConvention(int convention); /** * \brief Convert an indices coordinate point (image coordinates) into a world * coordinate point */ virtual double * GetWorldCoordinatesForSlice(int slice); /** * \brief Convert a world coordinate point into an image indices coordinate point */ virtual int GetSliceForWorldCoordinates(double pos[3]); /** * \brief Reset the 3D position to center */ virtual void ResetPosition(void); /** * \brief Reset position - zoom - window/level to default */ virtual void Reset(void); /** * \brief Reset the camera in a nice way for the 2D view */ virtual void ResetCamera(void); /** * \brief Set the zoom factor in the views */ vtkSetMacro(Zoom, double); /** * \brief Get the zoom factor in the views * \return double representing the zoom factor */ vtkGetMacro(Zoom, double); /** * \brief Useful method that transform a display position into a world corrdinate point */ virtual double *GetWorldCoordinatesFromDisplayPosition(int xy[2]); virtual double * GetWorldCoordinatesFromDisplayPosition(const int & x, const int & y); //BTX /** Access to the command of the viewer. This instance is in charge of observing the interactorstyle (GetInteractorStyle()) and update things accordingly in the view (i.e. the slice number when moving slice). */ vtkGetObjectMacro (Command, vtkViewImage2DCommand); //ETX /** * \brief Set whether or not the interpolation between pixels should be activated. * It is Off by default * \param[in] val 0: interpolation off, 1: interpolation on */ virtual void SetInterpolate(const int & val); /** * \brief Get whether or not the interpolation between pixels should be activated. * It is Off by default * \return val 0: interpolation off, 1: interpolation on */ virtual int GetInterpolate(); vtkBooleanMacro (Interpolate, int); /** * \brief Add a dataset to the view (has to be subclass of vtkPointSet). * The dataset will be cut through the implicit slice plane * (GetImplicitSlicePlane()). * This results in a loss of dimensionality, i.e. tetrahedron will be displayed * as triangles, triangles as lines, lines as points. * A vtkProperty of the dataset can be specified. * * \param[in] dataset Data to be displayed (shape, position, etc.) * \param[in] property Property of the data to be displayed (color, opacity, etc.) * \param[in] intersection Display projection or intersection of the dataset with the current slice * \param[in] iDataVisibility Visibility of the current actor */ virtual vtkActor * AddDataSet(vtkPolyData *polydata, vtkProperty *property = NULL, const bool & intersection = true, const bool & iDataVisibility = false); /** * \brief Set the camera motion vector */ vtkSetVector3Macro(CameraMotionVector, double); /** * \brief Get the camera motion vector * \return double[3] containing the motion vector */ vtkGetVector3Macro(CameraMotionVector, double); /** * \brief Set the annotation visibility */ virtual void SetShowAnnotations(const int & iShowAnnotations); /** * \brief Get the annotation visibility * \return 0: not visible, 1:visible */ vtkGetMacro(ShowAnnotations, int); /** * \brief Show/Hide the annotations. */ vtkBooleanMacro(ShowAnnotations, int); /** * \brief Set camera focal point and position * \param[in] focal double[3] containing the focal point of the camera * \param[in] pos double[3] containing the position of the camera */ void SetCameraFocalAndPosition(double focal[3], double pos[3]); /** * \brief Set camera focal point and position * \param[out] focal double[3] containing the focal point of the camera * \param[out] pos double[3] containing the position of the camera */ void GetCameraFocalAndPosition(double focal[3], double pos[3]); /** Access to the position of the center of the view. CAUTION: for the moment this feature is de-activated because updating it slows down the visualization process. */ /** * \brief Get the view center * \return double[3] containing the center of the view */ vtkGetVector3Macro (ViewCenter, double); /** * \brief Update the orientation */ virtual void Update(void) { this->UpdateOrientation(); } /** * \brief Set interaction style to Default mode: * Left button: Window level * Right button: Zoom * Middle button: Pan * Wheel: Throught volume */ void SetDefaultInteractionStyle(void) { vtkInteractorStyleImage2D *t = vtkInteractorStyleImage2D::SafeDownCast (this->InteractorStyle); if ( t ) { t->SetDefaultMode(); } } /** * \brief Set interaction style to Zoom mode: * All buttons: Zoom */ void SetZoomInteractionStyle(void) { vtkInteractorStyleImage2D *t = vtkInteractorStyleImage2D::SafeDownCast (this->InteractorStyle); if ( t ) { t->SetZoomMode(); } } /** * \brief Set interaction style to Pan mode: * All buttons: Pan */ void SetPanInteractionStyle(void) { vtkInteractorStyleImage2D *t = vtkInteractorStyleImage2D::SafeDownCast (this->InteractorStyle); if ( t ) { t->SetPanMode(); } } /** * \brief Set interaction style to Zoom mode: * The actor the mouse is highlighted in addition to the Default Mode. */ void SetPickInteractionStyle(void) { vtkInteractorStyleImage2D *t = vtkInteractorStyleImage2D::SafeDownCast (this->InteractorStyle); if ( t ) { t->SetPickMode(); } } /* * \brief Synchronize the views * \param[in] iSynchronize Enable/disable synchronization */ void SynchronizeViews( bool iSynchronize) { vtkInteractorStyleImage2D *t = vtkInteractorStyleImage2D::SafeDownCast (this->InteractorStyle); if ( t ) { t->SynchronizeViews(iSynchronize); } } /** Access to the actor corresponding to the cursor. It follows the mouse cursor everywhere it goes, and can be activated by pressing 'c' */ vtkGetObjectMacro (Cursor, vtkPointHandleRepresentation2D); vtkGetObjectMacro (CursorGenerator, vtkCursor2D); /** * \brief Add contours with specific properties to the view */ template< class TContourContainer, class TPropertyContainer > void AddContours(TContourContainer & iContours, TPropertyContainer & iProperty, const bool & iIntersection = true) { if ( iContours.size() != iProperty.size() ) { vtkWarningMacro(<< "iContours.size() != iProperty.size()"); return; } typedef typename TContourContainer::iterator ContourContainerIterator; typedef typename TPropertyContainer::iterator PropertyContainerIterator; ContourContainerIterator contour_it = iContours.begin(); ContourContainerIterator contour_end = iContours.end(); PropertyContainerIterator prop_it = iProperty.begin(); PropertyContainerIterator prop_end = iProperty.end(); while ( contour_it != contour_end ) { this->AddDataSet(*contour_it, *prop_it, iIntersection); ++contour_it; ++prop_it; } } /** * */ /* template void RemoveContours(TContourContainer& iContours) { typedef typename TContourContainer::iterator ContourContainerIterator; ContourContainerIterator contour_it = iContours.begin(); ContourContainerIterator contour_end = iContours.end(); while (contour_it != contour_end) { this->RemoveDataSet(*contour_it); ++contour_it; } } */ std::map ExtractActors( vtkPolyData *iDataSet, ORIENTATION iOrientation); protected: vtkViewImage2D(); ~vtkViewImage2D(); virtual void UpdateSlicePlane(void); virtual void UpdateCenter(void); virtual void UpdateOrientation(); virtual void PostUpdateOrientation(void); virtual void SetSlicePlaneFromOrientation(void); virtual int SetCameraFromOrientation(void); virtual void SetAnnotationsFromOrientation(void); /** * \brief After the orientation has changed, it is crucial to adapt * a couple of things according to new orientation. * Thus UpdateOrientation() is here overwritten and calls * PostUpdateOrientation(), where the SlicePlane, the Camera settings, * the CornerAnnotation, and the SliceImplicitPlane are modified. */ virtual void SetImplicitPlaneFromOrientation(void); /** * \brief Update the cursor position and the CornerAnnotation (top-left) according * to current mouse position. */ ///\todo This may has to be modified as with this configuration, the user has // no possibility of changing the upper-left corner annotation because it is // bypassed by this method at each mouse movement. virtual void UpdateCursor(void); /** * \brief This method is called each time the orientation changes (SetViewOrientation()) * and sets the appropriate color to the slice plane. * Red: R-L direction --> sagittal orientation * Green: A-P direction --> coronal orientation * Blue: I-S direction --> axial orientation */ virtual void InitializeSlicePlane(void); /** * \brief Overwrite of the Superclass InstallPipeline() method in order to set up the * home made InteractorStyle, and make it observe all events we need */ virtual void InstallPipeline(void); virtual int SetCameraToConvention(void); virtual void SetAnnotationToConvention(void); virtual void SetSlicePlaneToConvention(unsigned int axis); vtkMatrix4x4 *ConventionMatrix; vtkSmartPointer< vtkPlane > SliceImplicitPlane; /** * \brief This polydata instance is a square colored (see InitializeSlicePlane()) according to the * orientation of the view. It follows the image actor and is used by other view to display * intersections between views. */ vtkPolyData *SlicePlane; /** * \brief Get the orientation annotation. This annotation describes the orientation * of the slice plane, according to the rule * Right(R)-Left(L) Anterior(A)-Posterior(P) Inferior(I)-Superior(S) */ vtkOrientationAnnotation *OrientationAnnotation; vtkInteractorStyle *InteractorStyleSwitcher; /** * \brief InteractorStyle used in this view. It is a vtkInteractorStyleImage2D by default * but can be set to vtkInteractorStyleRubberBandZoom with SetInteractorStyleType(). * Rubber band zoom is in beta. Prefer using default behaviour. */ vtkInteractorStyleRubberBandZoom *InteractorStyleRubberZoom; /** * \brief Access to the command of the viewer. * This instance is in charge of observing the interactorstyle (GetInteractorStyle()) * and update things accordingly in the view (i.e. the slice number when moving slice). */ vtkViewImage2DCommand *Command; /** * \brief Access to the actor corresponding to the cursor. It follows the mouse cursor * everywhere it goes, and can be activated by pressing 'c' */ vtkPointHandleRepresentation2D *Cursor; /** * \brief Access to the actor corresponding to the cursor. It follows the mouse cursor * everywhere it goes, and can be activated by pressing 'c' */ vtkCursor2D *CursorGenerator; int ViewOrientation; int ViewConvention; int InteractorStyleType; double ViewCenter[3]; char SliceAndWindowInformation[64]; char ImageInformation[64]; double Zoom; double CameraMotionVector[3]; }; #endif /* _vtkViewImage2D_h_ */ GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkLookupTableManager.h0000644000175000017500000001624111667757442030047 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _vtk_LookupTableManager_h_ #define _vtk_LookupTableManager_h_ #include #include #include #include "MegaVTK2Configure.h" /** \class vtkLookupTableManager \ingroup MegaVTK \brief Define and manage all the lookup tables available in GoFigure2 */ class VTK_RENDERINGADDON2_EXPORT vtkLookupTableManager:public vtkObject { public: /* * \brief Name of all the lookup tables */ //BTX enum LookupTableIds { LUT_BW = 0, LUT_BWINV, LUT_SPECTTUM, LUT_HOTMETAL, LUT_GECOLORS, LUT_FLOW, LUT_LONI, LUT_LONI2, LUT_ASYMETRY, LUT_PVALUE, LUT_ROI, LUT_RANDOM }; //ETX /** * \brief Convenient method to access the constructor */ static vtkLookupTableManager * New(); vtkTypeRevisionMacro (vtkLookupTableManager, vtkObject); /** * \brief Get the BW lookup table * \return vtkLookupTable pointer to the BW lookup table */ static vtkLookupTable * GetBWLookupTable(void); /** * \brief Get the BWInverse lookup table * \return vtkLookupTable pointer to the BWInverse lookup table */ static vtkLookupTable * GetBWInverseLookupTable(void); /** * \brief Get the Spectrum lookup table * \return vtkLookupTable pointer to the Spectrum lookup table */ static vtkLookupTable * GetSpectrumLookupTable(void); /** * \brief Get the Hot Metal lookup table * \return vtkLookupTable pointer to the Hot Metal lookup table */ static vtkLookupTable * GetHotMetalLookupTable(void); /** * \brief Get the GE Color lookup table * \return vtkLookupTable pointer to the GE Color lookup table */ static vtkLookupTable * GetGEColorLookupTable(void); /** * \brief Get the Spectrum lookup table * \return vtkLookupTable pointer to the Spectrum lookup table */ static vtkLookupTable * GetFlowLookupTable(void); /** * \brief Get the LONI lookup table * \return vtkLookupTable pointer to the LONI lookup table */ static vtkLookupTable * GetLONILookupTable(void); /** * \brief Get the LONI2 lookup table * \return vtkLookupTable pointer to the LONI2 lookup table */ static vtkLookupTable * GetLONI2LookupTable(void); /** * \brief Get the Asymmetry lookup table * \return vtkLookupTable pointer to the Asymmetry lookup table */ static vtkLookupTable * GetAsymmetryLookupTable(void); /** * \brief Get the PValue lookup table * \return vtkLookupTable pointer to the PValue lookup table */ static vtkLookupTable * GetPValueLookupTable(void); /** * \brief Get the Random lookup table * \return vtkLookupTable pointer to the Random lookup table */ static vtkLookupTable* GetRandomLookupTable(); /** * \brief Get the available lookup table * \return Vector of strings where the strings are the name of the available * lookup tables */ static std::vector< std::string > GetAvailableLookupTables(void); /** * \brief Get the ROI lookup table * \return vtkLookupTable pointer to the ROI lookup table */ static vtkLookupTable * GetROILookupTable(void); /** * \brief Get the indexed lookup table * \param[in] iIndex of the lookup table * \return vtkLookupTable pointer to the indexed lookup table */ static vtkLookupTable * GetLookupTable(const int & iIndex); /** * \brief Get one HSV based lookup table * \param[in] iRGB input color to be used to generate the lookup table * \return vtkLookupTable pointer to one HSV based lookup table */ static vtkLookupTable* GetHSVBasedLookupTable( double iRGB[3] ); protected: vtkLookupTableManager(); ~vtkLookupTableManager(); private: }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkOrientedBoxWidget.h0000644000175000017500000001156411667757442027724 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _vtkOrientedBoxWidget_h_ #define _vtkOrientedBoxWidget_h_ #include "vtkBoxWidget.h" #include "MegaVTK2Configure.h" class vtkMatrix4x4; /** \class vtkOrientedBoxWidget \ingroup MegaVTK \brief orthogonal hexahedron 3D widget with pre-defined orientation Description This 3D widget defines a region of interest. By default it behaves exactly as the vtkBoxWidget class does. But if the user set the Orientation matrix with SetOrientationMatrix() then all the actors of the widgets (handles, hexahedron, etc) will be oriented according to the argument. \see vtk3DWidget vtkBoxWidget */ class VTK_RENDERINGADDON2_EXPORT vtkOrientedBoxWidget:public vtkBoxWidget { public: /** * \brief Convenient method to access the constructor. */ static vtkOrientedBoxWidget * New(); vtkTypeRevisionMacro(vtkOrientedBoxWidget, vtkBoxWidget); /** * \brief Get the orientation matrix of the vtkBoxWidget */ vtkGetObjectMacro (OrientationMatrix, vtkMatrix4x4); // Set the orientation matrix of the vtkBoxWidget virtual void SetOrientationMatrix(vtkMatrix4x4 *matrix); protected: vtkOrientedBoxWidget(); ~vtkOrientedBoxWidget(); virtual void OnMouseMove(); vtkMatrix4x4 *OrientationMatrix; vtkMatrix4x4 *InvertedOrientationMatrix; }; #endif /* _vtkOrientedBoxWidget_h_ */ GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2DCollectionCommand.h0000644000175000017500000000740411667757442031712 0ustar mathieumathieu/*========================================================================= Author: $Author:$ // Author of last commit Version: $Rev:$ // Revision of last commit Date: $Date:$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkViewImage2DCollectionCommand_h #define __vtkViewImage2DCollectionCommand_h #include "vtkCommand.h" #include "vtkObject.h" #include "MegaVTK2Configure.h" #include class vtkViewImage2DCollection; class vtkProp3D; /** * \class vtkViewImage2DCollectionCommand * \ingroup MegaVTK * \brief Manage events occuring in a 2D view and apply it to a collection */ class VTK_RENDERINGADDON2_EXPORT vtkViewImage2DCollectionCommand: public vtkCommand { public: /** * \brief Convenient method to access the constructor. */ static vtkViewImage2DCollectionCommand * New(); /** * \brief Get the current collection * \return vtkViewImage2DCollection pointer to the current collection */ vtkViewImage2DCollection * GetCollection(); /** * \brief Set the current collection * \param[in] p vtkViewImage2DCollection pointer to the current collection */ void SetCollection(vtkViewImage2DCollection *p); /** * \brief Synchronize the 2d views * \param[in] iSynchronize enable/disable synchronization */ void SynchronizeViews( bool iSynchronizeViews); // Description: // Satisfy the superclass API for callbacks. Recall that the caller is // the instance invoking the event; eid is the event id (see // vtkCommand.h); and calldata is information sent when the callback // was invoked (e.g., progress value in the vtkCommand::ProgressEvent). virtual void Execute( vtkObject * caller, unsigned long event, void *vtkNotUsed(callData) ); protected: vtkViewImage2DCollectionCommand(); ~vtkViewImage2DCollectionCommand(); private: vtkViewImage2DCollection *Collection; double InitialWindow; double InitialLevel; bool m_SynchronizeViews; }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage.h0000644000175000017500000004570711667757442026221 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _vtkViewImage_h_ #define _vtkViewImage_h_ #include "MegaVTK2Configure.h" #include "vtkImageViewer2.h" #include #include #include #include #include #include /** This macro can be useful as we frequently set an instance this way, meaning unregistering previously set instance, registering given instance, and call a modified event. However this might be not the best place to define it... */ //BTX #define vtkSetObjectMacro2Body(object, type, _arg) \ if ( this->object == _arg ) { return; } \ if ( this->object ) \ { \ this->object->UnRegister(this); \ } \ this->object = _arg; \ \ if ( this->object != NULL ) \ { \ this->object->Register(this); \ } \ \ this->Modified(); \ //ETX /** This macro can be useful as we frequently set an instance this way, meaning unregistering previously set instance, registering given instance, and call a modified event. However this might be not the best place to define it... */ //BTX #define vtkSetObjectMacro2(object, type) \ virtual void Set ## object (type * _arg) \ { \ vtkSetObjectMacro2Body (object, type, _arg); \ } \ //ETX class vtkMatrix4x4; class vtkScalarBarActor; class vtkLookupTable; class vtkTextProperty; class vtkCornerAnnotation; class vtkOrientationAnnotation; // class vtkQuadricLODActor; class vtkActor; class vtkDataSet; class vtkPolyData; class vtkProperty; class vtkMatrixToLinearTransform; class vtkRenderWindowInteractor; class vtkInteractorStyle; class vtkColorTransferFunction; class vtkProp3D; class vtkProp; class vtkTransform; class vtkScalarsToColors; /** * \defgroup MegaVTK MegaVTK */ /** \class vtkViewImage \ingroup MegaVTK \brief This class is a top-level convenience class for displaying a scalar - or RGB image in a 2D or 3D scene. It inherits from the vtkImageViewer2 class, which is initially designed for 2D scene visualization. However, vtkViewImage overrides some of its parents' methods (SetSlice()) in order to generalize its purpose to 2D AND 3D scene visualization. As a high-level class, it provides the user with convinient functionalities such as a colormap (SetLookupTable()), a scalar bar (ScalarBarActor), some corner annotations (CornerAnnotation), access to the background color (SetBackground()), the annotation text properties (SetTextProperty()), or a call for reseting to default values (Reset() or ResetCamera()). The principle add-on of this class is to tacke the common issue of placing different objects in a same consistent reference frame. In a world coordinates system, an volume image can be localized by its origin and its spacing, and an orientation vector defining how to rotate the volume to be consistent with reality. The vtkImageData class has among its attributes the origin and the spacing information. However, the orientation information is missing. The vtkViewImage class tackle this lack by providing the user the possibility to set an orientation matrix with SetOrientationMatrix(). This matrix will directly be applied to the actor describing the image in the 2D - or 3D - scene. The rotation 3x3 component of this matrix has to be orthogonal (no scaling). The offset component may contain the origin information. In this case the user will have to make sure that this information is absent from the vtkImageData instance given in SetInput(). For that you can call : view->GetInput()->SetOrigin(0,0,0). */ class VTK_RENDERINGADDON2_EXPORT vtkViewImage:public vtkImageViewer2 { public: vtkTypeRevisionMacro(vtkViewImage, vtkImageViewer2); virtual void SetInput(vtkImageData *input); // Description: // Render the resulting image. virtual void Render(void); /** Access to the RenderWindow interactor */ virtual vtkRenderWindowInteractor * GetInteractor(); virtual vtkRenderWindowInteractor * GetRenderWindowInteractor(); /** \brief Get the corner annotation. \todo make the corner annotation such that it follows the slice number, the image scalar value at cursor, the spacing, etc */ vtkGetObjectMacro(CornerAnnotation, vtkCornerAnnotation); /** \brief Get the scalar bar actor. This instance follows the color window/level of the viewer. */ vtkGetObjectMacro(ScalarBarActor, vtkScalarBarActor); /** \brief The OrientationMatrix instance (GetOrientationMatrix()) is a very important added feature of this viewer. It describes the rotation and translation to apply to the image bouding box (axis aligned) to the world coordinate system. Rotation part is usually given by the GetDirection() method on an itk::Image for instance. Translation usually correspond to the origin of the image given by GetOrigin() on an itk::Image. CAUTION: if you provide non-zero origin to the viewer vtkImageData input (SetInput()), then don't provide translation to the OrientationMatrix instance, otherwise the information is redundant. The best behaviour is to force the origin of the vtkImageData input to zero and provide this origin information in the OrientationMatrix. */ vtkGetObjectMacro(OrientationMatrix, vtkMatrix4x4); virtual void SetOrientationMatrix(vtkMatrix4x4 *matrix); /** The LookupTable instance (GetLookupTable()) can be used to set a user-defined color-table to the viewer. Default is a linear black to white table. */ vtkGetObjectMacro(LookupTable, vtkLookupTable); virtual void SetLookupTable(vtkLookupTable *lookuptable); /** * \brief Get a pointer to the current vtkTextProperty * * The TextProperty instance (GetTextProperty()) describes the font * and other settings of the CornerAnnotation instance * (GetCornerAnnotation()) */ vtkGetObjectMacro(TextProperty, vtkTextProperty); virtual void SetTextProperty(vtkTextProperty *textproperty); /** * \brief Set the world coordinates * \param[in] x x value * \param[in] y y value * \param[in] z z value * * The world is not always what we think it is ... * Use this method to move the viewer slice such that the position * (in world coordinates) given by the arguments is contained by * the slice plane. If the given position is outside the bounds * of the image, then the slice will be as close as possible. */ void SetWorldCoordinates(const double & x, const double & y, const double & z); virtual void SetWorldCoordinates(double pos[3]) = 0; /** \brief Set/Get the current slice to display (depending on the orientation this can be in X, Y or Z). This method has been overriden in order to generalize the use of this class to 2D AND 3D scene visualization. Thus in this top-level class SetSlice() does not do anything. \param[in] iSlice New position of the slice */ virtual void SetSlice(int iSlice) { int *range = this->GetSliceRange(); if (range) { if (iSlice < range[0]) { iSlice = range[0]; } else if (iSlice > range[1]) { iSlice = range[1]; } } if (this->Slice == iSlice) { return; } this->Slice = iSlice; this->Modified(); this->UpdateDisplayExtent(); } virtual void Update(void){} /** \brief Convert an indices coordinate point (image coordinates) into a world coordinate point */ virtual double *GetWorldCoordinatesFromImageCoordinates(int indices[3]); /** \brief Convert a world coordinate point into an image indices coordinate point */ virtual int *GetImageCoordinatesFromWorldCoordinates(double position[3]); /** \brief Get the pixel value at a given world coordinate point in space, return zero if out of bounds. */ virtual double GetValueAtPosition(double worldcoordinates[3], int component = 0); /** \brief Set the background color. Format is RGB, 0 <= R,G,B <=1 Example: SetBackground(0.9,0.9,0.9) for grey-white. */ virtual void SetBackground(double rgb[3]); virtual void SetBackground(const double & r, const double & g, const double & b); virtual double * GetBackground(void); /** \brief Reset the camera */ virtual void ResetCamera(void); /** * \brief Set the camera position * \param[in] arg pointer to a double[3] containing the new position of the camera */ void SetCameraPosition(double *arg); /** * \brief Get the camera position * \return pointer to a double[3] containing the position of the camera */ double * GetCameraPosition(void); /** * \brief Set the camera focal point * \param[in] arg pointer to a double[3] containing the new focal point of the * camera */ void SetCameraFocalPoint(double *arg); /** * \brief Get the camera focal point * \return pointer to a double[3] containing the new focal point of the * camera */ double * GetCameraFocalPoint(void); /** * \brief Set the camera view up * \param[in] arg pointer to a double[3] containing the new view up of the * camera */ void SetCameraViewUp(double *arg); /** * \brief Get the camera view up * \return pointer to a double[3] containing the new view up of the * camera */ double * GetCameraViewUp(void); /** * \brief Set the camera parallel scale * \param[in] arg double containing the new parallel scale */ void SetCameraParallelScale(double arg); /** * \brief Get the camera parallel scale * \return double containing the new parallel scale */ double GetCameraParallelScale(void); /** \brief Reset position - zoom - window/level to default */ virtual void Reset(void); /** * \brief Set the annotation status. * 0: annotations are not visible * 1: annotations are visible */ vtkBooleanMacro (ShowAnnotations, int); /** * \brief Get the annotation status. * 0: annotations are not visible * 1: annotations are visible */ vtkGetMacro (ShowAnnotations, int); /** * \brief Change the visibility of the annotations * \param[in] iShowAnnotations int * 0: annotations are not visible * 1: annotations are visible */ virtual void SetShowAnnotations(const int & iShowAnnotations); /** \brief Enable or Disable interaction on the view. */ virtual void Enable(void); /** \brief Enable or Disable interaction on the view. */ virtual void Disable(void); /** \brief Enable or Disable interaction on the view. */ virtual bool GetEnabled(void); /** * \brief Set the visibility of the scalar bar. * 0: scalar bar is not visible * 1: scalar bar is visible */ vtkBooleanMacro(ShowScalarBar, int); /** * \brief Get the visibility of the scalar bar. * 0: scalar bar is not visible * 1: scalar bar is visible */ vtkGetMacro(ShowScalarBar, int); /** \brief Show/Hide scalar bar. */ virtual void SetShowScalarBar(const bool &); /** \brief Set window and level for mapping pixels to colors. */ virtual void SetColorWindow(double s); virtual void SetColorLevel(double s); /** \brief Reset the window level */ virtual void ResetWindowLevel(void); void UpdateWindowLevel(); /** * \brief Get the current position in world coordinate. * \return double pointer to the current position in world coordinates * * This framework is only used in vtkViewImage2D to * update corner annotations and cursor position. */ double * GetCurrentPoint(void) { return this->CurrentPoint; } /** * \brief Get the current position in world coordinate. * \param[in,out] point double pointer to the current position in world coordinates (double[3]) * * This framework is only used in vtkViewImage2D to * update corner annotations and cursor position. */ void GetCurrentPoint(double point[3]) { point[0] = this->CurrentPoint[0]; point[1] = this->CurrentPoint[1]; point[2] = this->CurrentPoint[2]; } /** * \brief Get information about the color of the image. * true: multi-channels image (i.e. color) * false: single-channel image (i.e. black and white) */ vtkGetMacro(IsColor, bool); /** \brief Set the linewidth for added dataset in the scene (when using AddDataSet) */ vtkSetMacro( IntersectionLineWidth, float ); /** \brief Get the linewidth for added dataset in the scene (when using AddDataSet) */ vtkGetMacro( IntersectionLineWidth, float ); void SetWindow(double iWindow); double GetWindow(); void SetLevel(double iLevel); double GetLevel(); protected: vtkViewImage(); ~vtkViewImage(); /** The OrientationMatrix instance (GetOrientationMatrix()) is a very important added feature of this viewer. It describes the rotation and translation to apply to the image bouding box (axis aligned) to the world coordinate system. Rotation part is usually given by the GetDirection() method on an itk::Image for instance. Translation usually correspond to the origin of the image given by GetOrigin() on an itk::Image. CAUTION: if you provide non-zero origin to the viewer vtkImageData input (SetInput()), then don't provide translation to the OrientationMatrix instance, otherwise the information is redundant. The best behaviour is to force the origin of the vtkImageData input to zero and provide this origin information in the OrientationMatrix. */ vtkMatrix4x4 *OrientationMatrix; /** The corner annotation gather information related to the image. In vtkViewImage2D, it displays slice number, spacing, window-level, position, etc Access and change the values with GetCornerAnnotation()->SetText(n, const char*). n begins down-right and increases anti-clockwise. */ vtkCornerAnnotation *CornerAnnotation; /** The TextProperty instance (GetTextProperty()) describes the font and other settings of the CornerAnnotation instance (GetCornerAnnotation()) */ vtkTextProperty *TextProperty; /** The LookupTable instance (GetLookupTable()) can be used to set a user-defined color-table to the viewer. Default is a linear black to white table. */ vtkLookupTable *LookupTable; /** Get the scalar bar actor. This instance follows the color window/level of the viewer. */ vtkScalarBarActor *ScalarBarActor; /** This vtkTransform instance carries the OrientationMatrix (see GetOrientationMatrix()) and is used to quickly transform the slice plane in vtkViewImage2D. */ vtkMatrixToLinearTransform *OrientationTransform; std::string DirectionAnnotationMatrix[3][2]; float IntersectionLineWidth; /** local instances. */ int ShowAnnotations; int ShowScalarBar; /** Get the current position in world coordinate. This framework is only used in vtkViewImage2D to update corner annotations and cursor position. */ double CurrentPoint[3]; bool IsColor; double Window; double Level; }; #endif /* _vtkViewImage_h_ */ GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkInteractorStyleImage3D.h0000644000175000017500000001456611667757442030630 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _vtk_InteractorStyleImage3D_h_ #define _vtk_InteractorStyleImage3D_h_ #include #include "MegaVTK2Configure.h" #include "vtkActor.h" #include "vtkProp.h" #include class vtkProp; /** * \class vtkInteractorStyleImage3D * \ingroup MegaVTK * \brief Define the interactor behavior withing a vtkImage3D. * 4 modes (Default, Zoom, Pan and Pick) */ //MOTION FLAG #define VTKIS_PICK3D 1050 class VTK_RENDERINGADDON2_EXPORT vtkInteractorStyleImage3D: public vtkInteractorStyleTrackballCamera { public: /** * \brief Convenient method to access the constructor */ static vtkInteractorStyleImage3D * New(); vtkTypeRevisionMacro (vtkInteractorStyleImage3D, vtkInteractorStyleTrackballCamera); //BTX enum InteractionTypeIds { InteractionTypeWindowLevel = 0, InteractionTypeZoom, InteractionTypePan, InteractionTypeMeshPicking, InteractionTypeDefault }; virtual void OnMouseMove(); virtual void OnLeftButtonDown(); virtual void OnLeftButtonUp(); virtual void OnRightButtonDown(); virtual void OnRightButtonUp(); virtual void OnMiddleButtonDown(); virtual void OnMiddleButtonUp(); virtual void OnChar(); /** * \brief Store the actor which is pointed by the cursor into "m_CurrentProp" */ void SetCurrentProp(vtkProp *iCurrent); /** * \brief Return the actor which is pointed by the cursor */ vtkProp * GetCurrentProp(); /** * \brief Store the actor which is pointed by the cursor into "m_CurrentProp" */ void SetCurrentState(bool iSate); /** * \brief Store the actor which is pointed by the cursor into "m_CurrentProp" */ bool GetCurrentState(); /** * \brief Start Pick Mode by updating the "State" and sending the "StartPickEvent" */ void StartPick(); /** * \brief Draw a bounding box around the "m_CurrentProp" (i.e. actor pointed * by the mouse) */ void HighlightCurrentActor(); /** * \brief Start the Default Mode */ void EnableDefaultMode(); /** * \brief Start the Zoom Mode */ void EnableZoomMode(); /** * \brief Start the Pan Mode */ void EnablePanMode(); /** * \brief Start the Pick Mode */ void EnablePickMode(); void SetPlanesActors( std::vector< vtkProp3D * > iBounds); protected: vtkInteractorStyleImage3D(); ~vtkInteractorStyleImage3D(); private: vtkInteractorStyleImage3D(const vtkInteractorStyleImage3D &); // Not // implemented. void operator=(const vtkInteractorStyleImage3D &); // Not // implemented. vtkProp * m_CurrentProp; unsigned int m_Mode; bool m_State; std::vector< vtkProp3D * > m_PlanesActors; }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkImage3DCroppingBoxCallback.cxx0000644000175000017500000001223211667757442031703 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkImage3DCroppingBoxCallback.h" #include "vtkSmartPointer.h" #include "vtkBoxWidget.h" #include "vtkPolyData.h" void vtkImage3DCroppingBoxCallback::Execute(vtkObject *caller, unsigned long, void *) { if ( !this->VolumeMapper ) { return; } // get the box widget vtkBoxWidget *widget = reinterpret_cast< vtkBoxWidget * >( caller ); if ( !widget ) { return; } // Get the poly data defined by the vtkBoxWidget vtkSmartPointer< vtkPolyData > myBox = vtkSmartPointer< vtkPolyData >::New(); widget->GetPolyData(myBox); double bounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; this->VolumeMapper->GetBounds(bounds); // myBox contains 15 points and points 8 to 13 // define the bounding box double xmin, xmax, ymin, ymax, zmin, zmax; double *pt = myBox->GetPoint(8); xmin = pt[0]; pt = myBox->GetPoint(9); xmax = pt[0]; pt = myBox->GetPoint(10); ymin = pt[1]; pt = myBox->GetPoint(11); ymax = pt[1]; pt = myBox->GetPoint(12); zmin = pt[2]; pt = myBox->GetPoint(13); zmax = pt[2]; if ( xmin < bounds[0] ) { xmin = bounds[0]; } if ( ymin < bounds[2] ) { ymin = bounds[2]; } if ( zmin < bounds[4] ) { zmin = bounds[4]; } if ( xmax > bounds[1] ) { xmax = bounds[1]; } if ( ymax > bounds[3] ) { ymax = bounds[3]; } if ( zmax > bounds[5] ) { zmax = bounds[5]; } this->VolumeMapper->SetCroppingRegionFlagsToSubVolume(); this->VolumeMapper->SetCroppingRegionPlanes(xmin, xmax, ymin, ymax, zmin, zmax); }GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/lut/0000755000175000017500000000000011667757442024235 5ustar mathieumathieuGoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/lut/GEColor.h0000644000175000017500000001645411667757442025712 0ustar mathieumathieu/*========================================================================= Program: vtkINRIA3D Module: $Id: GEColor.h 477 2007-11-20 17:46:10Z filus $ Language: C++ Author: $Author: filus $ Date: $Date: 2007-11-20 12:46:10 -0500 (Tue, 20 Nov 2007) $ Version: $Revision: 477 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _lut_GEColor_h_ #define _lut_GEColor_h_ static const int GEColor[3 * 256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 128, 126, 124, 122, 120, 118, 116, 114, 112, 110, 108, 106, 104, 102, 100, 98, 96, 94, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 72, 70, 68, 66, 64, 63, 61, 59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33, 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 252, 248, 244, 240, 236, 232, 228, 224, 220, 216, 212, 208, 204, 200, 196, 192, 188, 184, 180, 176, 172, 168, 164, 160, 156, 152, 148, 144, 140, 136, 132, 128, 124, 120, 116, 112, 108, 104, 100, 96, 92, 88, 84, 80, 76, 72, 68, 64, 60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, 250, 255 }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/lut/HotMetal.h0000644000175000017500000001574611667757442026140 0ustar mathieumathieu/*========================================================================= Program: vtkINRIA3D Module: $Id: HotMetal.h 477 2007-11-20 17:46:10Z filus $ Language: C++ Author: $Author: filus $ Date: $Date: 2007-11-20 12:46:10 -0500 (Tue, 20 Nov 2007) $ Version: $Revision: 477 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _lut_HotMetal_h_ #define _lut_HotMetal_h_ static const int HotMetal[256 * 3] = { 0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 14, 15, 16, 18, 19, 21, 22, 23, 25, 26, 28, 29, 30, 32, 33, 35, 36, 37, 39, 40, 42, 43, 44, 46, 47, 49, 50, 51, 53, 54, 56, 57, 58, 60, 61, 63, 64, 65, 67, 68, 70, 71, 72, 74, 75, 77, 78, 79, 81, 82, 84, 85, 86, 88, 89, 91, 92, 93, 95, 96, 98, 99, 100, 102, 103, 105, 106, 107, 109, 110, 112, 113, 114, 116, 117, 119, 120, 121, 123, 124, 126, 127, 128, 130, 131, 133, 134, 135, 137, 138, 140, 141, 142, 144, 145, 147, 148, 149, 151, 152, 154, 155, 156, 158, 159, 161, 162, 163, 165, 166, 168, 169, 170, 172, 173, 175, 176, 177, 179, 180, 182, 183, 184, 186, 187, 189, 190, 191, 193, 194, 196, 197, 198, 200, 201, 203, 204, 205, 207, 208, 210, 211, 212, 214, 215, 217, 218, 219, 221, 222, 224, 225, 226, 228, 229, 231, 232, 233, 235, 236, 238, 239, 240, 242, 243, 245, 246, 247, 249, 250, 252, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 8, 11, 14, 16, 19, 22, 25, 28, 30, 33, 36, 39, 42, 44, 47, 50, 53, 56, 58, 61, 64, 67, 70, 72, 75, 78, 81, 84, 86, 89, 92, 95, 98, 100, 103, 106, 109, 112, 114, 117, 120, 123, 126, 128, 131, 134, 137, 140, 142, 145, 148, 151, 154, 156, 159, 162, 165, 168, 170, 173, 176, 179, 182, 184, 187, 190, 193, 196, 198, 201, 204, 207, 210, 212, 215, 218, 221, 224, 226, 229, 232, 235, 238, 240, 243, 246, 249, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, 71, 75, 79, 83, 87, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 183, 187, 191, 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251 }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/lut/Asymmetry.h0000644000175000017500000003540111667757442026403 0ustar mathieumathieu/*========================================================================= Program: vtkINRIA3D Module: $Id: Asymmetry.h 477 2007-11-20 17:46:10Z filus $ Language: C++ Author: $Author: filus $ Date: $Date: 2007-11-20 12:46:10 -0500 (Tue, 20 Nov 2007) $ Version: $Revision: 477 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _lut_asymmetry_h_ #define _lut_asymmetry_h_ static const double AsymmetryLUT[256][3] = { { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.019608, 1.000000 }, { 0.000000, 0.039216, 1.000000 }, { 0.000000, 0.058824, 1.000000 }, { 0.000000, 0.078431, 1.000000 }, { 0.000000, 0.098039, 1.000000 }, { 0.000000, 0.117647, 1.000000 }, { 0.000000, 0.137255, 1.000000 }, { 0.000000, 0.156863, 1.000000 }, { 0.000000, 0.176471, 1.000000 }, { 0.000000, 0.196078, 1.000000 }, { 0.000000, 0.215686, 1.000000 }, { 0.000000, 0.235294, 1.000000 }, { 0.000000, 0.254902, 1.000000 }, { 0.000000, 0.274510, 1.000000 }, { 0.000000, 0.294118, 1.000000 }, { 0.000000, 0.313725, 1.000000 }, { 0.000000, 0.333333, 1.000000 }, { 0.000000, 0.352941, 1.000000 }, { 0.000000, 0.372549, 1.000000 }, { 0.000000, 0.392157, 1.000000 }, { 0.000000, 0.411765, 1.000000 }, { 0.000000, 0.431373, 1.000000 }, { 0.000000, 0.450980, 1.000000 }, { 0.000000, 0.470588, 1.000000 }, { 0.000000, 0.490196, 1.000000 }, { 0.000000, 0.509804, 1.000000 }, { 0.000000, 0.529412, 1.000000 }, { 0.000000, 0.549020, 1.000000 }, { 0.000000, 0.568627, 1.000000 }, { 0.000000, 0.588235, 1.000000 }, { 0.000000, 0.607843, 1.000000 }, { 0.000000, 0.627451, 1.000000 }, { 0.000000, 0.647059, 1.000000 }, { 0.000000, 0.666667, 1.000000 }, { 0.000000, 0.686275, 1.000000 }, { 0.000000, 0.705882, 1.000000 }, { 0.000000, 0.725490, 1.000000 }, { 0.000000, 0.745098, 1.000000 }, { 0.000000, 0.764706, 1.000000 }, { 0.000000, 0.784314, 1.000000 }, { 0.000000, 0.803922, 1.000000 }, { 0.000000, 0.823529, 1.000000 }, { 0.000000, 0.843137, 1.000000 }, { 0.000000, 0.862745, 1.000000 }, { 0.000000, 0.882353, 1.000000 }, { 0.000000, 0.901961, 1.000000 }, { 0.000000, 0.921569, 1.000000 }, { 0.000000, 0.941176, 1.000000 }, { 0.000000, 0.960784, 1.000000 }, { 0.000000, 0.980392, 1.000000 }, { 0.000000, 1.000000, 1.000000 }, { 0.000000, 1.000000, 0.980392 }, { 0.000000, 1.000000, 0.960784 }, { 0.000000, 1.000000, 0.941176 }, { 0.000000, 1.000000, 0.921569 }, { 0.000000, 1.000000, 0.901961 }, { 0.000000, 1.000000, 0.882353 }, { 0.000000, 1.000000, 0.862745 }, { 0.000000, 1.000000, 0.843137 }, { 0.000000, 1.000000, 0.823529 }, { 0.000000, 1.000000, 0.803922 }, { 0.000000, 1.000000, 0.784314 }, { 0.000000, 1.000000, 0.764706 }, { 0.000000, 1.000000, 0.745098 }, { 0.000000, 1.000000, 0.725490 }, { 0.000000, 1.000000, 0.705882 }, { 0.000000, 1.000000, 0.686275 }, { 0.000000, 1.000000, 0.666667 }, { 0.000000, 1.000000, 0.647059 }, { 0.000000, 1.000000, 0.627451 }, { 0.000000, 1.000000, 0.607843 }, { 0.000000, 1.000000, 0.588235 }, { 0.000000, 1.000000, 0.568627 }, { 0.000000, 1.000000, 0.549020 }, { 0.000000, 1.000000, 0.529412 }, { 0.000000, 1.000000, 0.509804 }, { 0.000000, 1.000000, 0.490196 }, { 0.000000, 1.000000, 0.470588 }, { 0.000000, 1.000000, 0.450980 }, { 0.000000, 1.000000, 0.431373 }, { 0.000000, 1.000000, 0.411765 }, { 0.000000, 1.000000, 0.392157 }, { 0.000000, 1.000000, 0.372549 }, { 0.000000, 1.000000, 0.352941 }, { 0.000000, 1.000000, 0.333333 }, { 0.000000, 1.000000, 0.313725 }, { 0.000000, 1.000000, 0.294118 }, { 0.000000, 1.000000, 0.274510 }, { 0.000000, 1.000000, 0.254902 }, { 0.000000, 1.000000, 0.235294 }, { 0.000000, 1.000000, 0.215686 }, { 0.000000, 1.000000, 0.196078 }, { 0.000000, 1.000000, 0.176471 }, { 0.000000, 1.000000, 0.156863 }, { 0.000000, 1.000000, 0.137255 }, { 0.000000, 1.000000, 0.117647 }, { 0.000000, 1.000000, 0.098039 }, { 0.000000, 1.000000, 0.078431 }, { 0.000000, 1.000000, 0.058824 }, { 0.000000, 1.000000, 0.039216 }, { 0.000000, 1.000000, 0.019608 }, { 0.000000, 1.000000, 0.000000 }, { 0.019608, 1.000000, 0.000000 }, { 0.039216, 1.000000, 0.000000 }, { 0.058824, 1.000000, 0.000000 }, { 0.078431, 1.000000, 0.000000 }, { 0.098039, 1.000000, 0.000000 }, { 0.117647, 1.000000, 0.000000 }, { 0.137255, 1.000000, 0.000000 }, { 0.156863, 1.000000, 0.000000 }, { 0.176471, 1.000000, 0.000000 }, { 0.196078, 1.000000, 0.000000 }, { 0.215686, 1.000000, 0.000000 }, { 0.235294, 1.000000, 0.000000 }, { 0.254902, 1.000000, 0.000000 }, { 0.274510, 1.000000, 0.000000 }, { 0.294118, 1.000000, 0.000000 }, { 0.313725, 1.000000, 0.000000 }, { 0.333333, 1.000000, 0.000000 }, { 0.352941, 1.000000, 0.000000 }, { 0.372549, 1.000000, 0.000000 }, { 0.392157, 1.000000, 0.000000 }, { 0.411765, 1.000000, 0.000000 }, { 0.431373, 1.000000, 0.000000 }, { 0.450980, 1.000000, 0.000000 }, { 0.470588, 1.000000, 0.000000 }, { 0.490196, 1.000000, 0.000000 }, { 0.509804, 1.000000, 0.000000 }, { 0.529412, 1.000000, 0.000000 }, { 0.549020, 1.000000, 0.000000 }, { 0.568627, 1.000000, 0.000000 }, { 0.588235, 1.000000, 0.000000 }, { 0.607843, 1.000000, 0.000000 }, { 0.627451, 1.000000, 0.000000 }, { 0.647059, 1.000000, 0.000000 }, { 0.666667, 1.000000, 0.000000 }, { 0.686275, 1.000000, 0.000000 }, { 0.705882, 1.000000, 0.000000 }, { 0.725490, 1.000000, 0.000000 }, { 0.745098, 1.000000, 0.000000 }, { 0.764706, 1.000000, 0.000000 }, { 0.784314, 1.000000, 0.000000 }, { 0.803922, 1.000000, 0.000000 }, { 0.823529, 1.000000, 0.000000 }, { 0.843137, 1.000000, 0.000000 }, { 0.862745, 1.000000, 0.000000 }, { 0.882353, 1.000000, 0.000000 }, { 0.901961, 1.000000, 0.000000 }, { 0.921569, 1.000000, 0.000000 }, { 0.941176, 1.000000, 0.000000 }, { 0.960784, 1.000000, 0.000000 }, { 0.980392, 1.000000, 0.000000 }, { 1.000000, 1.000000, 0.000000 }, { 1.000000, 0.980392, 0.000000 }, { 1.000000, 0.960784, 0.000000 }, { 1.000000, 0.941176, 0.000000 }, { 1.000000, 0.921569, 0.000000 }, { 1.000000, 0.901961, 0.000000 }, { 1.000000, 0.882353, 0.000000 }, { 1.000000, 0.862745, 0.000000 }, { 1.000000, 0.843137, 0.000000 }, { 1.000000, 0.823529, 0.000000 }, { 1.000000, 0.803922, 0.000000 }, { 1.000000, 0.784314, 0.000000 }, { 1.000000, 0.764706, 0.000000 }, { 1.000000, 0.745098, 0.000000 }, { 1.000000, 0.725490, 0.000000 }, { 1.000000, 0.705882, 0.000000 }, { 1.000000, 0.686275, 0.000000 }, { 1.000000, 0.666667, 0.000000 }, { 1.000000, 0.647059, 0.000000 }, { 1.000000, 0.627451, 0.000000 }, { 1.000000, 0.607843, 0.000000 }, { 1.000000, 0.588235, 0.000000 }, { 1.000000, 0.568627, 0.000000 }, { 1.000000, 0.549020, 0.000000 }, { 1.000000, 0.529412, 0.000000 }, { 1.000000, 0.509804, 0.000000 }, { 1.000000, 0.490196, 0.000000 }, { 1.000000, 0.470588, 0.000000 }, { 1.000000, 0.450980, 0.000000 }, { 1.000000, 0.431373, 0.000000 }, { 1.000000, 0.411765, 0.000000 }, { 1.000000, 0.392157, 0.000000 }, { 1.000000, 0.372549, 0.000000 }, { 1.000000, 0.352941, 0.000000 }, { 1.000000, 0.333333, 0.000000 }, { 1.000000, 0.313725, 0.000000 }, { 1.000000, 0.294118, 0.000000 }, { 1.000000, 0.274510, 0.000000 }, { 1.000000, 0.254902, 0.000000 }, { 1.000000, 0.235294, 0.000000 }, { 1.000000, 0.215686, 0.000000 }, { 1.000000, 0.196078, 0.000000 }, { 1.000000, 0.176471, 0.000000 }, { 1.000000, 0.156863, 0.000000 }, { 1.000000, 0.137255, 0.000000 }, { 1.000000, 0.117647, 0.000000 }, { 1.000000, 0.098039, 0.000000 }, { 1.000000, 0.078431, 0.000000 }, { 1.000000, 0.058824, 0.000000 }, { 1.000000, 0.039216, 0.000000 }, { 1.000000, 0.019608, 0.000000 }, { 1.000000, 0.000000, 0.000000 }, { 1.000000, 0.000000, 0.019608 }, { 1.000000, 0.000000, 0.039216 }, { 1.000000, 0.000000, 0.058824 }, { 1.000000, 0.000000, 0.078431 }, { 1.000000, 0.000000, 0.098039 }, { 1.000000, 0.000000, 0.117647 }, { 1.000000, 0.000000, 0.137255 }, { 1.000000, 0.000000, 0.156863 }, { 1.000000, 0.000000, 0.176471 }, { 1.000000, 0.000000, 0.196078 }, { 1.000000, 0.000000, 0.215686 }, { 1.000000, 0.000000, 0.235294 }, { 1.000000, 0.000000, 0.254902 }, { 1.000000, 0.000000, 0.274510 }, { 1.000000, 0.000000, 0.294118 }, { 1.000000, 0.000000, 0.313725 }, { 1.000000, 0.000000, 0.333333 }, { 1.000000, 0.000000, 0.352941 }, { 1.000000, 0.000000, 0.372549 }, { 1.000000, 0.000000, 0.392157 }, { 1.000000, 0.000000, 0.411765 }, { 1.000000, 0.000000, 0.431373 }, { 1.000000, 0.000000, 0.450980 }, { 1.000000, 0.000000, 0.470588 }, { 1.000000, 0.000000, 0.490196 }, { 1.000000, 0.000000, 0.509804 }, { 1.000000, 0.000000, 0.529412 }, { 1.000000, 0.000000, 0.549020 }, { 1.000000, 0.000000, 0.568627 }, { 1.000000, 0.000000, 0.588235 }, { 1.000000, 0.000000, 0.607843 }, { 1.000000, 0.000000, 0.627451 }, { 1.000000, 0.000000, 0.647059 }, { 1.000000, 0.000000, 0.666667 }, { 1.000000, 0.000000, 0.686275 }, { 1.000000, 0.000000, 0.705882 }, { 1.000000, 0.000000, 0.725490 }, { 1.000000, 0.000000, 0.745098 }, { 1.000000, 0.000000, 0.764706 }, { 1.000000, 0.000000, 0.784314 }, { 1.000000, 0.000000, 0.803922 }, { 1.000000, 0.000000, 0.823529 }, { 1.000000, 0.000000, 0.843137 }, { 1.000000, 0.000000, 0.862745 }, { 1.000000, 0.000000, 0.882353 }, { 1.000000, 0.000000, 0.901961 }, { 1.000000, 0.000000, 0.921569 }, { 1.000000, 0.000000, 0.941176 }, { 1.000000, 0.000000, 0.960784 }, { 1.000000, 0.000000, 0.980392 }, { 1.000000, 0.000000, 1.000000 } }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/lut/Flow.h0000644000175000017500000001605511667757442025324 0ustar mathieumathieu/*========================================================================= Program: vtkINRIA3D Module: $Id: Flow.h 477 2007-11-20 17:46:10Z filus $ Language: C++ Author: $Author: filus $ Date: $Date: 2007-11-20 12:46:10 -0500 (Tue, 20 Nov 2007) $ Version: $Revision: 477 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _lut_Flow_h_ #define _lut_Flow_h_ static const int Flow[3 * 256] = { 32, 32, 32, 32, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 26, 26, 26, 26, 26, 25, 25, 25, 25, 25, 24, 24, 24, 24, 24, 23, 23, 23, 23, 23, 22, 22, 22, 22, 22, 21, 21, 21, 21, 21, 20, 20, 20, 20, 19, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 200, 197, 194, 191, 188, 185, 182, 179, 176, 173, 170, 167, 164, 161, 158, 155, 152, 149, 146, 143, 140, 137, 134, 131, 128, 125, 122, 119, 116, 113, 110, 107, 104, 101, 98, 95, 92, 89, 86, 83, 80, 77, 74, 71, 68, 65, 62, 59, 56, 53, 50, 47, 44, 41, 38, 35, 32, 29, 26, 23, 20, 20, 20, 19, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62, 66, 70, 74, 78, 82, 86, 90, 94, 98, 102, 106, 110, 114, 118, 122, 126, 130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, 247, 244, 240, 236, 232, 228, 225, 221, 217, 213, 209, 206, 202, 198, 194, 190, 186, 183, 179, 175, 171, 167, 164, 160, 156, 152, 148, 145, 141, 137, 133, 129, 126, 122, 118, 114, 110, 107, 103, 99, 95, 91, 88, 84, 80, 76, 72, 69, 65, 61, 57, 53, 49, 46, 42, 38, 34, 30, 27, 23, 19, 15, 11, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248, 255 }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/lut/LONI2.h0000644000175000017500000002034611667757442025236 0ustar mathieumathieu/*========================================================================= Program: vtkINRIA3D Module: $Id: LONI2.h 477 2007-11-20 17:46:10Z filus $ Language: C++ Author: $Author: filus $ Date: $Date: 2007-11-20 12:46:10 -0500 (Tue, 20 Nov 2007) $ Version: $Revision: 477 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _lut_LONI2_h_ #define _lut_LONI2_h_ static const double LONI2[120][3] = { { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.000000, 1.000000 }, { 0.000000, 0.111111, 1.000000 }, { 0.000000, 0.222222, 1.000000 }, { 0.000000, 0.333333, 1.000000 }, { 0.000000, 0.444444, 1.000000 }, { 0.000000, 0.555556, 1.000000 }, { 0.000000, 0.666667, 1.000000 }, { 0.000000, 0.777778, 1.000000 }, { 0.000000, 0.888889, 1.000000 }, { 0.000000, 1.000000, 1.000000 }, { 0.000000, 1.000000, 1.000000 }, { 0.000000, 1.000000, 0.888889 }, { 0.000000, 1.000000, 0.777778 }, { 0.000000, 1.000000, 0.666667 }, { 0.000000, 1.000000, 0.555556 }, { 0.000000, 1.000000, 0.444444 }, { 0.000000, 1.000000, 0.333333 }, { 0.000000, 1.000000, 0.222222 }, { 0.000000, 1.000000, 0.111111 }, { 0.000000, 1.000000, 0.000000 }, { 0.000000, 1.000000, 0.000000 }, { 0.111111, 1.000000, 0.000000 }, { 0.222222, 1.000000, 0.000000 }, { 0.333333, 1.000000, 0.000000 }, { 0.444444, 1.000000, 0.000000 }, { 0.555556, 1.000000, 0.000000 }, { 0.666667, 1.000000, 0.000000 }, { 0.777778, 1.000000, 0.000000 }, { 0.888889, 1.000000, 0.000000 }, { 1.000000, 1.000000, 0.000000 }, { 1.000000, 1.000000, 0.000000 }, { 1.000000, 0.947368, 0.000000 }, { 1.000000, 0.894737, 0.000000 }, { 1.000000, 0.842105, 0.000000 }, { 1.000000, 0.789474, 0.000000 }, { 1.000000, 0.736842, 0.000000 }, { 1.000000, 0.684211, 0.000000 }, { 1.000000, 0.631579, 0.000000 }, { 1.000000, 0.578947, 0.000000 }, { 1.000000, 0.526316, 0.000000 }, { 1.000000, 0.473684, 0.000000 }, { 1.000000, 0.421053, 0.000000 }, { 1.000000, 0.368421, 0.000000 }, { 1.000000, 0.315789, 0.000000 }, { 1.000000, 0.263158, 0.000000 }, { 1.000000, 0.210526, 0.000000 }, { 1.000000, 0.157895, 0.000000 }, { 1.000000, 0.105263, 0.000000 }, { 1.000000, 0.052632, 0.000000 }, { 1.000000, 0.000000, 0.000000 }, { 1.000000, 0.000000, 0.000000 }, { 1.000000, 0.000000, 0.052632 }, { 1.000000, 0.000000, 0.105263 }, { 1.000000, 0.000000, 0.157895 }, { 1.000000, 0.000000, 0.210526 }, { 1.000000, 0.000000, 0.263158 }, { 1.000000, 0.000000, 0.315789 }, { 1.000000, 0.000000, 0.368421 }, { 1.000000, 0.000000, 0.421053 }, { 1.000000, 0.000000, 0.473684 }, { 1.000000, 0.000000, 0.526316 }, { 1.000000, 0.000000, 0.578947 }, { 1.000000, 0.000000, 0.631579 }, { 1.000000, 0.000000, 0.684211 }, { 1.000000, 0.000000, 0.736842 }, { 1.000000, 0.000000, 0.789474 }, { 1.000000, 0.000000, 0.842105 }, { 1.000000, 0.000000, 0.894737 }, { 1.000000, 0.000000, 0.947368 }, { 1.000000, 0.000000, 1.000000 } }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/lut/Spectrum.h0000644000175000017500000001622311667757442026214 0ustar mathieumathieu/*========================================================================= Program: vtkINRIA3D Module: $Id: Spectrum.h 477 2007-11-20 17:46:10Z filus $ Language: C++ Author: $Author: filus $ Date: $Date: 2007-11-20 12:46:10 -0500 (Tue, 20 Nov 2007) $ Version: $Revision: 477 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _lut_Spectrum_h_ #define _lut_Spectrum_h_ static const int Spectrum[256 * 3] = { 255, 250, 245, 240, 235, 230, 225, 220, 215, 210, 205, 200, 195, 190, 185, 180, 175, 170, 165, 160, 155, 150, 145, 140, 135, 130, 125, 120, 115, 110, 105, 100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 245, 240, 235, 230, 225, 220, 215, 210, 205, 200, 195, 190, 185, 180, 175, 170, 165, 160, 155, 150, 145, 140, 135, 130, 125, 120, 115, 110, 105, 100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 245, 240, 235, 230, 225, 220, 215, 210, 205, 200, 195, 190, 185, 180, 175, 170, 165, 160, 155, 150, 145, 140, 135, 130, 125, 120, 115, 110, 105, 100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/lut/LONI.h0000644000175000017500000002677711667757442025172 0ustar mathieumathieu/*========================================================================= Program: vtkINRIA3D Module: $Id: LONI.h 477 2007-11-20 17:46:10Z filus $ Language: C++ Author: $Author: filus $ Date: $Date: 2007-11-20 12:46:10 -0500 (Tue, 20 Nov 2007) $ Version: $Revision: 477 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _lut_LONI_h_ #define _lut_LONI_h_ static const double LONI[203][3] = { { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0, 1.0000 }, { 0, 0.0244, 1.0000 }, { 0, 0.0488, 1.0000 }, { 0, 0.0732, 1.0000 }, { 0, 0.0976, 1.0000 }, { 0, 0.1220, 1.0000 }, { 0, 0.1463, 1.0000 }, { 0, 0.1707, 1.0000 }, { 0, 0.1951, 1.0000 }, { 0, 0.2195, 1.0000 }, { 0, 0.2439, 1.0000 }, { 0, 0.2683, 1.0000 }, { 0, 0.2927, 1.0000 }, { 0, 0.3171, 1.0000 }, { 0, 0.3415, 1.0000 }, { 0, 0.3659, 1.0000 }, { 0, 0.3902, 1.0000 }, { 0, 0.4146, 1.0000 }, { 0, 0.4390, 1.0000 }, { 0, 0.4634, 1.0000 }, { 0, 0.4878, 1.0000 }, { 0, 0.5122, 1.0000 }, { 0, 0.5366, 1.0000 }, { 0, 0.5610, 1.0000 }, { 0, 0.5854, 1.0000 }, { 0, 0.6098, 1.0000 }, { 0, 0.6341, 1.0000 }, { 0, 0.6585, 1.0000 }, { 0, 0.6829, 1.0000 }, { 0, 0.7073, 1.0000 }, { 0, 0.7317, 1.0000 }, { 0, 0.7561, 1.0000 }, { 0, 0.7805, 1.0000 }, { 0, 0.8049, 1.0000 }, { 0, 0.8293, 1.0000 }, { 0, 0.8537, 1.0000 }, { 0, 0.8780, 1.0000 }, { 0, 0.9024, 1.0000 }, { 0, 0.9268, 1.0000 }, { 0, 0.9512, 1.0000 }, { 0, 0.9756, 1.0000 }, { 0, 1.0000, 1.0000 }, { 0, 1.0000, 0.9756 }, { 0, 1.0000, 0.9512 }, { 0, 1.0000, 0.9268 }, { 0, 1.0000, 0.9024 }, { 0, 1.0000, 0.8780 }, { 0, 1.0000, 0.8537 }, { 0, 1.0000, 0.8293 }, { 0, 1.0000, 0.8049 }, { 0, 1.0000, 0.7805 }, { 0, 1.0000, 0.7561 }, { 0, 1.0000, 0.7317 }, { 0, 1.0000, 0.7073 }, { 0, 1.0000, 0.6829 }, { 0, 1.0000, 0.6585 }, { 0, 1.0000, 0.6341 }, { 0, 1.0000, 0.6098 }, { 0, 1.0000, 0.5854 }, { 0, 1.0000, 0.5610 }, { 0, 1.0000, 0.5366 }, { 0, 1.0000, 0.5122 }, { 0, 1.0000, 0.4878 }, { 0, 1.0000, 0.4634 }, { 0, 1.0000, 0.4390 }, { 0, 1.0000, 0.4146 }, { 0, 1.0000, 0.3902 }, { 0, 1.0000, 0.3659 }, { 0, 1.0000, 0.3415 }, { 0, 1.0000, 0.3171 }, { 0, 1.0000, 0.2927 }, { 0, 1.0000, 0.2683 }, { 0, 1.0000, 0.2439 }, { 0, 1.0000, 0.2195 }, { 0, 1.0000, 0.1951 }, { 0, 1.0000, 0.1707 }, { 0, 1.0000, 0.1463 }, { 0, 1.0000, 0.1220 }, { 0, 1.0000, 0.0976 }, { 0, 1.0000, 0.0732 }, { 0, 1.0000, 0.0488 }, { 0, 1.0000, 0.0244 }, { 0, 1.0000, 0 }, { 0.0244, 1.0000, 0 }, { 0.0488, 1.0000, 0 }, { 0.0732, 1.0000, 0 }, { 0.0976, 1.0000, 0 }, { 0.1220, 1.0000, 0 }, { 0.1463, 1.0000, 0 }, { 0.1707, 1.0000, 0 }, { 0.1951, 1.0000, 0 }, { 0.2195, 1.0000, 0 }, { 0.2439, 1.0000, 0 }, { 0.2683, 1.0000, 0 }, { 0.2927, 1.0000, 0 }, { 0.3171, 1.0000, 0 }, { 0.3415, 1.0000, 0 }, { 0.3659, 1.0000, 0 }, { 0.3902, 1.0000, 0 }, { 0.4146, 1.0000, 0 }, { 0.4390, 1.0000, 0 }, { 0.4634, 1.0000, 0 }, { 0.4878, 1.0000, 0 }, { 0.5122, 1.0000, 0 }, { 0.5366, 1.0000, 0 }, { 0.5610, 1.0000, 0 }, { 0.5854, 1.0000, 0 }, { 0.6098, 1.0000, 0 }, { 0.6341, 1.0000, 0 }, { 0.6585, 1.0000, 0 }, { 0.6829, 1.0000, 0 }, { 0.7073, 1.0000, 0 }, { 0.7317, 1.0000, 0 }, { 0.7561, 1.0000, 0 }, { 0.7805, 1.0000, 0 }, { 0.8049, 1.0000, 0 }, { 0.8293, 1.0000, 0 }, { 0.8537, 1.0000, 0 }, { 0.8780, 1.0000, 0 }, { 0.9024, 1.0000, 0 }, { 0.9268, 1.0000, 0 }, { 0.9512, 1.0000, 0 }, { 0.9756, 1.0000, 0 }, { 1.0000, 1.0000, 0 }, { 1.0000, 0.9756, 0 }, { 1.0000, 0.9512, 0 }, { 1.0000, 0.9268, 0 }, { 1.0000, 0.9024, 0 }, { 1.0000, 0.8780, 0 }, { 1.0000, 0.8537, 0 }, { 1.0000, 0.8293, 0 }, { 1.0000, 0.8049, 0 }, { 1.0000, 0.7805, 0 }, { 1.0000, 0.7561, 0 }, { 1.0000, 0.7317, 0 }, { 1.0000, 0.7073, 0 }, { 1.0000, 0.6829, 0 }, { 1.0000, 0.6585, 0 }, { 1.0000, 0.6341, 0 }, { 1.0000, 0.6098, 0 }, { 1.0000, 0.5854, 0 }, { 1.0000, 0.5610, 0 }, { 1.0000, 0.5366, 0 }, { 1.0000, 0.5122, 0 }, { 1.0000, 0.4878, 0 }, { 1.0000, 0.4634, 0 }, { 1.0000, 0.4390, 0 }, { 1.0000, 0.4146, 0 }, { 1.0000, 0.3902, 0 }, { 1.0000, 0.3659, 0 }, { 1.0000, 0.3415, 0 }, { 1.0000, 0.3171, 0 }, { 1.0000, 0.2927, 0 }, { 1.0000, 0.2683, 0 }, { 1.0000, 0.2439, 0 }, { 1.0000, 0.2195, 0 }, { 1.0000, 0.1951, 0 }, { 1.0000, 0.1707, 0 }, { 1.0000, 0.1463, 0 }, { 1.0000, 0.1220, 0 }, { 1.0000, 0.0976, 0 }, { 1.0000, 0.0732, 0 }, { 1.0000, 0.0488, 0 }, { 1.0000, 0.0244, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 }, { 1.0000, 0, 0 } }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/lut/Random.h0000644000175000017500000000505111667757442025627 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __lut_Random_h #define __lut_Random_h static const int RandomColors[90] = { 255, 0, 0, 0, 205, 0, 0, 0, 255, 0, 255, 255, 255, 0, 255, 255, 127, 0, 0, 100, 0, 138, 43, 226, 139, 35, 35, 0, 0, 128, 139, 139, 0, 255, 62, 150, 139, 76, 57, 0, 134, 139, 205, 104, 57, 191, 62, 255, 0, 139, 69, 199, 21, 133, 205, 55, 0, 32, 178, 170, 106, 90, 205, 255, 20, 147, 69, 139, 116, 72, 118, 255, 205, 79, 57, 0, 0, 205, 139, 34, 82, 139, 0, 139, 238, 130, 238, 139, 0, 0 }; #endif // __lut_Random_h GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3DCommand.h0000644000175000017500000000750611667757442027702 0ustar mathieumathieu/*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkViewImage3DCommand_h #define __vtkViewImage3DCommand_h #include "vtkCommand.h" #include "vtkObject.h" #include "MegaVTK2Configure.h" class vtkViewImage3D; class vtkImplicitPlaneWidget; class vtkOrientedBoxWidget; /** * \class vtkViewImage3DCommand * \ingroup MegaVTK * \brief Manage events occuring in 3D view */ class VTK_RENDERINGADDON2_EXPORT vtkViewImage3DCommand: public vtkCommand { public: /** * \brief Convenient method to access the constructor. */ static vtkViewImage3DCommand * New(); //BTX enum EventIds { SliceMoveEvent = ( vtkCommand::UserEvent + 1 ), StartSliceMoveEvent, EndSliceMoveEvent, ZoomEvent, PanEvent, RequestedPositionEvent, ResetViewerEvent, MeshPickingEvent, BoxPickingEvent, CameraMoveEvent, DefaultMoveEvent, BoxWidgetModifiedEvent, ReadyEvent, BoxWidgetReadyEvent, VisibilityUpdatedEvent, UpdateRenderEvent }; //ETX // Description: // Satisfy the superclass API for callbacks. Recall that the caller is // the instance invoking the event; eid is the event id (see // vtkCommand.h); and calldata is information sent when the callback // was invoked (e.g., progress value in the vtkCommand::ProgressEvent). virtual void Execute(vtkObject *caller, unsigned long, void *); /** * \brief Set the 3d image related to this 3d event manager * \param[in] vtkViewImage3D Target 3D image */ void SetVtkImageView3D(vtkViewImage3D *vtkViewImage3D); /** * \brief Set the plane widget * \param[in] iPlaneWidget vtkImplicitPlaneWidget pointer to the plane widget */ void SetPlaneWidget(vtkImplicitPlaneWidget *iPlaneWidget); /** * \brief Set the box widget * \param[in] iBoxWidget vtkOrientedBoxWidget pointer to the box widget */ void SetBoxWidget(vtkOrientedBoxWidget *iBoxWidget); protected: vtkViewImage3DCommand(); ~vtkViewImage3DCommand(); private: vtkViewImage3D * m_vtkViewImage3D; vtkImplicitPlaneWidget *m_PlaneWidget; vtkOrientedBoxWidget * m_BoxWidget; }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkLookupTableManager.cxx0000644000175000017500000003476011667757442030430 0ustar mathieumathieu/*========================================================================= Program: vtkINRIA3D Module: $Id: vtkLookupTableManager.cxx 842 2008-05-20 16:57:09Z ntoussaint $ Language: C++ Author: $Author: arnaudgelas $ Date: $Date: 2009-07-31 14:33:39 -0400 (Fri, 31 Jul 2009) $ Version: $Revision: 490 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkLookupTableManager.h" #include vtkCxxRevisionMacro(vtkLookupTableManager, "$Revision: 490 $"); vtkStandardNewMacro(vtkLookupTableManager); #include "lut/Spectrum.h" #include "lut/HotMetal.h" #include "lut/GEColor.h" #include "lut/Flow.h" #include "lut/LONI.h" #include "lut/LONI2.h" #include "lut/Asymmetry.h" #include "lut/Random.h" #include vtkLookupTableManager::vtkLookupTableManager() { } vtkLookupTableManager::~vtkLookupTableManager() { } std::vector< std::string > vtkLookupTableManager::GetAvailableLookupTables() { std::vector< std::string > v_lutNames; v_lutNames.push_back("B/W"); v_lutNames.push_back("B/W Inverse"); v_lutNames.push_back("Spectrum"); v_lutNames.push_back("HotMetal"); v_lutNames.push_back("GEColor"); v_lutNames.push_back("Flow"); v_lutNames.push_back("LONI"); v_lutNames.push_back("LONI2"); v_lutNames.push_back("Asymmetry"); v_lutNames.push_back("P-Value"); v_lutNames.push_back("ROI"); v_lutNames.push_back("Random"); return v_lutNames; } vtkLookupTable * vtkLookupTableManager::GetLookupTable(const int & iIndex) { vtkLookupTable *lut = 0; switch ( iIndex ) { case LUT_BW: lut = vtkLookupTableManager::GetBWLookupTable(); break; case LUT_BWINV: lut = vtkLookupTableManager::GetBWInverseLookupTable(); break; case LUT_SPECTTUM: lut = vtkLookupTableManager::GetSpectrumLookupTable(); break; case LUT_HOTMETAL: lut = vtkLookupTableManager::GetHotMetalLookupTable(); break; case LUT_GECOLORS: lut = vtkLookupTableManager::GetGEColorLookupTable(); break; case LUT_FLOW: lut = vtkLookupTableManager::GetFlowLookupTable(); break; case LUT_LONI: lut = vtkLookupTableManager::GetLONILookupTable(); break; case LUT_LONI2: lut = vtkLookupTableManager::GetLONI2LookupTable(); break; case LUT_ASYMETRY: lut = vtkLookupTableManager::GetAsymmetryLookupTable(); break; case LUT_PVALUE: lut = vtkLookupTableManager::GetPValueLookupTable(); break; case LUT_ROI: lut = vtkLookupTableManager::GetROILookupTable(); break; case LUT_RANDOM: lut = vtkLookupTableManager::GetRandomLookupTable(); break; default: std::cout << "Unknown Lookup Table" << std::endl; break; } return lut; } vtkLookupTable * vtkLookupTableManager::GetBWLookupTable() { vtkLookupTable *bwLut = vtkLookupTable::New(); bwLut->SetTableRange (0, 1); bwLut->SetSaturationRange (0, 0); bwLut->SetHueRange (0, 0); bwLut->SetValueRange (0, 1); bwLut->Build(); return bwLut; } vtkLookupTable * vtkLookupTableManager::GetBWInverseLookupTable() { vtkLookupTable *bwLut = vtkLookupTable::New(); bwLut->SetTableRange (0, 1); bwLut->SetSaturationRange (0, 0); bwLut->SetHueRange (0, 0); bwLut->SetValueRange (1, 0); bwLut->Build(); return bwLut; } vtkLookupTable * vtkLookupTableManager::GetSpectrumLookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->SetNumberOfTableValues(256); lut->Build(); for ( int i = 0; i < 256; i++ ) { lut->SetTableValue(i, (double)Spectrum[i] / 255.0, (double)Spectrum[256 + i] / 255.0, (double)Spectrum[256 * 2 + i] / 255.0, 1.0); } return lut; } vtkLookupTable * vtkLookupTableManager::GetHotMetalLookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->SetNumberOfTableValues(256); lut->Build(); for ( int i = 0; i < 256; i++ ) { lut->SetTableValue(i, (double)HotMetal[i] / 255.0, (double)HotMetal[256 + i] / 255.0, (double)HotMetal[256 * 2 + i] / 255.0, 1.0); } return lut; } vtkLookupTable * vtkLookupTableManager::GetGEColorLookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->SetNumberOfTableValues(256); lut->Build(); for ( int i = 0; i < 256; i++ ) { lut->SetTableValue(i, (double)GEColor[i] / 255.0, (double)GEColor[256 + i] / 255.0, (double)GEColor[256 * 2 + i] / 255.0, 1.0); } return lut; } vtkLookupTable * vtkLookupTableManager::GetFlowLookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->SetNumberOfTableValues(256); lut->Build(); for ( int i = 0; i < 256; i++ ) { lut->SetTableValue(i, (double)Flow[i] / 255.0, (double)Flow[256 + i] / 255.0, (double)Flow[256 * 2 + i] / 255.0, 1.0); } return lut; } vtkLookupTable * vtkLookupTableManager::GetLONILookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->SetNumberOfTableValues(203); lut->Build(); for ( int i = 0; i < 203; i++ ) { lut->SetTableValue(i, (double)LONI[i][0], (double)LONI[i][1], (double)LONI[i][2], 1.0); } return lut; } vtkLookupTable * vtkLookupTableManager::GetLONI2LookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->SetNumberOfTableValues(120); lut->Build(); for ( int i = 0; i < 120; i++ ) { lut->SetTableValue(i, (double)LONI2[i][0], (double)LONI2[i][1], (double)LONI2[i][2], 1.0); } return lut; } vtkLookupTable * vtkLookupTableManager::GetAsymmetryLookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->SetNumberOfTableValues(256); lut->Build(); for ( int i = 0; i < 256; i++ ) { lut->SetTableValue(i, (double)AsymmetryLUT[i][0], (double)AsymmetryLUT[i][1], (double)AsymmetryLUT[i][2], 1.0); } return lut; } vtkLookupTable * vtkLookupTableManager::GetPValueLookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->SetTableRange (0, 1); lut->SetSaturationRange (1.0, 1.5); lut->SetHueRange (0.666, 0.8333); //lut->SetHueRange (0.666, 0.0); lut->SetValueRange (0.5, 1.0); lut->Build(); return lut; } vtkLookupTable * vtkLookupTableManager::GetROILookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->SetNumberOfTableValues (256); lut->SetTableValue (0, 0.0, 0.0, 0.0, 0.0); // erase color lut->SetTableValue (1, 1.0, 0.0, 0.0, 0.5); lut->SetTableValue (2, 0.0, 1.0, 0.0, 0.5); lut->SetTableValue (3, 0.0, 0.0, 1.0, 0.5); lut->SetTableValue (4, 1.0, 1.0, 0.0, 0.5); lut->SetTableValue (5, 0.0, 1.0, 1.0, 0.5); lut->SetTableValue (6, 1.0, 0.0, 1.0, 0.5); lut->SetTableValue (7, 1.0, 0.5, 0.0, 0.5); lut->SetTableValue (8, 0.0, 1.0, 0.5, 0.5); lut->SetTableValue (9, 0.5, 0.0, 1.0, 0.5); lut->SetTableValue (10, 1.0, 1.0, 0.5, 0.5); lut->SetTableValue (11, 0.5, 1.0, 1.0, 0.5); lut->SetTableValue (12, 1.0, 0.5, 1.0, 0.5); // Fill the rest of the labels with color ramps, code taken from SNAP // for (int i = 13; i < 256; i++) // { // if (i < 85) // { // lut->SetTableValue (i, ((84.0-i)/85.0 * 200.0 + 50.0)/255.0, (i/85.0 * // 200.0 + 50.0)/255.0, 0, 0.5); // } // else if (i < 170) // { // lut->SetTableValue (i, 0, ((169.0-i)/85.0 * 200.0 + 50)/255.0, // ((i-85)/85.0 * 200.0 + 50)/255.0, 0.5); // } // else // { // lut->SetTableValue (i, ((i-170)/85.0 * 200.0 + 50)/255.0, 0.0, // ((255.0-i)/85.0 * 200.0 + 50)/255.0, 0.5); // } // } // Fill the rest with random colors // for (int i = 13; i < 256; i++) // { // srand (clock()); // // put a random color // int i1 = 1 + (int) (100.0 * ((double)rand() / (RAND_MAX + 1.0))); // int i2 = 1 + (int) (100.0 * ((double)rand() / (RAND_MAX + 1.0))); // int i3 = 1 + (int) (100.0 * ((double)rand() / (RAND_MAX + 1.0))); // double rand_1 = (double)(i1)/(100.0); // double rand_2 = (double)(i2)/(100.0); // double rand_3 = (double)(i3)/(100.0); // double r = rand_1, g = rand_2, b = rand_3; // if (i1 < 33) // r = 1; // else if (i1 < 66) // g = 1; // else if (i1 < 100) // b = 1; // lut->SetTableValue (i, r, g, b, 0.5); // } for ( int i = 12; i < 256; i++ ) { if ( i % 12 == 0 ) { lut->SetTableValue (i, 1.0, 0.0, 0.0, 0.5); } else if ( i % 12 == 1 ) { lut->SetTableValue (i, 0.0, 1.0, 0.0, 0.5); } else if ( i % 12 == 2 ) { lut->SetTableValue (i, 0.0, 0.0, 1.0, 0.5); } else if ( i % 12 == 3 ) { lut->SetTableValue (i, 1.0, 1.0, 0.0, 0.5); } else if ( i % 12 == 4 ) { lut->SetTableValue (i, 0.0, 1.0, 1.0, 0.5); } else if ( i % 12 == 5 ) { lut->SetTableValue (i, 1.0, 0.0, 1.0, 0.5); } else if ( i % 12 == 6 ) { lut->SetTableValue (i, 1.0, 0.5, 0.0, 0.5); } else if ( i % 12 == 7 ) { lut->SetTableValue (i, 0.0, 1.0, 0.5, 0.5); } else if ( i % 12 == 8 ) { lut->SetTableValue (i, 0.5, 0.0, 1.0, 0.5); } else if ( i % 12 == 9 ) { lut->SetTableValue (i, 1.0, 1.0, 0.5, 0.5); } else if ( i % 12 == 10 ) { lut->SetTableValue (i, 0.5, 1.0, 1.0, 0.5); } else if ( i % 12 == 11 ) { lut->SetTableValue (i, 1.0, 0.5, 1.0, 0.5); } } return lut; } vtkLookupTable * vtkLookupTableManager::GetRandomLookupTable() { vtkLookupTable *lut = vtkLookupTable::New(); lut->SetNumberOfTableValues(30); lut->Build(); int k = 0; int r, g, b; for ( int i = 0; i < 30; i++ ) { r = RandomColors[k++]; g = RandomColors[k++]; b = RandomColors[k++]; lut->SetTableValue(i, static_cast< double >( r ) / 255., static_cast< double >( g ) / 255., static_cast< double >( b ) / 255., 1.0); } return lut; } vtkLookupTable * vtkLookupTableManager::GetHSVBasedLookupTable(double iHSV[3]) { vtkLookupTable *lut = vtkLookupTable::New(); lut->SetTableRange (0., 1.); if ( ( iHSV[0] >= 0. ) && ( iHSV[0] <= 1. ) ) { lut->SetHueRange (iHSV[0], iHSV[0]); } else { std::cout << "iHSV[0] < 0 or > 1" << std::endl; return NULL; } if ( ( iHSV[1] >= 0. ) && ( iHSV[1] <= 1. ) ) { lut->SetSaturationRange (iHSV[1], iHSV[1]); } else { std::cout << "iHSV[1] < 0 or > 1" << std::endl; return NULL; } if ( ( iHSV[2] >= 0. ) && ( iHSV[2] <= 1. ) ) { lut->SetValueRange (0., iHSV[2]); } else { std::cout << "iHSV[2] < 0 or > 1" << std::endl; return NULL; } lut->Build(); return lut; }GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2DCommand.h0000644000175000017500000001345311667757442027677 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _vtkViewImage2DCommand_h_ #define _vtkViewImage2DCommand_h_ #include #include "MegaVTK2Configure.h" class vtkInteractorStyleImage2D; class vtkInteractorStyleImage; class vtkViewImage2D; /** * \class vtkViewImage2DCommand * \ingroup MegaVTK * \brief Manage events occuring in 2D view */ class VTK_RENDERINGADDON2_EXPORT vtkViewImage2DCommand:public vtkCommand { public: /** * \brief Convenient method to access the constructor. */ static vtkViewImage2DCommand * New() { return new vtkViewImage2DCommand; } //BTX enum EventIds { SliceMoveEvent = ( vtkCommand::UserEvent + 1 ), StartSliceMoveEvent, EndSliceMoveEvent, ZoomEvent, PanEvent, RequestedPositionEvent, ResetViewerEvent, ContourPickingEvent, MeshPickingEvent, CameraMoveEvent, DefaultMoveEvent, WindowLevelEvent, SyncViewsEvent }; //ETX // Description: // Satisfy the superclass API for callbacks. Recall that the caller is // the instance invoking the event; eid is the event id (see // vtkCommand.h); and calldata is information sent when the callback // was invoked (e.g., progress value in the vtkCommand::ProgressEvent). virtual void Execute( vtkObject * caller, unsigned long event, void *vtkNotUsed(callData) ); /** * \brief Set the 2d image related to this 2d event manager * \param[in] viewer vtkViewImage2D Target 2D image */ void SetViewer(vtkViewImage2D *viewer) { this->Viewer = viewer; } protected: vtkViewImage2DCommand(); ~vtkViewImage2DCommand(){} /** * \brief Method to be called if an event is caught in "Windowing Mode" * \param[in] isi Related interactor */ void Windowing(vtkInteractorStyleImage2D *isi); /** * \brief Method to be called if an event is caught in "Zooming Mode" */ void Zooming(); /** * \brief Method to be called if an event is caught in "Panning Mode" */ void Panning(); /** * \brief Method to be called when an event is caught to update information in 2D view * such as position, pixel intensity, etc. */ void PrintInformation(); private: vtkViewImage2D *Viewer; double InitialWindow; double InitialLevel; int InitialSlice; }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkImage3DImagePlaneCallback.cxx0000644000175000017500000002052711667757442031461 0ustar mathieumathieu/*========================================================================= Program: vtkINRIA3D Module: $Id: vtkImage3DImagePlaneCallback.cxx 665 2008-02-11 12:31:28Z ntoussaint $ Language: C++ Author: $Author: arnaudgelas $ Date: $Date: 2009-07-31 14:33:39 -0400 (Fri, 31 Jul 2009) $ Version: $Revision: 490 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkImage3DImagePlaneCallback.h" #include #include #include #include #include "vtkViewImage2D.h" #include void vtkImage3DImagePlaneCallback::Execute(vtkObject *caller, unsigned long, void *) { /* if( !this->ViewImage2D ) { return; } */ // get the box widget // vtkPlaneWidget *widget = reinterpret_cast(caller); vtkPlaneWidget *widget = vtkPlaneWidget::SafeDownCast(caller); if ( !widget ) { return; } vtkImageData *imageData = vtkImageData::SafeDownCast( widget->GetInput() ); if ( !imageData ) { this->Reslice->SetInput (NULL); return; } this->Reslice->SetInput (imageData); // Calculate appropriate pixel spacing for the reslicing imageData->UpdateInformation(); double spacing[3]; imageData->GetSpacing(spacing); double imOrigin[3]; imageData->GetOrigin(imOrigin); int extent[6]; imageData->GetWholeExtent(extent); double bounds[] = { imOrigin[0] + spacing[0] * extent[0], //xmin imOrigin[0] + spacing[0] * extent[1], //xmax imOrigin[1] + spacing[1] * extent[2], //ymin imOrigin[1] + spacing[1] * extent[3], //ymax imOrigin[2] + spacing[2] * extent[4], //zmin imOrigin[2] + spacing[2] * extent[5] }; //zmax int i = 0; for ( i = 0; i <= 4; i += 2 ) // reverse bounds if necessary { if ( bounds[i] > bounds[i + 1] ) { double t = bounds[i + 1]; bounds[i + 1] = bounds[i]; bounds[i] = t; } } double abs_normal[3]; widget->GetNormal(abs_normal); double planeCenter[3]; widget->GetCenter(planeCenter); double nmax = 0.0; int k = 0; for ( i = 0; i < 3; i++ ) { abs_normal[i] = fabs(abs_normal[i]); if ( abs_normal[i] > nmax ) { nmax = abs_normal[i]; k = i; } } // Force the plane to lie within the true image bounds along its normal // if ( planeCenter[k] > bounds[2 * k + 1] ) { planeCenter[k] = bounds[2 * k + 1]; } else if ( planeCenter[k] < bounds[2 * k] ) { planeCenter[k] = bounds[2 * k]; } widget->SetCenter(planeCenter); // get the planes double point1[3], point2[3], origin[4], normal[3]; widget->GetPoint1 (point1); widget->GetPoint2 (point2); widget->GetOrigin (origin); widget->GetNormal (normal); double axis1[3], axis2[3]; for ( i = 0; i < 3; i++ ) { axis1[i] = point1[i] - origin[i]; axis2[i] = point2[i] - origin[i]; } double planeSizeX = vtkMath::Normalize(axis1); double planeSizeY = vtkMath::Normalize(axis2); this->ResliceAxes->Identity(); for ( i = 0; i < 3; i++ ) { this->ResliceAxes->SetElement(0, i, axis1[i]); this->ResliceAxes->SetElement(1, i, axis2[i]); this->ResliceAxes->SetElement(2, i, normal[i]); } origin[3] = 1.0; double originXYZW[4]; this->ResliceAxes->MultiplyPoint(origin, originXYZW); this->ResliceAxes->Transpose(); double neworiginXYZW[4]; double point[] = { originXYZW[0], originXYZW[1], originXYZW[2], originXYZW[3] }; this->ResliceAxes->MultiplyPoint(point, neworiginXYZW); this->ResliceAxes->SetElement(0, 3, neworiginXYZW[0]); this->ResliceAxes->SetElement(1, 3, neworiginXYZW[1]); this->ResliceAxes->SetElement(2, 3, neworiginXYZW[2]); this->Reslice->SetResliceAxes (this->ResliceAxes); this->Reslice->SetInterpolationModeToLinear(); this->Reslice->SetOutputSpacing (1.0, 1.0, 1.0); this->Reslice->SetOutputOrigin (0, 0, 0); this->Reslice->SetOutputExtent (0, static_cast< int >( planeSizeX ) - 1, 0, static_cast< int >( planeSizeY ) - 1, 0, 0); this->Reslice->Update(); /* if( this->FirstRender ) { this->ViewImage2D->SetImage ( this->Reslice->GetOutput() ); this->ViewImage2D->ResetCurrentPoint(); this->ViewImage2D->ResetWindowLevel(); this->FirstRender = false; } this->ViewImage2D->Update(); this->ViewImage2D->Render(); */ }GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkPolylineDecimation.h0000644000175000017500000000711111667757442030117 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkPolylineDecimation_h #define __vtkPolylineDecimation_h #include #include #include #include "MegaVTK2Configure.h" /** * \class vtkPolylineDecimation * \ingroup MegaVTK * \brief Decimate a polyline * \note With the git version of VTK, this class does not make any sense * (the code has been contributed back to VTK) */ class VTK_RENDERINGADDON2_EXPORT vtkPolylineDecimation:public vtkPolyDataAlgorithm { public: // Description: // Standard methods for type information and printing. vtkTypeRevisionMacro(vtkPolylineDecimation, vtkPolyDataAlgorithm); void PrintSelf(ostream & os, vtkIndent indent); /** * \brief Instantiate this object with a target reduction of 0.90. */ static vtkPolylineDecimation * New(); /** * \brief Specify the desired reduction in the total number of polygons * (e.g., if TargetReduction is set to 0.9, this filter will try to reduce * the data set to 10% of its original size) */ vtkSetClampMacro(TargetReduction, double, 0.0, 1.0); /** * \brief Get the target reduction */ vtkGetMacro(TargetReduction, double); protected: vtkPolylineDecimation(); ~vtkPolylineDecimation(); int RequestData( vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector); double ComputeError(vtkPolyData *input, int prev, int id, int next); void UpdateError(vtkPolyData *input, const int & iId); int GetPrev(const int & iId); int GetNext(const int & iId); bool Closed; double TargetReduction; std::map< int, double > VertexErrorMap; vtkPriorityQueue *PriorityQueue; private: vtkPolylineDecimation(const vtkPolylineDecimation &); // Not implemented. void operator=(const vtkPolylineDecimation &); // Not implemented. }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkImageBlendWithMask.h0000644000175000017500000001331011667757442027764 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkImageBlendWithMask_h #define __vtkImageBlendWithMask_h #include "vtkThreadedImageAlgorithm.h" #include "vtkLookupTable.h" #include "MegaVTK2Configure.h" /** * \class vtkImageBlendWithMask * \brief TO BE FILLED * \ingroup MegaVTK */ class VTK_RENDERINGADDON2_EXPORT vtkImageBlendWithMask: public vtkThreadedImageAlgorithm { public: /* * \brief Convenient method to access the constructor */ static vtkImageBlendWithMask * New(); vtkTypeRevisionMacro (vtkImageBlendWithMask, vtkThreadedImageAlgorithm); void PrintSelf(ostream & os, vtkIndent indent); /* * \brief Set the LUT to map the mask */ vtkSetObjectMacro (LookupTable, vtkLookupTable); /* * \brief Get the LUT to map the mask */ vtkGetObjectMacro (LookupTable, vtkLookupTable); /* * \brief Set the input to be masked * \param[in] in vtkImageData pointer to the input image */ void SetImageInput(vtkImageData *in); /* * \brief Set the mask to be used * \param[in] in vtkImageData pointer to the input mask */ void SetMaskInput(vtkImageData *in); // Set the input volume 1 for this filter virtual void SetInput1(vtkDataObject *in) { this->SetInput(0, in); } // Set the input volume 2 for this filter virtual void SetInput2(vtkDataObject *in) { this->SetInput(1, in); } protected: vtkImageBlendWithMask(); ~vtkImageBlendWithMask(); vtkLookupTable *LookupTable; virtual int RequestInformation (vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector); virtual void ThreadedRequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *vtkNotUsed(outputVector), vtkImageData ***inData, vtkImageData **outData, int extent[6], int threadId); private: vtkImageBlendWithMask (const vtkImageBlendWithMask &); void operator=(const vtkImageBlendWithMask &); }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3D.cxx0000644000175000017500000006171311667757442026756 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkViewImage3D.h" #include "vtkSmartPointer.h" #include "vtkInteractorStyleImage3D.h" #include "vtkViewImage3DCommand.h" #include "vtkImageAppendComponents.h" #include "vtkImageExtractComponents.h" #include "vtkCamera.h" #include "vtkCommand.h" #include "vtkImageActor.h" #include "vtkImageData.h" #include "vtkImageMapToWindowLevelColors.h" #include "vtkInteractorStyleImage.h" #include "vtkObjectFactory.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkMatrix4x4.h" #include "vtkTransform.h" #include "vtkScalarBarActor.h" #include "vtkOrientationAnnotation.h" #include "vtkCornerAnnotation.h" #include "vtkTextProperty.h" #include "vtkLookupTable.h" #include "vtkMath.h" #include "vtkPlane.h" #include "vtkCutter.h" // #include "vtkQuadricLODActor.h" #include "vtkActor.h" #include "vtkPolyDataMapper.h" #include "vtkPoints.h" #include "vtkIdList.h" #include "vtkOutlineSource.h" #include "vtkMatrixToLinearTransform.h" #include "vtkPointData.h" #include "vtkUnsignedCharArray.h" #include "vtkIntArray.h" #include "vtkImageAccumulate.h" #include "vtkQuadricClustering.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "vtkRenderWindow.h" #include "vtkScalarsToColors.h" #include "vtkColorTransferFunction.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "vtkPlanes.h" #include "vtkPlane.h" vtkCxxRevisionMacro(vtkViewImage3D, "$Revision: 501 $"); vtkStandardNewMacro(vtkViewImage3D); //---------------------------------------------------------------------------- class VTK_RENDERINGADDON2_EXPORT ImageActorCallback : public vtkCommand { public: static ImageActorCallback * New() { return new ImageActorCallback; } void Execute( vtkObject *caller, unsigned long event, void *vtkNotUsed(callData) ) { if ( !this->Actor ) { return; } vtkImageActor *imagecaller = vtkImageActor::SafeDownCast (caller); if ( !imagecaller ) { return; } if ( !imagecaller->GetInput() ) { return; } if ( event == vtkCommand::ModifiedEvent ) { this->Actor->SetInput( imagecaller->GetInput() ); this->Actor->SetInterpolate( imagecaller->GetInterpolate() ); this->Actor->SetOpacity( imagecaller->GetOpacity() ); this->Actor->SetDisplayExtent ( imagecaller->GetDisplayExtent() ); } } //---------------------------------------------------------------------------- vtkImageActor *Actor; protected: ImageActorCallback() : Actor(0) { } ~ImageActorCallback() { } }; //---------------------------------------------------------------------------- /** * */ vtkViewImage3D::vtkViewImage3D() { this->VolumeProperty = vtkVolumeProperty::New(); this->VolumeActor = vtkVolume::New(); this->Callback = vtkImage3DCroppingBoxCallback::New(); this->SmartVolumeMapper3D = vtkSmartVolumeMapper::New(); this->Phantom.push_back( vtkImageActor::New() ); this->Phantom.push_back( vtkImageActor::New() ); this->Phantom.push_back( vtkImageActor::New() ); this->PhantomCallback.push_back( ImageActorCallback::New() ); this->PhantomCallback.push_back( ImageActorCallback::New() ); this->PhantomCallback.push_back( ImageActorCallback::New() ); this->BoundsActor.push_back( vtkActor::New() ); this->BoundsActor.push_back( vtkActor::New() ); this->BoundsActor.push_back( vtkActor::New() ); this->Command = vtkViewImage3DCommand::New(); this->Command->SetVtkImageView3D(this); // the new interactor style this->InteractorStyle3D = vtkInteractorStyleImage3D::New(); this->SetupWidgets(); } //---------------------------------------------------------------------------- /** * */ vtkViewImage3D::~vtkViewImage3D() { // delete all vtk objetcts: this->SmartVolumeMapper3D->Delete(); this->VolumeProperty->Delete(); this->VolumeActor->Delete(); this->Callback->Delete(); this->Cube->Delete(); this->Marker->Delete(); this->Phantom[0]->Delete(); this->Phantom[1]->Delete(); this->Phantom[2]->Delete(); this->PhantomCallback[0]->Delete(); this->PhantomCallback[1]->Delete(); this->PhantomCallback[2]->Delete(); this->BoundsActor[0]->Delete(); this->BoundsActor[1]->Delete(); this->BoundsActor[2]->Delete(); this->Command->Delete(); this->InteractorStyle3D->Delete(); CleanVolumeRenderingVectors(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * */ void vtkViewImage3D::SetupWidgets() { // Create an annotated cube actor (directions) this->Cube = vtkAnnotatedCubeActor::New(); this->Cube->SetXPlusFaceText( this->DirectionAnnotationMatrix[0][1].c_str() ); this->Cube->SetXMinusFaceText( this->DirectionAnnotationMatrix[0][0].c_str() ); this->Cube->SetYPlusFaceText( this->DirectionAnnotationMatrix[1][1].c_str() ); this->Cube->SetYMinusFaceText( this->DirectionAnnotationMatrix[1][0].c_str() ); this->Cube->SetZPlusFaceText( this->DirectionAnnotationMatrix[2][1].c_str() ); this->Cube->SetZMinusFaceText( this->DirectionAnnotationMatrix[2][0].c_str() ); this->Cube->SetZFaceTextRotation(90); this->Cube->SetFaceTextScale(0.65); this->Cube->GetCubeProperty()->SetColor(0.5, 1, 1); this->Cube->GetTextEdgesProperty()->SetLineWidth(1); this->Cube->GetTextEdgesProperty()->SetDiffuse(0); this->Cube->GetTextEdgesProperty()->SetAmbient(1); this->Cube->GetTextEdgesProperty()->SetColor(0.18, 0.28, 0.23); this->Cube->SetTextEdgesVisibility (1); this->Cube->SetCubeVisibility(1); this->Cube->SetFaceTextVisibility(1); this->Cube->GetXPlusFaceProperty()->SetColor (1, 0, 0); this->Cube->GetXPlusFaceProperty()->SetInterpolationToFlat(); this->Cube->GetXMinusFaceProperty()->SetColor (1, 0, 0); this->Cube->GetXMinusFaceProperty()->SetInterpolationToFlat(); this->Cube->GetYPlusFaceProperty()->SetColor (0, 1, 0); this->Cube->GetYPlusFaceProperty()->SetInterpolationToFlat(); this->Cube->GetYMinusFaceProperty()->SetColor (0, 1, 0); this->Cube->GetYMinusFaceProperty()->SetInterpolationToFlat(); this->Cube->GetZPlusFaceProperty()->SetColor (0, 0, 1); this->Cube->GetZPlusFaceProperty()->SetInterpolationToFlat(); this->Cube->GetZMinusFaceProperty()->SetColor (0, 0, 1); this->Cube->GetZMinusFaceProperty()->SetInterpolationToFlat(); this->Marker = vtkOrientationMarkerWidget::New(); this->Marker->SetOutlineColor (0.93, 0.57, 0.13); this->Marker->SetOrientationMarker (this->Cube); this->Marker->SetViewport (0.0, 0.05, 0.15, 0.15); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * */ void vtkViewImage3D::Render() { if ( this->FirstRender ) { // Initialize the size if not set yet vtkImageData *input = this->GetInput(); if ( this->RenderWindow->GetSize()[0] == 0 && input ) { if ( this->Renderer ) { this->ResetCamera(); } this->FirstRender = 0; } } if ( this->GetInput() ) { this->RenderWindow->Render(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * */ void vtkViewImage3D::SetVolumeRenderingOff() { // triplanar rendering on //SetTriPlanarRenderingOn(); CleanVolumeRenderingVectors(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage3D::CleanVolumeRenderingVectors() { //this->VolumeActor->SetVisibility (false); for(unsigned int i=0; iSetVisibility(false); this->Renderer->RemoveViewProp(m_VolumeActors[i]); } //delete everything... for(unsigned int i=0; iDelete(); m_VolumeMappers[i]->Delete(); m_VolumeProperties[i]->Delete(); } m_VolumeActors.clear(); m_VolumeMappers.clear(); m_VolumeProperties.clear(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * */ void vtkViewImage3D::SetVolumeRenderingOn(const std::vector& iImages, const std::vector& iOpacities) { // triplanar rendering off //SetTriPlanarRenderingOff(); int *size = this->GetInput()->GetDimensions(); if ( ( size[0] < 2 ) || ( size[1] < 2 ) || ( size[2] < 2 ) ) { vtkWarningMacro (<< "Cannot do volume rendering for a single slice, skipping" << endl); return; } CleanVolumeRenderingVectors(); //for(unsigned int j=0; jCroppingOn(); smartVolumeMapper3D->SetCroppingRegionFlagsToSubVolume(); smartVolumeMapper3D->SetCroppingRegionFlags (0x7ffdfff); m_VolumeMappers.push_back(smartVolumeMapper3D); // PROPERTY vtkVolumeProperty* volumeProperty = vtkVolumeProperty::New(); if(iOpacities.size() == 1) { volumeProperty->SetScalarOpacity(0, iOpacities[0]); volumeProperty->SetScalarOpacity(1, iOpacities[0]); volumeProperty->SetScalarOpacity(2, iOpacities[0]); } else { vtkSmartPointer opacityFunction = vtkSmartPointer::New(); opacityFunction->AddPoint (0, 0.0); opacityFunction->AddPoint (255, 1.0); volumeProperty->SetScalarOpacity(0, opacityFunction); volumeProperty->SetScalarOpacity(1, opacityFunction); volumeProperty->SetScalarOpacity(2, opacityFunction); } // one dataset-1 tf, not 1 tf for each component volumeProperty->IndependentComponentsOff(); volumeProperty->SetInterpolationTypeToLinear(); //volumeProperty->SetScalarOpacityUnitDistance(1.0); volumeProperty->ShadeOff(); m_VolumeProperties.push_back(volumeProperty); // ACTOR vtkVolume* volumeActor = vtkVolume::New(); volumeActor->SetProperty (volumeProperty); volumeActor->SetMapper (smartVolumeMapper3D); volumeActor->PickableOff(); volumeActor->DragableOff(); volumeActor->SetVisibility (true); m_VolumeActors.push_back(volumeActor); // get the index of the first non-NULL component int i(0); if(iOpacities.size() == 1) { for(i=0; i<3;++i) { double range[2]; iImages[0]->GetPointData()->GetScalars()->GetRange(range,i); if(range[1]>0) { break; } } } else { for(i=0; i<3;++i) { double range[2]; this->GetInput()->GetPointData()->GetScalars()->GetRange(range,i); if(range[1]>0) { break; } } } // mix components // dont't really get the point but has sth to do with the alpha component // create a "FAKE" 4th alpha channel...?? vtkImageExtractComponents* extComp = vtkImageExtractComponents::New(); if(iOpacities.size() == 1) { extComp->SetInput(iImages[0]); } else { extComp->SetInput(this->GetInput()); } extComp->SetComponents(i); extComp->Update(); vtkImageAppendComponents* addComp = vtkImageAppendComponents::New(); if(iOpacities.size() == 1) { addComp->AddInput(iImages[0]); } else { addComp->AddInput(this->GetInput()); } addComp->AddInput( extComp->GetOutput() ); addComp->Update(); for(unsigned int j=0; jDelete(); } extComp->Delete(); // add output to mapper smartVolumeMapper3D->SetInput( addComp->GetOutput() ); addComp->Delete(); this->Renderer->AddViewProp (volumeActor); //} } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * */ void vtkViewImage3D::SetTriPlanarRenderingOn() { this->VolumeActor->SetVisibility(false); for ( int i = 0; i < 3; i++ ) { this->Phantom[i]->SetVisibility(true); this->BoundsActor[i]->SetVisibility(true); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage3D::SetTriPlanarRenderingOff() { this->VolumeActor->SetVisibility(true); for ( int i = 0; i < 3; i++ ) { this->Phantom[i]->SetVisibility(false); this->BoundsActor[i]->SetVisibility(false); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * * @param i * @param input * @param in_bounds */ void vtkViewImage3D::Add2DPhantom(const unsigned int & i, vtkImageActor *input, vtkPolyData *in_bounds) { if ( i >= 3 ) { return; } vtkRenderer *ren = this->GetRenderer(); if ( ren ) { ren->RemoveActor(this->Phantom[i]); this->Phantom[i]->SetInput ( input->GetInput() ); this->Phantom[i]->SetDisplayExtent ( input->GetDisplayExtent() ); this->Phantom[i]->SetUserMatrix ( input->GetUserMatrix() ); this->PhantomCallback[i]->Actor = this->Phantom[i]; input->AddObserver (vtkCommand::ModifiedEvent, this->PhantomCallback[i]); ren->AddActor (this->Phantom[i]); /** IMPORTANT NOTE Adding a 2D actor in the 3D scene should be as simple as the next line instead of the code above... Unfortunately it does not seem to work properly. But this is something we should investigate in because it would be much simpler */ // this->GetRenderer()->AddActor (input); if ( in_bounds ) { ren->RemoveActor(this->BoundsActor[i]); vtkSmartPointer< vtkPolyDataMapper > bounds_mapper = vtkSmartPointer< vtkPolyDataMapper >::New(); bounds_mapper->SetInput(in_bounds); bounds_mapper->StaticOn(); this->BoundsActor[i]->SetMapper(bounds_mapper); this->BoundsActor[i]->GetProperty()->SetRepresentationToWireframe(); this->BoundsActor[i]->GetProperty()->SetLineWidth(2.); ren->AddActor(this->BoundsActor[i]); } } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage3D::SetBoundsActorsVisibility(bool iVisibility) { vtkstd::vector< vtkActor * >::iterator BoundsActorIterator = BoundsActor.begin(); while ( BoundsActorIterator != BoundsActor.end() ) { ( *BoundsActorIterator )->SetVisibility(iVisibility); ++BoundsActorIterator; } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * */ void vtkViewImage3D::InstallPipeline() { if ( this->RenderWindow && this->Renderer ) { this->RenderWindow->AddRenderer(this->Renderer); } if ( this->Interactor ) { // Add observers this->InteractorStyle3D->AddObserver( vtkViewImage3DCommand::MeshPickingEvent, this->Command); this->InteractorStyle3D->AddObserver( vtkViewImage3DCommand::BoxPickingEvent, this->Command); this->Interactor->SetInteractorStyle(this->InteractorStyle3D); this->Interactor->SetRenderWindow(this->RenderWindow); //this->PlaneWidget->SetInteractor ( this->Interactor ); this->Marker->SetInteractor (this->Interactor); this->Marker->On(); this->Marker->InteractiveOff (); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * * @param dataset * @param property * @param intersection * @param iDataVisibility * @return */ // vtkQuadricLODActor* vtkActor * vtkViewImage3D::AddDataSet(vtkDataSet *dataset, vtkProperty *property, const bool & intersection, const bool & iDataVisibility) { (void)intersection; if ( !this->Renderer ) { return NULL; } vtkCamera *cam = this->Renderer->GetActiveCamera(); if ( !cam ) { return NULL; } vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInput( dynamic_cast< vtkPolyData * >( dataset ) ); mapper->SetScalarVisibility(iDataVisibility); mapper->StaticOn(); mapper->ImmediateModeRenderingOn(); vtkActor *actor3d = vtkActor::New(); actor3d->SetMapper(mapper); if ( property ) { // Generates bug in visu //actor3d->SetProperty( property ); actor3d->GetProperty()->BackfaceCullingOn(); actor3d->GetProperty()->SetColor( property->GetColor() ); actor3d->GetProperty()->SetOpacity( property->GetOpacity() ); actor3d->GetProperty()->SetLineWidth(this->IntersectionLineWidth); } return actor3d; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * * @param matrix */ void vtkViewImage3D::SetOrientationMatrix(vtkMatrix4x4 *matrix) { this->Superclass::SetOrientationMatrix (matrix); this->VolumeActor->SetUserMatrix (matrix); //this->BoxWidget->SetOrientationMatrix (matrix); // this->PlaneWidget->SetTransform (transform); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * */ vtkInteractorStyleImage3D * vtkViewImage3D::GetInteractorStyle3D() { return this->InteractorStyle3D; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage3D::ComputeDistances(double *n, double *origin) { // go through all actors // relative distance from point to plane vtkActorCollection *test = this->Renderer->GetActors(); test->InitTraversal(); vtkProp3D *prop_temp = test->GetNextActor(); while ( prop_temp ) { double *point = prop_temp->GetCenter(); double distance = n[0] * ( point[0] - origin[0] ) + n[1] * ( point[1] - origin[1] ) + n[2] * ( point[2] - origin[2] ); bool state; if ( distance < 0 ) { state = false; } else { state = true; } this->GetInteractorStyle3D()->SetCurrentProp(prop_temp); this->GetInteractorStyle3D()->SetCurrentState(state); this->InvokeEvent(vtkViewImage3DCommand::VisibilityUpdatedEvent); prop_temp = test->GetNextActor(); } // emit signal to say to render this->InvokeEvent(vtkViewImage3DCommand::UpdateRenderEvent); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage3D::ComputeDistancesToSquare(vtkPlanes *planes) { // go through all actors // relative distance from point to plane vtkActorCollection *test = this->Renderer->GetActors(); test->InitTraversal(); vtkProp3D *prop_temp = test->GetNextActor(); while ( prop_temp ) { double *point(prop_temp->GetCenter()); bool show(true); for ( int i = 0; i < 6; ++i ) { double *n = planes->GetPlane(i)->GetNormal(); double *origin = planes->GetPlane(i)->GetOrigin(); double distance = n[0] * ( point[0] - origin[0] ) + n[1] * ( point[1] - origin[1] ) + n[2] * ( point[2] - origin[2] ); if ( distance > 0 ) { show = false; break; } } this->GetInteractorStyle3D()->SetCurrentProp(prop_temp); this->GetInteractorStyle3D()->SetCurrentState(show); this->InvokeEvent(vtkViewImage3DCommand::VisibilityUpdatedEvent); prop_temp = test->GetNextActor(); } planes->Delete(); // emit signal to say to render this->InvokeEvent(vtkViewImage3DCommand::UpdateRenderEvent); } //---------------------------------------------------------------------------- std::vector< vtkProp3D * > vtkViewImage3D:: GetPlanesActors() { std::vector planeActors; for( size_t i =0; i < this->BoundsActor.size(); i++ ) { planeActors.push_back(dynamic_cast(this->BoundsActor[i])); } for(size_t i =0; i < this->Phantom.size(); i++) { planeActors.push_back(dynamic_cast(this->Phantom[i])); } return planeActors; } GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkInteractorStyleImage2D.h0000644000175000017500000001515011667757442030615 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _vtk_InteractorStyleImage2D_h_ #define _vtk_InteractorStyleImage2D_h_ #include #include "MegaVTK2Configure.h" #include "vtkActor.h" #include "vtkProp.h" #include #define VTKIS_SLICE_MOVE 5051 /** * \class vtkInteractorStyleImage2D * \ingroup MegaVTK * \brief Define the interactor behavior withing a vtkImage2D. * 4 modes (Default, Zoom, Pan and Pick) */ class VTK_RENDERINGADDON2_EXPORT vtkInteractorStyleImage2D: public vtkInteractorStyleImage { public: /** * \brief Convenient method to access the constructor */ static vtkInteractorStyleImage2D * New(); vtkTypeRevisionMacro (vtkInteractorStyleImage2D, vtkInteractorStyleImage); //BTX enum InteractionTypeIds { InteractionTypeWindowLevel = 0, InteractionTypeZoom, InteractionTypePan, InteractionTypeContourPicking, InteractionTypeDefault }; virtual void OnMouseMove(); virtual void OnLeftButtonDown(); virtual void OnLeftButtonUp(); virtual void OnMiddleButtonDown(); virtual void OnMiddleButtonUp(); virtual void OnRightButtonDown(); virtual void OnRightButtonUp(); virtual void OnMouseWheelForward(); virtual void OnMouseWheelBackward(); virtual void OnChar(); virtual void OnKeyDown(); virtual void OnKeyUp(); virtual void OnKeyPress(); virtual void OnKeyRelease(); virtual void StartSliceMove(); virtual void SliceMove(); virtual void EndSliceMove(); virtual void DefaultMoveAction(); // Different modes /** * \brief Start the Default Mode */ void SetDefaultMode(); /** * \brief Start the Zoom Mode */ void SetZoomMode(); /** * \brief Start the Pan Mode */ void SetPanMode(); /** * \brief Start the Pick Mode */ void SetPickMode(); /** * \brief Draw a bounding box around the actor which is pointed by the cursor */ void HighlightCurrentActor(); vtkGetMacro(SliceStep, int); int * GetRequestedPosition(void) { return this->RequestedPosition; } /** * \brief Return the actor which is pointed by the cursor */ vtkProp * GetCurrentProp(); /* * \brief Synchronize the views * \param[in] iSynchronize Enable/disable synchronization */ void SynchronizeViews( bool iSynchronize); /* * \brief Add plane actors to be able to get rid of them while picking, * wireframe mode. and surface mode * \param[in] iSynchronize Enable/disable synchronization */ void SetPlanesActors( std::vector< vtkProp3D * > iBounds); protected: vtkInteractorStyleImage2D(); ~vtkInteractorStyleImage2D(); int SliceStep; int *RequestedPosition; private: vtkInteractorStyleImage2D(const vtkInteractorStyleImage2D &); // Not // implemented. void operator=(const vtkInteractorStyleImage2D &); // Not // implemented. unsigned int m_Mode; bool m_LeftButtonDown; bool m_SynchronizeViews; std::vector< vtkProp3D * > m_PlanesActors; }; #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkOrientedBoxWidget.cxx0000644000175000017500000002147511667757442030301 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkOrientedBoxWidget.h" #include "vtkMatrixToLinearTransform.h" #include "vtkObjectFactory.h" #include "vtkMatrix4x4.h" #include "vtkPoints.h" #include "vtkActor.h" #include "vtkAssemblyNode.h" #include "vtkAssemblyPath.h" #include "vtkCallbackCommand.h" #include "vtkCamera.h" #include "vtkCellArray.h" #include "vtkCellPicker.h" #include "vtkDoubleArray.h" #include "vtkFloatArray.h" #include "vtkMath.h" #include "vtkObjectFactory.h" #include "vtkPlanes.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkProperty.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkSphereSource.h" #include "vtkTransform.h" vtkCxxRevisionMacro(vtkOrientedBoxWidget, "$Revision: 490 $"); vtkStandardNewMacro(vtkOrientedBoxWidget); //---------------------------------------------------------------------------- vtkOrientedBoxWidget::vtkOrientedBoxWidget() { this->OrientationMatrix = vtkMatrix4x4::New(); this->OrientationMatrix->Identity(); this->InvertedOrientationMatrix = vtkMatrix4x4::New(); this->InvertedOrientationMatrix->Identity(); } //---------------------------------------------------------------------------- vtkOrientedBoxWidget::~vtkOrientedBoxWidget() { this->OrientationMatrix->Delete(); this->InvertedOrientationMatrix->Delete(); } //---------------------------------------------------------------------------- void vtkOrientedBoxWidget::SetOrientationMatrix(vtkMatrix4x4 *matrix) { if ( matrix == this->OrientationMatrix ) { return; } if ( this->OrientationMatrix ) { this->OrientationMatrix->UnRegister (this); this->OrientationMatrix = NULL; } this->OrientationMatrix = matrix; if ( this->OrientationMatrix ) { // move all the actors according to the user-matrix this->HexActor->SetUserMatrix (matrix); this->HexFace->SetUserMatrix (matrix); this->HexOutline->SetUserMatrix (matrix); for ( unsigned int i = 0; i < 7; i++ ) { this->Handle[i]->SetUserMatrix (matrix); } // initialize inverse matrix vtkMatrix4x4::Invert (this->OrientationMatrix, this->InvertedOrientationMatrix); } } //---------------------------------------------------------------------------- void vtkOrientedBoxWidget::OnMouseMove() { // See whether we're active if ( this->State == vtkBoxWidget::Outside || this->State == vtkBoxWidget::Start ) { return; } int X = this->Interactor->GetEventPosition()[0]; int Y = this->Interactor->GetEventPosition()[1]; // Do different things depending on state // Calculations everybody does double focalPoint[4], pickPoint[4], prevPickPoint[4]; double z, vpn[3]; vtkCamera *camera = this->CurrentRenderer->GetActiveCamera(); if ( !camera ) { return; } // Compute the two points defining the motion vector this->ComputeWorldToDisplay(this->LastPickPosition[0], this->LastPickPosition[1], this->LastPickPosition[2], focalPoint); z = focalPoint[2]; this->ComputeDisplayToWorld( static_cast< double >( this->Interactor->GetLastEventPosition()[0] ), static_cast< double >( this->Interactor->GetLastEventPosition()[1] ), z, prevPickPoint); this->ComputeDisplayToWorld(static_cast< double >( X ), static_cast< double >( Y ), z, pickPoint); // multiply pick points by the inverted orientation matrix // to recover the true movement to apply this->InvertedOrientationMatrix->MultiplyPoint (prevPickPoint, prevPickPoint); this->InvertedOrientationMatrix->MultiplyPoint (pickPoint, pickPoint); // Process the motion if ( this->State == vtkBoxWidget::Moving ) { // Okay to process if ( this->CurrentHandle ) { if ( this->RotationEnabled && this->CurrentHandle == this->HexFace ) { camera->GetViewPlaneNormal(vpn); this->Rotate(X, Y, prevPickPoint, pickPoint, vpn); } else if ( this->TranslationEnabled && this->CurrentHandle == this->Handle[6] ) { this->Translate(prevPickPoint, pickPoint); } else if ( this->TranslationEnabled && this->ScalingEnabled ) { if ( this->CurrentHandle == this->Handle[0] ) { this->MoveMinusXFace(prevPickPoint, pickPoint); } else if ( this->CurrentHandle == this->Handle[1] ) { this->MovePlusXFace(prevPickPoint, pickPoint); } else if ( this->CurrentHandle == this->Handle[2] ) { this->MoveMinusYFace(prevPickPoint, pickPoint); } else if ( this->CurrentHandle == this->Handle[3] ) { this->MovePlusYFace(prevPickPoint, pickPoint); } else if ( this->CurrentHandle == this->Handle[4] ) { this->MoveMinusZFace(prevPickPoint, pickPoint); } else if ( this->CurrentHandle == this->Handle[5] ) { this->MovePlusZFace(prevPickPoint, pickPoint); } } } } else if ( this->ScalingEnabled && this->State == vtkBoxWidget::Scaling ) { this->Scale(prevPickPoint, pickPoint, X, Y); } // Interact, if desired this->EventCallbackCommand->SetAbortFlag(1); this->InvokeEvent(vtkCommand::InteractionEvent, NULL); this->Interactor->Render(); }GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2DCollection.h0000644000175000017500000003344111667757442030413 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _vtkViewImage2DCollection_h_ #define _vtkViewImage2DCollection_h_ #include "vtkCollection.h" #include "vtkCommand.h" #include "vtkViewImage2D.h" #include "MegaVTK2Configure.h" #include /** This macro can be useful as we frequently set an instance this way, meaning unregistering previously set instance, registering given instance, and call a modified event. However this might be not the best place to define it... */ //BTX #define vtkSyncSetMacro(name, type, base) \ virtual void SyncSet ## name (type _arg) \ { \ this->InitTraversal(); \ base *item = this->GetNextItem(); \ while ( item ) \ { \ item->Set ## name (_arg); \ item = this->GetNextItem(); \ } \ } ///ETX ///BTX #define vtkSyncSetObjectMacro(name, type, base) \ virtual void SyncSet ## name (type * _arg) \ { \ this->InitTraversal(); \ base *item = this->GetNextItem(); \ while ( item ) \ { \ item->Set ## name (_arg); \ item = this->GetNextItem(); \ } \ } ///ETX class vtkScalarBarActor; class vtkLookupTable; class vtkTextProperty; class vtkCornerAnnotation; class vtkOrientationAnnotation; class vtkPlane; class vtkActor; class vtkDataSet; class vtkPolyData; class vtkProperty; class vtkDataSetCollection; class vtkMatrixToLinearTransform; class vtkViewImage2DCollectionCommand; /** * \class vtkViewImage2DCollection * \ingroup MegaVTK * \brief Manage a collection of 2D views */ class VTK_RENDERINGADDON2_EXPORT vtkViewImage2DCollection:public vtkCollection { public: /** * \brief Convenient method to access the constructor. */ static vtkViewImage2DCollection * New(); vtkTypeRevisionMacro(vtkViewImage2DCollection, vtkCollection); /* * \bief Get the next vtkViewImage2D in the list. Return NULL when at the end of * the list * \return vtkViewImage2D pointer to the next vtkViewImage2D in the collection */ vtkViewImage2D * GetNextItem() { return static_cast< vtkViewImage2D * >( this->GetNextItemAsObject() ); } /* * \bief Get the next vtkViewImage2D2D in the list. Return NULL when at the end of * the list * \param[in] i index of the element we are looking for in the collection * \return vtkViewImage2D pointer to the selected element */ vtkViewImage2D * GetItem(int i) { return static_cast< vtkViewImage2D * >( this->GetItemAsObject(i) ); } /* * \bief Add an object to the list. Does not prevent duplicate entries. * \param[in] vtkViewImage2D pointer to the element to be added in the collection */ void AddItem(vtkViewImage2D *); /* * \bief Replace the i'th item in the collection with another 2D image * \param[in] i index of the element we want to remplace * \param[in] vtkViewImage2D pointer to the element to be added in the collection */ void ReplaceItem(int i, vtkViewImage2D *); /* * \brief Remove the i'th item in the list. * \param[in] i index of the element we want to removed * * Be careful if using this function during traversal of the list using * GetNextItemAsObject (or GetNextItem in derived class). The list WILL * be shortened if a valid index is given! If this->Current is equal to the * element being removed, have it point to then next element in the list. */ void RemoveItem(int i); /* * \brief Remove an object from the list. * \param[in] vtkViewImage2D pointer to the element to be removed * Removes the first object found, not * all occurrences. If no object found, list is unaffected. See warning * in description of RemoveItem(int). */ void RemoveItem(vtkViewImage2D *); /* * \brief Remove all objects from the collection. */ void RemoveAllItems(); /* * \brief Initialize the planes actors in all the views */ void Initialize(); /* * \brief Initialize the the observers. */ void InitializeAllObservers(); /* * \brief Get the callbacks associated to the collection * \return vtkViewImage2DCollectionCommand pointer */ vtkGetObjectMacro (Command, vtkViewImage2DCollectionCommand); /* * \brief Get the ExtraRenderWindow associated to the collection (3D) * \return vtkRenderWindow pointer to the ExtraRenderWindow */ vtkGetObjectMacro (ExtraRenderWindow, vtkRenderWindow); /* * \brief Add an extra window of a different type to the collection * \param[in] wim Render Window associated to the extra window */ void SetExtraRenderWindow(vtkRenderWindow *win) { this->ExtraRenderWindow = win; } vtkSyncSetMacro (Slice, int, vtkViewImage2D); vtkSyncSetMacro (SliceOrientation, int, vtkViewImage2D); vtkSyncSetMacro (ShowAnnotations, bool, vtkViewImage2D); vtkSyncSetMacro (ShowScalarBar, bool, vtkViewImage2D); vtkSyncSetMacro (ColorWindow, double, vtkViewImage2D); vtkSyncSetMacro (ColorLevel, double, vtkViewImage2D); vtkSyncSetObjectMacro (OrientationMatrix, vtkMatrix4x4, vtkViewImage2D); vtkSyncSetObjectMacro (LookupTable, vtkLookupTable, vtkViewImage2D); vtkSyncSetObjectMacro (TextProperty, vtkTextProperty, vtkViewImage2D); vtkSyncSetObjectMacro (Input, vtkImageData, vtkViewImage2D); vtkSyncSetObjectMacro (InputConnection, vtkAlgorithmOutput, vtkViewImage2D); vtkSyncSetObjectMacro (Size, int, vtkViewImage2D); vtkSyncSetObjectMacro (Position, int, vtkViewImage2D); vtkSyncSetObjectMacro (WorldCoordinates, double, vtkViewImage2D); /// Description: Synchronize interpolate between views vtkSyncSetMacro (Interpolate, int, vtkViewImage2D); /// Description: Synchronize reset window level between views virtual void SyncResetWindowLevel(void); void SyncUpdateWindowLevel(void); /// Description: Synchronize reset camera between views virtual void SyncResetCamera(void); /// Description: Synchronize render between views virtual void SyncRender(); /// Description: Synchronize render between views except iV ///(which is already up to date) virtual void SyncRender( vtkViewImage2D* iV ); /// Description: Synchronize reset between views virtual void SyncReset(void); /// Description: Synchronize interactor start between views virtual void SyncStart(void); // Decide weither or not the collection will link interactions /// Description: link slice flag vtkGetMacro (LinkSliceMove, unsigned int); /// Description: link slice flag virtual void SetLinkSliceMove(unsigned int v); /// Description: link slice flag vtkBooleanMacro (LinkSliceMove, unsigned int); /// Description: link color window flag vtkGetMacro (LinkColorWindowLevel, unsigned int); /// Description: link color window flag virtual void SetLinkColorWindowLevel(unsigned int v); /// Description: link color window flag vtkBooleanMacro (LinkColorWindowLevel, unsigned int); /// Description: link reset color window flag vtkGetMacro (LinkResetWindowLevel, unsigned int); /// Description: link reset color window flag virtual void SetLinkResetWindowLevel(unsigned int v); /// Description: link reset color window flag vtkBooleanMacro (LinkResetWindowLevel, unsigned int); /// Description: link reset viewer flag vtkGetMacro (LinkResetViewer, unsigned int); /// Description: link reset viewer flag virtual void SetLinkResetViewer(unsigned int v); /// Description: link reset viewer flag vtkBooleanMacro (LinkResetViewer, unsigned int); /// Description: link requested position (double click) flag vtkGetMacro (LinkRequestedPosition, unsigned int); /// Description: link requested position (double click) flag virtual void SetLinkRequestedPosition(unsigned int v); /// Description: link requested position (double click) flag vtkBooleanMacro (LinkRequestedPosition, unsigned int); /// Description: link camera flag vtkGetMacro (LinkCamera, unsigned int); /// Description: link camera flag virtual void SetLinkCamera(unsigned int v); /// Description: link camera flag vtkBooleanMacro (LinkCamera, unsigned int); /// Description: link position flag vtkGetMacro (LinkPosition, unsigned int); /// Description: link position flag virtual void SetLinkPosition(unsigned int v); /// Description: link position flag vtkBooleanMacro (LinkPosition, unsigned int); /// Description: show axes (view intersections) flag virtual void SetShowAxes(unsigned int v); /// Description: show axes (view intersections) flag vtkBooleanMacro (ShowAxes, unsigned int); /// Description: show axes (view intersections) flag vtkGetMacro (ShowAxes, unsigned int); void SyncSetBackground(double *rgb); void SyncPan(); void SyncSetZoomAndParallelScale(double Zoom, double ParallelScale); /** * \brief Set the visibility of the plane actor. * \param[in] iVisibility */ void SetSplinePlaneActorsVisibility(bool iVisibility); /** * \brief Change Interaction mode of the collection to DefaultMode() */ void EnableDefaultInteractionMode(); /** * \brief Change Interaction mode of the collection to ZoomMode() */ void EnableZoomInteractionMode(); /** * \brief Change Interaction mode of the collection to ZoomMode() */ void EnablePanInteractionMode(); /** * \brief Change Interaction mode of the collection to ContourPickingMode() */ void EnableContourPickingMode(); /** * \brief Synchronize the 2d views * \param[in] iSynchronize enable/disable synchronization */ void SynchronizeViews( bool iSynchronize); /** * \brief Get the plane actors */ std::vector< vtkProp3D * > GetPlanesActors(); protected: vtkViewImage2DCollection(); ~vtkViewImage2DCollection(); vtkViewImage2DCollectionCommand *Command; vtkRenderWindow * ExtraRenderWindow; std::vector< vtkProp3D * > PlanesActors; unsigned int LinkSliceMove; unsigned int LinkColorWindowLevel; unsigned int LinkResetWindowLevel; unsigned int LinkResetViewer; unsigned int LinkRequestedPosition; unsigned int LinkCamera; unsigned int LinkPosition; unsigned int ShowAxes; }; #endif /* _vtkViewImage2DCollection_h_ */ GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2D.cxx0000644000175000017500000012214111667757442026746 0ustar mathieumathieu/*======================================================================== Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkViewImage2D.h" #include "vtkSmartPointer.h" #include "vtkCamera.h" #include "vtkCommand.h" #include "vtkImageActor.h" #include "vtkImageData.h" #include "vtkImageMapToWindowLevelColors.h" #include "vtkInteractorStyleImage.h" #include "vtkObjectFactory.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkMatrix4x4.h" #include "vtkTransform.h" #include "vtkScalarBarActor.h" #include "vtkOrientationAnnotation.h" #include "vtkCornerAnnotation.h" #include "vtkTextProperty.h" #include "vtkLookupTable.h" #include "vtkMath.h" #include "vtkPlane.h" #include "vtkPlaneCutter.h" // #include "vtkQuadricLODActor.h" #include "vtkActor.h" #include "vtkPolyDataMapper.h" #include "vtkPoints.h" #include "vtkIdList.h" #include "vtkOutlineSource.h" #include "vtkMatrixToLinearTransform.h" #include "vtkPointData.h" #include "vtkUnsignedCharArray.h" #include "vtkIntArray.h" #include "vtkImageAccumulate.h" #include "vtkInteractorStyleImage2D.h" #include "vtkViewImage2DCommand.h" #include "vtkProperty.h" #include #include #include #include #include #include #include #include #include #include #include vtkCxxRevisionMacro(vtkViewImage2D, "$Revision: 541 $"); vtkStandardNewMacro(vtkViewImage2D); //---------------------------------------------------------------------------- vtkViewImage2D::vtkViewImage2D() { this->ConventionMatrix = vtkMatrix4x4::New(); this->SliceImplicitPlane = vtkSmartPointer< vtkPlane >::New(); this->SlicePlane = vtkPolyData::New(); this->Command = vtkViewImage2DCommand::New(); this->OrientationAnnotation = vtkOrientationAnnotation::New(); this->Command->SetViewer(this); this->SliceImplicitPlane->SetOrigin(0, 0, 0); this->SliceImplicitPlane->SetNormal(0, 0, 1); this->ViewConvention = vtkViewImage2D::VIEW_CONVENTION_RADIOLOGICAL; this->ViewOrientation = vtkViewImage2D::VIEW_ORIENTATION_AXIAL; this->ViewCenter[0] = this->ViewCenter[1] = this->ViewCenter[2] = 0; this->ConventionMatrix->Zero(); this->ConventionMatrix->SetElement(2, 0, 1); this->ConventionMatrix->SetElement(2, 1, 1); this->ConventionMatrix->SetElement(1, 2, -1); this->ConventionMatrix->SetElement(0, 3, 1); this->ConventionMatrix->SetElement(1, 3, -1); this->ConventionMatrix->SetElement(2, 3, -1); this->OrientationAnnotation->SetTextProperty(this->TextProperty); this->Renderer->AddViewProp (this->OrientationAnnotation); this->CursorGenerator = vtkCursor2D::New(); this->CursorGenerator->AllOff(); this->CursorGenerator->AxesOn(); this->CursorGenerator->SetRadius(3); this->CursorGenerator->SetModelBounds (-40, 40, -40, 40, 0, 0); this->Cursor = vtkPointHandleRepresentation2D::New(); this->Cursor->ActiveRepresentationOff(); this->Cursor->SetCursorShape( this->CursorGenerator->GetOutput() ); this->Cursor->GetProperty()->SetColor (0.9, 0.9, 0.1); this->Cursor->SetVisibility (0); this->Renderer->AddViewProp(this->Cursor); this->ShowAnnotationsOn(); this->InitializeSlicePlane(); this->Zoom = 1.; this->Slice = -1; } //---------------------------------------------------------------------------- vtkViewImage2D:: ~vtkViewImage2D() { this->ConventionMatrix->Delete(); this->SlicePlane->Delete(); this->Command->Delete(); this->OrientationAnnotation->Delete(); this->Cursor->Delete(); this->CursorGenerator->Delete(); } //---------------------------------------------------------------------------- void vtkViewImage2D::SetViewConvention(int convention) { if ( ( convention < vtkViewImage2D::VIEW_CONVENTION_RADIOLOGICAL ) || convention == this->ViewConvention ) { return; } this->ViewConvention = convention; this->ConventionMatrix->SetElement(2, 0, 1); this->ConventionMatrix->SetElement(2, 1, 1); this->ConventionMatrix->SetElement(1, 2, -1); int x_watcher, y_watcher, z_watcher; switch ( convention ) { default: case vtkViewImage2D::VIEW_CONVENTION_RADIOLOGICAL: { x_watcher = 1; y_watcher = -1; z_watcher = -1; break; } case vtkViewImage2D::VIEW_CONVENTION_NEUROLOGICAL: { x_watcher = 1; y_watcher = 1; z_watcher = 1; break; } ///\todo why not adding cardiologic conventions with oblique points of // view ? /// actually we can't: oblique point of view implies resampling data: loss // of /// data... and we don't want that, do we ? } this->ConventionMatrix->SetElement(0, 3, x_watcher); this->ConventionMatrix->SetElement(1, 3, y_watcher); this->ConventionMatrix->SetElement(2, 3, z_watcher); this->UpdateOrientation(); } //---------------------------------------------------------------------------- void vtkViewImage2D::SetShowAnnotations(const int & iShowAnnotations) { this->Superclass::SetShowAnnotations (iShowAnnotations); this->OrientationAnnotation->SetVisibility (iShowAnnotations); } //---------------------------------------------------------------------------- void vtkViewImage2D::SetViewOrientation(int orientation) { ///\todo: in terms of view orientation here we can add some cardiac specific: /// short axis, long axis, and 4-chambers !!! exiting ! if ( ( orientation < vtkViewImage2D::VIEW_ORIENTATION_SAGITTAL ) || orientation == this->ViewOrientation ) { return; } this->ViewOrientation = orientation; unsigned int sliceorientation = 2; double dot = 0; for ( unsigned int i = 0; i < 3; i++ ) { if ( dot < fabs( this->GetOrientationMatrix()->GetElement(orientation, i) ) ) { dot = fabs( this->GetOrientationMatrix()->GetElement(orientation, i) ); sliceorientation = i; } } this->SetSliceOrientation(sliceorientation); } //---------------------------------------------------------------------------- void vtkViewImage2D::SetOrientationMatrix(vtkMatrix4x4 *matrix) { this->Superclass::SetOrientationMatrix(matrix); this->UpdateOrientation(); } //---------------------------------------------------------------------------- void vtkViewImage2D::InitializeSlicePlane(void) { vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New(); this->SlicePlane->SetPoints(points); points->InsertNextPoint(0, 0, 0); points->InsertNextPoint(1, 0, 0); points->InsertNextPoint(0, 1, 0); points->InsertNextPoint(1, 1, 0); this->SlicePlane->Allocate(4); vtkIdType pts[4]; pts[0] = 0; pts[1] = 1; pts[2] = 3; pts[3] = 2; this->SlicePlane->InsertNextCell(VTK_QUAD, 4, pts); pts[0] = 0; pts[1] = 2; pts[2] = 3; pts[3] = 1; this->SlicePlane->InsertNextCell(VTK_QUAD, 4, pts); vtkSmartPointer< vtkUnsignedCharArray > array = vtkSmartPointer< vtkUnsignedCharArray >::New(); array->SetName("Colors"); array->SetNumberOfComponents(3); unsigned char vals[3]; vals[0] = 255; vals[1] = 0; vals[2] = 0; array->InsertNextTupleValue(vals); array->InsertNextTupleValue(vals); array->InsertNextTupleValue(vals); array->InsertNextTupleValue(vals); this->SlicePlane->GetPointData()->SetScalars(array); } //---------------------------------------------------------------------------- void vtkViewImage2D::UpdateOrientation() { this->Superclass::UpdateOrientation(); this->PostUpdateOrientation(); } //---------------------------------------------------------------------------- void vtkViewImage2D::SetWorldCoordinates(double pos[3]) { this->SetSlice( this->GetSliceForWorldCoordinates(pos) ); } //---------------------------------------------------------------------------- int vtkViewImage2D::SetCameraToConvention(void) { vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL; if ( !cam ) { return -1; } double position[4], focalpoint[4], viewup[4]; double conventionposition[4]; conventionposition[0] = 0.; conventionposition[1] = 0.; conventionposition[2] = 0.; conventionposition[3] = 0.; double conventionview[4]; double focaltoposition[3]; double abs_focaltoposition[3]; std::vector< double * > viewupchoices; double first[3], second[3], third[3], fourth[3]; // First recover information from the camera. // Recover also information from the convention matrix unsigned int i; for ( i = 0; i < 3; i++ ) { position[i] = cam->GetPosition()[i]; focalpoint[i] = cam->GetFocalPoint()[i]; conventionposition[i] = this->ConventionMatrix->GetElement(i, 3); conventionview[i] = this->ConventionMatrix->GetElement(i, this->SliceOrientation); } position[3] = 1; focalpoint[3] = 1; conventionview[3] = 0; viewup[3] = 0; // Apply the orientation matrix to all this information this->GetOrientationMatrix()->MultiplyPoint(position, position); this->GetOrientationMatrix()->MultiplyPoint(focalpoint, focalpoint); this->GetOrientationMatrix()->MultiplyPoint(conventionview, conventionview); this->GetOrientationMatrix()->MultiplyPoint(conventionposition, conventionposition); // Compute the vector perpendicular to the view for ( i = 0; i < 3; i++ ) { focaltoposition[i] = position[i] - focalpoint[i]; abs_focaltoposition[i] = fabs(focaltoposition[i]); } // Deal with the position : // invert it if necessary( symetry among the focal point) if ( vtkMath::Dot(focaltoposition, conventionposition) < 0 ) { for ( i = 0; i < 3; i++ ) { position[i] -= 2 * focaltoposition[i]; } } // Now we now we have 4 choices for the View-Up information for ( i = 0; i < 3; i++ ) { first[i] = conventionview[i]; second[i] = -conventionview[i]; } vtkMath::Cross(first, focaltoposition, third); vtkMath::Cross(second, focaltoposition, fourth); vtkMath::Normalize(third); vtkMath::Normalize(fourth); viewupchoices.push_back(first); viewupchoices.push_back(second); viewupchoices.push_back(third); viewupchoices.push_back(fourth); // To choose between these choices, first we find the axis // the closest to the focaltoposition vector unsigned int id = 0; double dot = 0; for ( i = 0; i < 3; i++ ) { if ( dot < fabs(focaltoposition[i]) ) { dot = fabs(focaltoposition[i]); id = i; } } // Then we choose the convention matrix vector correspondant to the // one we just found for ( i = 0; i < 3; i++ ) { conventionview[i] = this->ConventionMatrix->GetElement(i, id); } // Then we pick from the 4 solutions the closest to the // vector just found unsigned int id2 = 0; double dot2 = 0; for ( i = 0; i < viewupchoices.size(); i++ ) { if ( dot2 < vtkMath::Dot(viewupchoices[i], conventionview) ) { dot2 = vtkMath::Dot(viewupchoices[i], conventionview); id2 = i; } } // We found the solution for ( i = 0; i < 3; i++ ) { viewup[i] = viewupchoices[id2][i]; } cam->SetPosition(position[0], position[1], position[2]); cam->SetFocalPoint(focalpoint[0], focalpoint[1], focalpoint[2]); cam->SetViewUp(viewup[0], viewup[1], viewup[2]); this->SliceImplicitPlane->SetNormal(abs_focaltoposition); double view_plane_normal[3]; cam->GetViewPlaneNormal(view_plane_normal); // Rotation of the( Anterior-Posterior)( Ventral-Dorsal) View if ( this->ViewOrientation == 0 ) { cam->Roll(-90.); } return id; } //---------------------------------------------------------------------------- void vtkViewImage2D::SetAnnotationToConvention(void) { vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL; if ( !cam ) { return; } std::string solution[4]; ///\todo surely there is a simpler way to do all of that ! double *viewup = cam->GetViewUp(); double *normal = cam->GetViewPlaneNormal(); double rightvector[3]; vtkMath::Cross(normal, viewup, rightvector); unsigned int id1 = 0; unsigned int id2 = 0; // unsigned int id3 = 0; double dot1 = 0; double dot2 = 0; double dot3 = 0; for ( unsigned int i = 0; i < 3; i++ ) { if ( dot1 <= fabs(viewup[i]) ) { dot1 = fabs(viewup[i]); id1 = i; } if ( dot2 <= fabs(rightvector[i]) ) { dot2 = fabs(rightvector[i]); id2 = i; } if ( dot3 <= fabs(normal[i]) ) { dot3 = fabs(normal[i]); // id3 = i; } } if ( viewup[id1] > 0 ) { solution[3] = this->DirectionAnnotationMatrix[id1][0]; solution[1] = this->DirectionAnnotationMatrix[id1][1]; } else { solution[3] = this->DirectionAnnotationMatrix[id1][1]; solution[1] = this->DirectionAnnotationMatrix[id1][0]; } if ( rightvector[id2] > 0 ) { solution[0] = this->DirectionAnnotationMatrix[id2][0]; solution[2] = this->DirectionAnnotationMatrix[id2][1]; } else { solution[0] = this->DirectionAnnotationMatrix[id2][1]; solution[2] = this->DirectionAnnotationMatrix[id2][0]; } for ( unsigned int i = 0; i < 4; i++ ) { this->OrientationAnnotation->SetText( i, solution[i].c_str() ); } } //---------------------------------------------------------------------------- void vtkViewImage2D::SetSlicePlaneToConvention(unsigned int axis) { unsigned char vals[3] = { 0, 0, 0 }; vals[axis] = 255; vtkUnsignedCharArray *array = vtkUnsignedCharArray::SafeDownCast( this->SlicePlane->GetPointData()->GetScalars() ); if ( !array ) { return; } array->SetTupleValue(0, vals); array->SetTupleValue(1, vals); array->SetTupleValue(2, vals); array->SetTupleValue(3, vals); } //---------------------------------------------------------------------------- void vtkViewImage2D::SetSlice(int slice) { if ( slice != this->Slice ) { vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL; if ( !cam ) { return; } this->Superclass::SetSlice(slice); this->UpdateSlicePlane(); } } //---------------------------------------------------------------------------- void vtkViewImage2D::UpdateSlicePlane(void) { vtkSmartPointer< vtkPoints > oldpoints = vtkSmartPointer< vtkPoints >::New(); vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New(); double x[3]; double * bounds = this->ImageActor->GetDisplayBounds(); unsigned int added1; unsigned int added2; for ( unsigned int i = 0; i < 4; i++ ) { added1 = ( !( i % 2 ) ) ? 1 : 0; added2 = ( i < 2 ) ? 1 : 0; x[( this->SliceOrientation + 1 ) % 3] = bounds[2 * ( ( this->SliceOrientation + 1 ) % 3 ) + added1]; x[( this->SliceOrientation + 2 ) % 3] = bounds[2 * ( ( this->SliceOrientation + 2 ) % 3 ) + added2]; x[this->SliceOrientation] = bounds[2 * this->SliceOrientation]; oldpoints->InsertPoint(i, x); } this->OrientationTransform->TransformPoints(oldpoints, points); this->SlicePlane->SetPoints(points); points->GetPoint(0, x); this->SliceImplicitPlane->SetOrigin(x); } //---------------------------------------------------------------------------- double * vtkViewImage2D::GetWorldCoordinatesFromDisplayPosition(const int & x, const int & y) { int xy[2] = { x, y }; return this->GetWorldCoordinatesFromDisplayPosition(xy); } //---------------------------------------------------------------------------- int vtkViewImage2D::GetSliceForWorldCoordinates(double pos[3]) { int *indices = this->GetImageCoordinatesFromWorldCoordinates(pos); int slice = indices[this->SliceOrientation]; delete[] indices; return slice; } //---------------------------------------------------------------------------- double * vtkViewImage2D::GetWorldCoordinatesForSlice(int slice) { int indices[3] = { slice, slice, slice }; return this->GetWorldCoordinatesFromImageCoordinates(indices); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2D::ResetPosition(void) { if ( !this->GetInput() ) { return; } int *range = this->GetSliceRange(); if ( range ) { this->SetSlice( ( range[1] + range[0] ) / 2 ); } } //---------------------------------------------------------------------------- void vtkViewImage2D::ResetCamera(void) { this->Zoom = 1.; double bounds[6]; this->GetInput()->GetBounds(bounds); double focal[3]; focal[0] = 0.5 * ( bounds[0] + bounds[1] ); focal[1] = 0.5 * ( bounds[2] + bounds[3] ); focal[2] = 0.5 * ( bounds[4] + bounds[5] ); double pos[3]; pos[0] = focal[0]; pos[1] = focal[1]; pos[2] = focal[2]; double length[3]; length[0] = 0.5 * ( bounds[1] - bounds[0] ); length[1] = 0.5 * ( bounds[3] - bounds[2] ); length[2] = 0.5 * ( bounds[5] - bounds[4] ); double radius = 0.75 * sqrt(length[0] * length[0] + length[1] * length[1] + length[2] * length[2]); vtkCamera *camera = this->GetRenderer()->GetActiveCamera(); double distance = radius / sin(camera->GetViewAngle() * vtkMath::Pi() / 360.0); double view_plane_normal[3]; camera->GetViewPlaneNormal(view_plane_normal); double *vup = camera->GetViewUp(); if ( fabs( vtkMath::Dot(vup, view_plane_normal) ) > 0.999 ) { vtkWarningMacro(<< "Resetting view-up since view plane normal is parallel"); camera->SetViewUp(-vup[2], vup[0], vup[1]); } pos[0] += distance * view_plane_normal[0]; pos[1] += distance * view_plane_normal[1]; pos[2] += distance * view_plane_normal[2]; this->SetCameraFocalAndPosition(focal, pos); double max_length = std::max( length[0], std::max(length[1], length[2]) ); bounds[0] = focal[0] - 50. * max_length; bounds[1] = focal[0] + 50. * max_length; bounds[2] = focal[1] - 50. * max_length; bounds[3] = focal[1] + 50. * max_length; bounds[4] = focal[2] - 50. * max_length; bounds[5] = focal[2] + 50. * max_length; this->GetRenderer()->ResetCameraClippingRange(bounds); camera->SetParallelScale(radius); } //---------------------------------------------------------------------------- void vtkViewImage2D::Reset(void) { //this->ResetPosition(); //this->ResetWindowLevel(); //this->ResetCamera(); } //---------------------------------------------------------------------------- void vtkViewImage2D::SetCameraFocalAndPosition(double focal[3], double pos[3]) { vtkRenderer *ren = this->GetRenderer(); if ( !ren ) { return; } vtkCamera *camera = ren->GetActiveCamera(); if ( !camera ) { return; } camera->SetFocalPoint(focal[0], focal[1], focal[2]); camera->SetPosition(pos[0], pos[1], pos[2]); } //---------------------------------------------------------------------------- void vtkViewImage2D::GetCameraFocalAndPosition(double focal[3], double pos[3]) { vtkRenderer *ren = this->GetRenderer(); if ( !ren ) { return; } vtkCamera *camera = ren->GetActiveCamera(); if ( !camera ) { return; } camera->GetPosition(pos); camera->GetFocalPoint(focal); } //---------------------------------------------------------------------------- double * vtkViewImage2D::GetWorldCoordinatesFromDisplayPosition(int xy[2]) { // in one case this function creates an array and don't manage it // in another case, it gives a pointer to a managed array : // MEMORY LEAKS if ( !this->GetInput() || !this->GetRenderer() ) { // case 1 : non managed array pointer double *nullpos = new double[3]; nullpos[0] = 0; nullpos[1] = 0; nullpos[2] = 0; return nullpos; } double *slicepos = this->GetWorldCoordinatesForSlice( this->GetSlice() ); this->GetRenderer()->SetWorldPoint(slicepos[0], slicepos[1], slicepos[2], 1.0); this->GetRenderer()->WorldToDisplay(); this->GetRenderer()->SetDisplayPoint(xy[0], xy[1], this->GetRenderer()->GetDisplayPoint()[2]); this->GetRenderer()->DisplayToWorld(); // think about deleting the temporary created array delete[] slicepos; // case 2 : pointer to managed array return this->GetRenderer()->GetWorldPoint(); } //---------------------------------------------------------------------------- void vtkViewImage2D::InstallPipeline() { if ( this->RenderWindow && this->Renderer ) { if ( !this->RenderWindow->HasRenderer(this->Renderer) ) { this->RenderWindow->AddRenderer(this->Renderer); } } if ( this->Interactor ) { if ( !this->InteractorStyle ) { this->InteractorStyle = vtkInteractorStyleImage2D::New(); this->Interactor->SetInteractorStyle(this->InteractorStyle); this->InteractorStyle->AddObserver( vtkCommand::KeyPressEvent, this->Command); this->InteractorStyle->AddObserver( vtkViewImage2DCommand::StartSliceMoveEvent, this->Command); this->InteractorStyle->AddObserver( vtkViewImage2DCommand::SliceMoveEvent, this->Command); this->InteractorStyle->AddObserver( vtkViewImage2DCommand::EndSliceMoveEvent, this->Command); this->InteractorStyle->AddObserver( vtkViewImage2DCommand::ResetViewerEvent, this->Command); this->InteractorStyle->AddObserver( vtkViewImage2DCommand::ZoomEvent, this->Command); this->InteractorStyle->AddObserver( vtkViewImage2DCommand::PanEvent, this->Command); this->InteractorStyle->AddObserver( vtkCommand::InteractionEvent, this->Command); this->InteractorStyle->AddObserver( vtkViewImage2DCommand::RequestedPositionEvent, this->Command); this->InteractorStyle->AddObserver( vtkViewImage2DCommand::ContourPickingEvent, this->Command); this->InteractorStyle->AddObserver( vtkViewImage2DCommand::MeshPickingEvent, this->Command); this->InteractorStyle->AddObserver( vtkCommand::StartWindowLevelEvent, this->Command); this->InteractorStyle->AddObserver( vtkCommand::WindowLevelEvent, this->Command); } this->InteractorStyleSwitcher = this->InteractorStyle; this->Interactor->SetInteractorStyle(this->InteractorStyle); this->Interactor->SetRenderWindow(this->RenderWindow); } if ( this->Renderer && this->ImageActor ) { this->ImageActor->SetInterpolate(false); } if ( this->Renderer && this->ImageActor ) { if ( !this->Renderer->GetActors()->IsItemPresent(this->ImageActor) ) { this->Renderer->AddViewProp(this->ImageActor); } } if ( this->ImageActor && this->WindowLevel ) { this->ImageActor->SetInput( this->WindowLevel->GetOutput() ); } } //---------------------------------------------------------------------------- void vtkViewImage2D::SetInterpolate(const int & val) { if ( this->ImageActor ) { this->ImageActor->SetInterpolate(val); } } //---------------------------------------------------------------------------- int vtkViewImage2D::GetInterpolate(void) { if ( this->ImageActor ) { return this->ImageActor->GetInterpolate(); } else { return 0; } } //---------------------------------------------------------------------------- // vtkQuadricLODActor* vtkActor * vtkViewImage2D::AddDataSet(vtkPolyData *dataset, vtkProperty *property, const bool & intersection, const bool & iDataVisibility) { // vtkCamera *cam = NULL; if ( !this->Renderer ) { // cam = this->Renderer->GetActiveCamera(); // } // else // { return NULL; } if ( !dataset ) { return NULL; } if ( dataset->GetNumberOfPoints() <= 0 ) { return NULL; } vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetScalarVisibility(iDataVisibility); mapper->ImmediateModeRenderingOn(); // check if input data is 2D double *bounds = dataset->GetBounds(); // get normal double *normal = this->SliceImplicitPlane->GetNormal(); // if in 2d if ( ( ( bounds[0] == bounds[1] ) && ( normal[1] == 0 ) && ( normal[2] == 0 ) ) || ( ( bounds[2] == bounds[3] ) && ( normal[2] == 0 ) && ( normal[0] == 0 ) ) || ( ( bounds[4] == bounds[5] ) && ( normal[0] == 0 ) && ( normal[1] == 0 ) ) ) { vtkSmartPointer extracter = vtkSmartPointer::New(); extracter->SetInput(dataset); extracter->SetImplicitFunction(this->SliceImplicitPlane); extracter->Update(); mapper->SetInput( extracter->GetOutput() ); } // i.e. if we cut a volume else { if ( intersection ) { vtkSmartPointer cutter = vtkSmartPointer::New(); cutter->SetInput(dataset); cutter->SetCutFunction(this->SliceImplicitPlane); mapper->SetInput( cutter->GetOutput() ); } else { mapper->SetInput(dataset); } } vtkActor * actor = vtkActor::New(); actor->SetMapper(mapper); if ( property ) { actor->SetProperty(property); } actor->GetProperty()->BackfaceCullingOn(); actor->GetProperty()->SetLineWidth(this->IntersectionLineWidth); this->Renderer->AddViewProp(actor); return actor; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- std::map vtkViewImage2D:: ExtractActors(vtkPolyData *iDataSet, ORIENTATION iOrientation) { std::map contours; // create plane to extract contours (based on orientation) double normal[3] = {0., 0., 0.}; switch (iOrientation) { case XY: { normal[2] = 1; break; } case XZ: { normal[1] = 1; break; } case YZ: { normal[0] = 1; break; } default: { break; } } double origin[3] = {0., 0., 0.}; origin[0] = iDataSet->GetCenter()[0]; origin[1] = iDataSet->GetCenter()[1]; origin[2] = iDataSet->GetCenter()[2]; double position = iDataSet->GetBounds()[4 - 2*iOrientation]; double maxPosition = iDataSet->GetBounds()[5 - 2*iOrientation]; /*std::cout << "position: " << position << "-" << maxPosition << std::endl;*/ // get information about image (spacing) double spacing = this->GetInput()->GetSpacing()[2-iOrientation]; while( position < maxPosition) { origin[2-iOrientation] = position; /* std::cout << "origin: " << origin[0] << "-" << origin[1] << "-" << origin[2] << std::endl; std::cout << "normal: " << normal[0] << "-" << normal[1] << "-" << normal[2] << std::endl; */ vtkPlane* plane = vtkPlane::New(); plane->SetNormal(normal); plane->SetOrigin(origin); // cut vtkCutter* cutter = vtkCutter::New(); cutter->SetInput(iDataSet); cutter->SetCutFunction(plane); cutter->Update(); plane->Delete(); vtkPolyDataMapper* mapper = vtkPolyDataMapper::New(); mapper->SetInput( cutter->GetOutput() ); cutter->Delete(); vtkActor* actor = vtkActor::New(); actor->SetMapper(mapper); actor->VisibilityOn(); mapper->Delete(); contours[position] = actor; // increase position position += spacing; } return contours; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void vtkViewImage2D::UpdateCenter(void) { if ( !this->GetInput() ) { return; } // vtkCamera *cam = NULL; if ( !this->Renderer ) { // cam = this->Renderer->GetActiveCamera(); // } // else // { // return; } int *dimensions = this->GetInput()->GetDimensions(); int indices[3] = { 0, 0, 0 }; for ( unsigned int i = 0; i < 3; i++ ) { indices[i] = (int)( (double)dimensions[i] / 2.0 ); } indices[this->SliceOrientation] = this->GetSlice(); double *center = this->GetWorldCoordinatesFromImageCoordinates (indices); for ( unsigned int i = 0; i < 3; i++ ) { this->ViewCenter[i] = center[i]; } delete[] center; } //---------------------------------------------------------------------------- void vtkViewImage2D::PostUpdateOrientation() { int axis = this->SetCameraToConvention(); this->ViewOrientation = axis; this->SetAnnotationToConvention(); this->SetSlicePlaneToConvention(axis); this->UpdateSlicePlane(); } //---------------------------------------------------------------------------- void vtkViewImage2D::SetSlicePlaneFromOrientation(void) { /** These lines tell the slice plane which color it should be ///\todo We should allow more colors... */ unsigned char vals[3] = { 0, 0, 0 }; vals[this->ViewOrientation] = 255; vtkUnsignedCharArray *array = vtkUnsignedCharArray::SafeDownCast ( this->SlicePlane->GetPointData()->GetScalars() ); if ( !array ) { return; } array->SetTupleValue (0, vals); array->SetTupleValue (1, vals); array->SetTupleValue (2, vals); array->SetTupleValue (3, vals); this->UpdateSlicePlane(); } //---------------------------------------------------------------------------- int vtkViewImage2D::SetCameraFromOrientation(void) { // The camera has already been set as if the image has no orientation. // So we just have to adjust its position and view up according // to the image orientation and conventions. vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL; if ( !cam ) { return -1; } double position[4], focalpoint[4], viewup[4]; double conventionposition[4]; double conventionview[4]; double focaltoposition[3]; std::vector< double * > viewupchoices; double first[3], second[3], third[3], fourth[3]; bool inverseposition; // First recover information from the camera. // Recover also information from the convention matrix for ( unsigned int i = 0; i < 3; i++ ) { position[i] = cam->GetPosition()[i]; focalpoint[i] = cam->GetFocalPoint()[i]; conventionposition[i] = this->ConventionMatrix->GetElement (i, 3); conventionview[i] = this->ConventionMatrix->GetElement (i, this->SliceOrientation); } position[3] = 1; focalpoint[3] = 1; conventionview[3] = 0; viewup[3] = 0; // Apply the orientation matrix to all this information if ( this->GetOrientationMatrix() ) { this->GetOrientationMatrix()->MultiplyPoint (position, position); this->GetOrientationMatrix()->MultiplyPoint (focalpoint, focalpoint); this->GetOrientationMatrix()->MultiplyPoint (conventionview, conventionview); this->GetOrientationMatrix()->MultiplyPoint (conventionposition, conventionposition); } // Compute the vector perpendicular to the view for ( unsigned int i = 0; i < 3; i++ ) { focaltoposition[i] = position[i] - focalpoint[i]; } // Deal with the position : // invert it if necessary (symetry among the focal point) inverseposition = ( vtkMath::Dot (focaltoposition, conventionposition) < 0 ); if ( inverseposition ) { for ( unsigned int i = 0; i < 3; i++ ) { position[i] -= 2 * focaltoposition[i]; } } // Now we now we have 4 choices for the View-Up information for ( unsigned int i = 0; i < 3; i++ ) { first[i] = conventionview[i]; second[i] = -conventionview[i]; } vtkMath::Cross (first, focaltoposition, third); vtkMath::Cross (second, focaltoposition, fourth); vtkMath::Normalize (third); vtkMath::Normalize (fourth); viewupchoices.push_back (first); viewupchoices.push_back (second); viewupchoices.push_back (third); viewupchoices.push_back (fourth); // To choose between these choices, first we find the axis // the closest to the focaltoposition vector unsigned int id = 0; double dot = 0; for ( unsigned int i = 0; i < 3; i++ ) { if ( dot < std::abs (focaltoposition[i]) ) { dot = std::abs (focaltoposition[i]); id = i; } } // Then we choose the convention matrix vector correspondant to the // one we just found for ( unsigned int i = 0; i < 3; i++ ) { conventionview[i] = this->ConventionMatrix->GetElement (i, id); } // Then we pick from the 4 solutions the closest to the // vector just found unsigned int id2 = 0; double dot2 = 0; for ( unsigned int i = 0; i < viewupchoices.size(); i++ ) { if ( dot2 < vtkMath::Dot (viewupchoices[i], conventionview) ) { dot2 = vtkMath::Dot (viewupchoices[i], conventionview); id2 = i; } } // We found the solution for ( unsigned int i = 0; i < 3; i++ ) { viewup[i] = viewupchoices[id2][i]; } cam->SetPosition(position[0], position[1], position[2]); cam->SetFocalPoint(focalpoint[0], focalpoint[1], focalpoint[2]); cam->SetViewUp(viewup[0], viewup[1], viewup[2]); return id; } //---------------------------------------------------------------------------- void vtkViewImage2D::SetAnnotationsFromOrientation(void) { // This method has to be called after the camera // has been set according to orientation and convention. // We rely on the camera settings to compute the oriention // annotations. vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL; if ( !cam ) { return; } std::string matrix[3][2]; matrix[0][0] = "R"; matrix[0][1] = "L"; matrix[1][0] = "A"; matrix[1][1] = "P"; matrix[2][0] = "I"; matrix[2][1] = "S"; std::string solution[4]; ///\todo surely there is a simpler way to do all of that ! double *viewup = cam->GetViewUp(); double *normal = cam->GetViewPlaneNormal(); double rightvector[3]; vtkMath::Cross (normal, viewup, rightvector); unsigned int id1 = 0; unsigned int id2 = 0; // unsigned int id3 = 0; double dot1 = 0; double dot2 = 0; double dot3 = 0; for ( unsigned int i = 0; i < 3; i++ ) { if ( dot1 <= std::abs (viewup[i]) ) { dot1 = std::abs (viewup[i]); id1 = i; } if ( dot2 <= std::abs (rightvector[i]) ) { dot2 = std::abs (rightvector[i]); id2 = i; } if ( dot3 <= std::abs (normal[i]) ) { dot3 = std::abs (normal[i]); //id3 = i; } } if ( viewup[id1] > 0 ) { solution[3] = matrix[id1][0]; solution[1] = matrix[id1][1]; } else { solution[3] = matrix[id1][1]; solution[1] = matrix[id1][0]; } if ( rightvector[id2] > 0 ) { solution[0] = matrix[id2][0]; solution[2] = matrix[id2][1]; } else { solution[0] = matrix[id2][1]; solution[2] = matrix[id2][0]; } for ( unsigned int i = 0; i < 4; i++ ) { this->OrientationAnnotation->SetText ( i, solution[i].c_str() ); } if ( this->GetInput() ) { // naively the X and Y axes of the current view // correspond to the rightvector and the viewup respectively. // But in fact we have to put those vectors back in the image // coordinates and see to which xyz image axis they correspond. double Xaxis[4] = { 0, 0, 0, 0 }; double Yaxis[4] = { 0, 0, 0, 0 }; for ( unsigned int i = 0; i < 3; i++ ) { Xaxis[i] = rightvector[i]; Yaxis[i] = viewup[i]; } vtkMatrix4x4 *inverse = vtkMatrix4x4::New(); inverse->Identity(); if ( this->GetOrientationMatrix() ) { vtkMatrix4x4::Invert (this->GetOrientationMatrix(), inverse); } inverse->MultiplyPoint (Xaxis, Xaxis); inverse->MultiplyPoint (Yaxis, Yaxis); inverse->Delete(); double dotX = 0; double dotY = 0; int idX, idY; idX = idY = 0; for ( unsigned int i = 0; i < 3; i++ ) { if ( dotX <= std::abs (Xaxis[i]) ) { dotX = std::abs (Xaxis[i]); idX = i; } if ( dotY <= std::abs (Yaxis[i]) ) { dotY = std::abs (Yaxis[i]); idY = i; } } int * dimensions = this->GetInput()->GetDimensions(); double *spacing = this->GetInput()->GetSpacing(); sprintf(this->ImageInformation, "Image Size: %i x %i\nVoxel Size: %g x %g mm", dimensions[idX], dimensions[idY], spacing[idX], spacing[idY]); sprintf(this->SliceAndWindowInformation, "\n\n"); this->CornerAnnotation->SetText(2, this->ImageInformation); this->CornerAnnotation->SetText(3, this->SliceAndWindowInformation); } } //---------------------------------------------------------------------------- void vtkViewImage2D::SetImplicitPlaneFromOrientation(void) { vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL; if ( !cam ) { return; } double *position = cam->GetPosition(); double *focalpoint = cam->GetFocalPoint(); double focaltoposition[3]; unsigned int i; // Compute the vector perpendicular to the view for ( i = 0; i < 3; i++ ) { focaltoposition[i] = fabs(position[i] - focalpoint[i]); } this->SliceImplicitPlane->SetNormal (focaltoposition); } //---------------------------------------------------------------------------- void vtkViewImage2D::UpdateCursor(void) { this->GetRenderer()->SetWorldPoint (this->CurrentPoint[0], this->CurrentPoint[1], this->CurrentPoint[2], 0); this->GetRenderer()->WorldToDisplay(); double *xy = this->GetRenderer()->GetDisplayPoint(); this->GetCursor()->SetDisplayPosition (xy); char os[128]; sprintf(os, "%s\nXYZ: %4.2f, %4.2f, %4.2f mm\nValue: %g", this->ImageInformation, this->CurrentPoint[0], this->CurrentPoint[1], this->CurrentPoint[2], this->GetValueAtPosition (this->CurrentPoint) ); this->CornerAnnotation->SetText(2, os); } GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/CMakeLists.txt0000644000175000017500000000106411667757442022622 0ustar mathieumathieuIF( WIN32 ) IF( NOT CYGWIN ) IF( NOT MINGW ) IF( BUILD_SHARED_LIBS ) ADD_DEFINITIONS( -DvtkRenderingAddOn2_EXPORTS ) ENDIF( BUILD_SHARED_LIBS ) ENDIF( NOT MINGW ) ENDIF( NOT CYGWIN ) ENDIF( WIN32 ) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/MegaVTK2Configure.h.in ${CMAKE_CURRENT_BINARY_DIR}/MegaVTK2Configure.h @ONLY IMMEDIATE) SUBDIRS( vtkRenderingAddOn ) SUBDIRS( vtkItk ) INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/MegaVTK2Configure.h DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkItk/0000755000175000017500000000000011667757442021335 5ustar mathieumathieuGoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkItk/itkImageToVTKImageFilter.h0000644000175000017500000001244211667757442026244 0ustar mathieumathieu/*========================================================================= Author: $Author:$ // Author of last commit Version: $Rev:$ // Revision of last commit Date: $Date:$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkImageToVTKImageFilter.h,v $ Language: C++ Date: $Date: 2007-11-20 12:46:10 -0500 (Tue, 20 Nov 2007) $ Version: $Revision: 477 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkImageToVTKImageFilter_h #define __itkImageToVTKImageFilter_h #include "itkVTKImageExport.h" #include "vtkImageImport.h" #include "vtkImageData.h" namespace itk { /** \class ImageToVTKImageFilter * \brief Converts an ITK image into a VTK image and plugs a * itk data pipeline to a VTK datapipeline. * * This class puts together an itkVTKImageExporter and a vtkImageImporter. * It takes care of the details related to the connection of ITK and VTK * pipelines. The User will perceive this filter as an adaptor to which * an itk::Image can be plugged as input and a vtkImage is produced as * output. * * \ingroup ImageFilters */ template< class TInputImage > class ITK_EXPORT ImageToVTKImageFilter:public ProcessObject { public: /** Standard class typedefs. */ typedef ImageToVTKImageFilter Self; typedef ProcessObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(ImageToVTKImageFilter, ProcessObject); /** Some typedefs. */ typedef TInputImage InputImageType; typedef typename InputImageType::ConstPointer InputImagePointer; typedef VTKImageExport< InputImageType > ExporterFilterType; typedef typename ExporterFilterType::Pointer ExporterFilterPointer; /** Get the output in the form of a vtkImage. This call is delegated to the internal vtkImageImporter filter */ vtkImageData * GetOutput() const; /** Set the input in the form of an itk::Image */ void SetInput(const InputImageType *); /** Return the internal VTK image importer filter. This is intended to facilitate users the access to methods in the importer */ vtkImageImport * GetImporter() const; /** Return the internal ITK image exporter filter. This is intended to facilitate users the access to methods in the exporter */ ExporterFilterType * GetExporter() const; /** This call delegate the update to the importer */ void Update(); protected: ImageToVTKImageFilter(); virtual ~ImageToVTKImageFilter(); private: ImageToVTKImageFilter(const Self &); //purposely not implemented void operator=(const Self &); //purposely not implemented ExporterFilterPointer m_Exporter; vtkImageImport * m_Importer; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkImageToVTKImageFilter.txx" #endif #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkItk/itkVTKImageToImageFilter.txx0000644000175000017500000001167111667757442026643 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkVTKImageToImageFilter.txx,v $ Language: C++ Date: $Date: 2007-11-20 12:46:10 -0500 (Tue, 20 Nov 2007) $ Version: $Revision: 477 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkVTKImageToImageFilter_txx #define _itkVTKImageToImageFilter_txx #include "itkVTKImageToImageFilter.h" namespace itk { /** * Constructor */ template< class TOutputImage > VTKImageToImageFilter< TOutputImage > ::VTKImageToImageFilter() { m_Exporter = vtkImageExport::New(); m_Importer = ImporterFilterType::New(); m_Importer->SetUpdateInformationCallback( m_Exporter->GetUpdateInformationCallback() ); m_Importer->SetPipelineModifiedCallback( m_Exporter->GetPipelineModifiedCallback() ); m_Importer->SetWholeExtentCallback( m_Exporter->GetWholeExtentCallback() ); m_Importer->SetSpacingCallback( m_Exporter->GetSpacingCallback() ); m_Importer->SetOriginCallback( m_Exporter->GetOriginCallback() ); m_Importer->SetScalarTypeCallback( m_Exporter->GetScalarTypeCallback() ); m_Importer->SetNumberOfComponentsCallback( m_Exporter->GetNumberOfComponentsCallback() ); m_Importer->SetPropagateUpdateExtentCallback( m_Exporter->GetPropagateUpdateExtentCallback() ); m_Importer->SetUpdateDataCallback( m_Exporter->GetUpdateDataCallback() ); m_Importer->SetDataExtentCallback( m_Exporter->GetDataExtentCallback() ); m_Importer->SetBufferPointerCallback( m_Exporter->GetBufferPointerCallback() ); m_Importer->SetCallbackUserData( m_Exporter->GetCallbackUserData() ); } /** * Destructor */ template< class TOutputImage > VTKImageToImageFilter< TOutputImage > ::~VTKImageToImageFilter() { if ( m_Exporter ) { m_Exporter->Delete(); m_Exporter = 0; } } /** * Set a vtkImageData as input */ template< class TOutputImage > void VTKImageToImageFilter< TOutputImage > ::SetInput(vtkImageData *inputImage) { m_Exporter->SetInput(inputImage); } /** * Get an itk::Image as output */ template< class TOutputImage > typename VTKImageToImageFilter< TOutputImage >::OutputImageType * VTKImageToImageFilter< TOutputImage > ::GetOutput() const { return m_Importer->GetOutput(); } /** * Get the exporter filter */ template< class TOutputImage > vtkImageExport * VTKImageToImageFilter< TOutputImage > ::GetExporter() const { return m_Exporter; } /** * Get the importer filter */ template< class TOutputImage > typename VTKImageToImageFilter< TOutputImage >::ImporterFilterType * VTKImageToImageFilter< TOutputImage > ::GetImporter() const { return m_Importer; } /** * Delegate the Update to the importer */ template< class TOutputImage > void VTKImageToImageFilter< TOutputImage > ::Update() { m_Importer->Update(); } } // end namespace itk #endifGoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkItk/vtkitkAdaptor.h0000644000175000017500000001073011667757442024336 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __vtkitkAdaptor_h #define __vtkitkAdaptor_h template< typename ITK_Exporter, typename VTK_Importer > void ConnectPipelines(ITK_Exporter exporter, VTK_Importer *importer) { exporter->Update(); importer->SetUpdateInformationCallback ( exporter->GetUpdateInformationCallback() ); importer->SetPipelineModifiedCallback ( exporter->GetPipelineModifiedCallback() ); importer->SetWholeExtentCallback ( exporter->GetWholeExtentCallback() ); importer->SetSpacingCallback ( exporter->GetSpacingCallback() ); importer->SetOriginCallback ( exporter->GetOriginCallback() ); importer->SetScalarTypeCallback ( exporter->GetScalarTypeCallback() ); importer->SetNumberOfComponentsCallback ( exporter->GetNumberOfComponentsCallback() ); importer->SetPropagateUpdateExtentCallback ( exporter->GetPropagateUpdateExtentCallback() ); importer->SetUpdateDataCallback ( exporter->GetUpdateDataCallback() ); importer->SetDataExtentCallback ( exporter->GetDataExtentCallback() ); importer->SetBufferPointerCallback ( exporter->GetBufferPointerCallback() ); importer->SetCallbackUserData ( exporter->GetCallbackUserData() ); importer->Update(); } /** * This function will connect the given vtkImageExport filter to * the given itk::VTKImageImport filter. */ template< typename VTK_Exporter, typename ITK_Importer > void ConnectPipelines(VTK_Exporter *exporter, ITK_Importer importer) { exporter->Update(); importer->SetUpdateInformationCallback ( exporter->GetUpdateInformationCallback() ); importer->SetPipelineModifiedCallback ( exporter->GetPipelineModifiedCallback() ); importer->SetWholeExtentCallback ( exporter->GetWholeExtentCallback() ); importer->SetSpacingCallback ( exporter->GetSpacingCallback() ); importer->SetOriginCallback ( exporter->GetOriginCallback() ); importer->SetScalarTypeCallback ( exporter->GetScalarTypeCallback() ); importer->SetNumberOfComponentsCallback ( exporter->GetNumberOfComponentsCallback() ); importer->SetPropagateUpdateExtentCallback ( exporter->GetPropagateUpdateExtentCallback() ); importer->SetUpdateDataCallback ( exporter->GetUpdateDataCallback() ); importer->SetDataExtentCallback ( exporter->GetDataExtentCallback() ); importer->SetBufferPointerCallback ( exporter->GetBufferPointerCallback() ); importer->SetCallbackUserData ( exporter->GetCallbackUserData() ); importer->Update(); } #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkItk/CMakeLists.txt0000644000175000017500000000040411667757442024073 0ustar mathieumathieuFILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE( GLOB __source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/*.txx" ) INSTALL( FILES ${__source_file_h} ${__source_file_txx} DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkItk/itkImageToVTKImageFilter.txx0000644000175000017500000001216011667757442026635 0ustar mathieumathieu/*========================================================================= Author: $Author:$ // Author of last commit Version: $Rev:$ // Revision of last commit Date: $Date:$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkImageToVTKImageFilter.txx,v $ Language: C++ Date: $Date: 2007-11-20 12:46:10 -0500 (Tue, 20 Nov 2007) $ Version: $Revision: 477 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkImageToVTKImageFilter_txx #define _itkImageToVTKImageFilter_txx #include "itkImageToVTKImageFilter.h" namespace itk { /** * Constructor */ template< class TInputImage > ImageToVTKImageFilter< TInputImage > ::ImageToVTKImageFilter() { m_Importer = vtkImageImport::New(); m_Exporter = ExporterFilterType::New(); m_Importer->SetUpdateInformationCallback( m_Exporter->GetUpdateInformationCallback() ); m_Importer->SetPipelineModifiedCallback( m_Exporter->GetPipelineModifiedCallback() ); m_Importer->SetWholeExtentCallback( m_Exporter->GetWholeExtentCallback() ); m_Importer->SetSpacingCallback( m_Exporter->GetSpacingCallback() ); m_Importer->SetOriginCallback( m_Exporter->GetOriginCallback() ); m_Importer->SetScalarTypeCallback( m_Exporter->GetScalarTypeCallback() ); m_Importer->SetNumberOfComponentsCallback( m_Exporter->GetNumberOfComponentsCallback() ); m_Importer->SetPropagateUpdateExtentCallback( m_Exporter->GetPropagateUpdateExtentCallback() ); m_Importer->SetUpdateDataCallback( m_Exporter->GetUpdateDataCallback() ); m_Importer->SetDataExtentCallback( m_Exporter->GetDataExtentCallback() ); m_Importer->SetBufferPointerCallback( m_Exporter->GetBufferPointerCallback() ); m_Importer->SetCallbackUserData( m_Exporter->GetCallbackUserData() ); } /** * Destructor */ template< class TInputImage > ImageToVTKImageFilter< TInputImage > ::~ImageToVTKImageFilter() { m_Importer->Delete(); } /** * Set an itk::Image as input */ template< class TInputImage > void ImageToVTKImageFilter< TInputImage > ::SetInput(const InputImageType *inputImage) { m_Exporter->SetInput(inputImage); } /** * Get a vtkImage as output */ template< class TInputImage > vtkImageData * ImageToVTKImageFilter< TInputImage > ::GetOutput() const { return m_Importer->GetOutput(); } /** * Get the importer filter */ template< class TInputImage > vtkImageImport * ImageToVTKImageFilter< TInputImage > ::GetImporter() const { return m_Importer; } /** * Get the exporter filter */ template< class TInputImage > typename ImageToVTKImageFilter< TInputImage >::ExporterFilterType * ImageToVTKImageFilter< TInputImage > ::GetExporter() const { return m_Exporter.GetPointer(); } /** * Delegate the Update to the importer */ template< class TInputImage > void ImageToVTKImageFilter< TInputImage > ::Update() { m_Importer->Update(); } } // end namespace itk #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/vtkItk/itkVTKImageToImageFilter.h0000644000175000017500000001255511667757442026251 0ustar mathieumathieu/*========================================================================= Author: $Author:$ // Author of last commit Version: $Rev:$ // Revision of last commit Date: $Date:$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkVTKImageToImageFilter.h,v $ Language: C++ Date: $Date: 2007-11-20 12:46:10 -0500 (Tue, 20 Nov 2007) $ Version: $Revision: 477 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkVTKImageToImageFilter_h #define __itkVTKImageToImageFilter_h #include "itkVTKImageImport.h" #include "vtkImageExport.h" #include "vtkImageData.h" #ifndef vtkFloatingPointType #define vtkFloatingPointType float #endif namespace itk { /** \class VTKImageToImageFilter * \brief Converts a VTK image into an ITK image and plugs a * vtk data pipeline to an ITK datapipeline. * * This class puts together an itkVTKImageImporter and a vtkImageExporter. * It takes care of the details related to the connection of ITK and VTK * pipelines. The User will perceive this filter as an adaptor to which * a vtkImage can be plugged as input and an itk::Image is produced as * output. * * \ingroup ImageFilters */ template< class TOutputImage > class ITK_EXPORT VTKImageToImageFilter:public ProcessObject { public: /** Standard class typedefs. */ typedef VTKImageToImageFilter Self; typedef ProcessObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(VTKImageToImageFilter, ProcessObject); /** Some typedefs. */ typedef TOutputImage OutputImageType; typedef typename OutputImageType::ConstPointer OutputImagePointer; typedef VTKImageImport< OutputImageType > ImporterFilterType; typedef typename ImporterFilterType::Pointer ImporterFilterPointer; /** Get the output in the form of a vtkImage. This call is delegated to the internal vtkImageImporter filter */ OutputImageType * GetOutput() const; /** Set the input in the form of a vtkImageData */ void SetInput(vtkImageData *); /** Return the internal VTK image exporter filter. This is intended to facilitate users the access to methods in the exporter */ vtkImageExport * GetExporter() const; /** Return the internal ITK image importer filter. This is intended to facilitate users the access to methods in the importer */ ImporterFilterType * GetImporter() const; /** This call delegate the update to the importer */ void Update(); protected: VTKImageToImageFilter(); virtual ~VTKImageToImageFilter(); private: VTKImageToImageFilter(const Self &); //purposely not implemented void operator=(const Self &); //purposely not implemented ImporterFilterPointer m_Importer; vtkImageExport * m_Exporter; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkVTKImageToImageFilter.txx" #endif #endif GoFigure2-v0.9.0/Code/ExternalCode/MegaVTK/MegaVTK2Configure.h.in0000644000175000017500000000062411667757442024023 0ustar mathieumathieu#ifndef __MegaVTK2Configure_h #define __MegaVTK2Configure_h /* Whether we are building shared libraries. */ #if defined ( WIN32 ) && defined ( GOFIGURE2_BUILD_SHARED_LIBS ) #if defined ( vtkRenderingAddOn2_EXPORTS ) #define VTK_RENDERINGADDON2_EXPORT __declspec(dllexport) #else #define VTK_RENDERINGADDON2_EXPORT __declspec(dllimport) #endif #else #define VTK_RENDERINGADDON2_EXPORT #endif #endifGoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/0000755000175000017500000000000011667757442023217 5ustar mathieumathieuGoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/vtkNormalEstimationFilter.h0000644000175000017500000001042011667757442030545 0ustar mathieumathieu/*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Program: Visualization Toolkit Module: vtkSurfaceReconstructionFilter.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ // .NAME vtkNormalEstimationFilter - estimate normals from unorganized points // .SECTION Description // vtkNormalEstimationFilter takes a list of points assumed to lie on // the surface of a solid 3D object. This procedure is based on the PhD // work of Hugues Hoppe: http://www.research.microsoft.com/~hoppe #ifndef __vtkNormalEstimationFilter_h #define __vtkNormalEstimationFilter_h #include "vtkPolyDataAlgorithm.h" #include "PoissonReconstructionConfigure.h" struct SurfacePoint; class PoissonReconstruction_EXPORT vtkNormalEstimationFilter:public vtkPolyDataAlgorithm { public: vtkTypeMacro(vtkNormalEstimationFilter, vtkPolyDataAlgorithm); void PrintSelf(ostream & os, vtkIndent indent); // Description: // Construct with NeighborhoodSize=20. static vtkNormalEstimationFilter * New(); // Description: vtkGetMacro(RadiusRatio, double); vtkSetMacro(RadiusRatio, double); protected: vtkNormalEstimationFilter(); ~vtkNormalEstimationFilter(); SurfacePoint *m_SurfacePoints; virtual int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *); virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); double RadiusRatio; vtkIdType NeighborhoodSize; virtual int FillInputPortInformation(int, vtkInformation *); void BuildLocalConnectivity(vtkDataSet *input); void EstimatePlanes(vtkDataSet *input); void ComputeCostForMST(vtkDataSet *input); int ConsistencyPropagation(); private: vtkNormalEstimationFilter(const vtkNormalEstimationFilter &); // Not // implemented. void operator=(const vtkNormalEstimationFilter &); // Not // implemented. }; #endif GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/MultiGridOctreeData.inl0000644000175000017500000026050711667757442027571 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include #include #include "MultiGridOctest.h" #define ITERATION_POWER 1.0/3 #define MEMORY_ALLOCATOR_BLOCK_SIZE 1<<12 #define READ_SIZE 1024 #define PAD_SIZE (Real(1.0)) const Real EPSILON=Real(1e-6); const Real ROUND_EPS=Real(1e-5); ///////////////////// // SortedTreeNodes // ///////////////////// inline SortedTreeNodes::SortedTreeNodes(void) { nodeCount=NULL; treeNodes=NULL; maxDepth=0; } inline SortedTreeNodes::~SortedTreeNodes(void) { if(nodeCount){delete[] nodeCount;} if(treeNodes){delete[] treeNodes;} nodeCount=NULL; treeNodes=NULL; } inline void SortedTreeNodes::set(TreeOctNode& root,const int& setIndex) { if(nodeCount) {delete[] nodeCount;} if(treeNodes) {delete[] treeNodes;} maxDepth=root.maxDepth()+1; nodeCount=new int[maxDepth+1]; treeNodes=new TreeOctNode*[root.nodes()]; TreeOctNode* temp=root.nextNode(); int i,cnt=0; while(temp) { treeNodes[cnt++]=temp; temp=root.nextNode(temp); } qsort(treeNodes,cnt,sizeof(const TreeOctNode*),TreeOctNode::CompareForwardPointerDepths); for(i=0;i<=maxDepth;i++) {nodeCount[i]=0;} for(i=0;inodeData.nodeIndex=i;} nodeCount[treeNodes[i]->depth()+1]++; } for(i=1;i<=maxDepth;i++) {nodeCount[i]+=nodeCount[i-1];} } ////////////////// // TreeNodeData // ////////////////// //int TreeNodeData::UseIndex=1; inline TreeNodeData::TreeNodeData() { if(UseIndex){ nodeIndex=-1; centerWeightContribution=0; } else{mcIndex=0;} value=0; } inline TreeNodeData::~TreeNodeData() {} //////////// // Octree // //////////// //template //double Octree::maxMemoryUsage=0; /* template inline double Octree::MemoryUsage(void) { double mem=MemoryInfo::Usage()/(1<<20); if(mem>maxMemoryUsage) {maxMemoryUsage=mem;} return mem; } */ template inline Octree::Octree(void) : normals(NULL) { radius=0; width=0; postNormalSmooth=0; } template inline void Octree::setNodeIndices(TreeOctNode& node,int& idx) { node.nodeData.nodeIndex=idx; idx++; if(node.children) {for(int i=0;i inline int Octree::NonLinearSplatOrientedPoint(TreeOctNode* node,const Point3D& position,const Point3D& normal) { double x,dxdy,dxdydz,dx[DIMENSION][3]; int i,j,k; TreeOctNode::Neighbors& neighbors=neighborKey.setNeighbors(node); double twidth; Point3D center; Real w; node->centerAndWidth(center,w); twidth=w; for(i=0;i<3;i++) { x=(center.coords[i]-position.coords[i]-twidth)/twidth; dx[i][0]=1.125+1.500*x+0.500*x*x; x=(center.coords[i]-position.coords[i])/twidth; dx[i][1]=0.750 - x*x; dx[i][2]=1.0-dx[i][1]-dx[i][0]; } for(i=0;i<3;i++) { for(j=0;j<3;j++) { dxdy=dx[0][i]*dx[1][j]; for(k=0;k<3;k++) { if(neighbors.neighbors[i][j][k]) { dxdydz=dxdy*dx[2][k]; int idx=neighbors.neighbors[i][j][k]->nodeData.nodeIndex; if(idx<0) { Point3D n; n.coords[0]=n.coords[1]=n.coords[2]=0; idx=neighbors.neighbors[i][j][k]->nodeData.nodeIndex=int(normals->size()); normals->push_back(n); } (*normals)[idx].coords[0]+=Real(normal.coords[0]*dxdydz); (*normals)[idx].coords[1]+=Real(normal.coords[1]*dxdydz); (*normals)[idx].coords[2]+=Real(normal.coords[2]*dxdydz); } } } } return 0; } template inline void Octree::NonLinearSplatOrientedPoint(const Point3D& position,const Point3D& normal,const int& splatDepth,const Real& samplesPerNode, const int& minDepth,const int& maxDepth) { double dx; Point3D n; TreeOctNode* temp; int i; double twidth; Point3D myCenter; Real myWidth; myCenter.coords[0]=myCenter.coords[1]=myCenter.coords[2]=Real(0.5); myWidth=Real(1.0); temp=&tree; while(temp->depth()children) { printf("Octree::NonLinearSplatOrientedPoint error\n"); return; } int cIndex=TreeOctNode::CornerIndex(myCenter,position); temp=&temp->children[cIndex]; myWidth/=2; if(cIndex&1){myCenter.coords[0]+=myWidth/2;} else {myCenter.coords[0]-=myWidth/2;} if(cIndex&2){myCenter.coords[1]+=myWidth/2;} else {myCenter.coords[1]-=myWidth/2;} if(cIndex&4){myCenter.coords[2]+=myWidth/2;} else {myCenter.coords[2]-=myWidth/2;} } Real alpha,newDepth; NonLinearGetSampleDepthAndWeight(temp,position,samplesPerNode,newDepth,alpha); if(newDepthmaxDepth) {newDepth=Real(maxDepth);} int topDepth=int(ceil(newDepth)); dx=1.0-(topDepth-newDepth); if(topDepth<=minDepth) { topDepth=minDepth; dx=1; } else if(topDepth>maxDepth) { topDepth=maxDepth; dx=1; } while(temp->depth()>topDepth) {temp=temp->parent;} while(temp->depth()children) {temp->initChildren();} int cIndex=TreeOctNode::CornerIndex(myCenter,position); temp=&temp->children[cIndex]; myWidth/=2; if(cIndex&1){myCenter.coords[0]+=myWidth/2;} else {myCenter.coords[0]-=myWidth/2;} if(cIndex&2){myCenter.coords[1]+=myWidth/2;} else {myCenter.coords[1]-=myWidth/2;} if(cIndex&4){myCenter.coords[2]+=myWidth/2;} else {myCenter.coords[2]-=myWidth/2;} } twidth=1.0/(1<depth()); for(i=0;iEPSILON) { dx=Real(1.0-dx); temp=temp->parent; twidth=1.0/(1<depth()); for(i=0;i inline void Octree::NonLinearGetSampleDepthAndWeight(TreeOctNode* node,const Point3D& position,const Real& samplesPerNode,Real& depth,Real& weight) { TreeOctNode* temp=node; weight=Real(1.0)/NonLinearGetSampleWeight(temp,position); if(weight>=samplesPerNode+1) {depth=Real(temp->depth()+log(weight/(samplesPerNode+1))/log(double(1<<(DIMENSION-1))));} else { Real oldAlpha,newAlpha; oldAlpha=newAlpha=weight; while(newAlpha<(samplesPerNode+1) && temp->parent) { temp=temp->parent; oldAlpha=newAlpha; newAlpha=Real(1.0)/NonLinearGetSampleWeight(temp,position); } depth=Real(temp->depth()+log(newAlpha/(samplesPerNode+1))/log(newAlpha/oldAlpha)); } weight=Real(pow(double(1<<(DIMENSION-1)),-double(depth))); } template inline Real Octree::NonLinearGetSampleWeight(TreeOctNode* node,const Point3D& position) { Real weight=0; double x,dxdy,dx[DIMENSION][3]; int i,j,k; TreeOctNode::Neighbors& neighbors=neighborKey.setNeighbors(node); double twidth; Point3D center; Real w; node->centerAndWidth(center,w); twidth=w; for(i=0;inodeData.centerWeightContribution); } } } } return Real(1.0/weight); } template inline int Octree::NonLinearUpdateWeightContribution(TreeOctNode* node,const Point3D& position,const Real& weight) { int i,j,k; TreeOctNode::Neighbors& neighbors=neighborKey.setNeighbors(node); double x,dxdy,dx[DIMENSION][3]; double twidth; Point3D center; Real w; node->centerAndWidth(center,w); twidth=w; for(i=0;inodeData.centerWeightContribution+=Real(dxdy*dx[2][k]);} } } } return 0; } template inline int Octree::setTree(vtkSmartPointer data,const int& maxDepth, const int& kernelDepth,const Real& samplesPerNode,const Real& scaleFactor,Point3D& center,Real& scale, const int& resetSamples,const int& useConfidence) { vtkSmartPointer dataNormals = vtkFloatArray::SafeDownCast(data->GetPointData()->GetNormals("Normals")); if(!dataNormals) { //vtkErrorMacro("The data set does not contain normals!"); cout << "The data set does not contain normals! This is a fatal error!" << endl; return 0; } Point3D min,max,position,normal,myCenter; Real myWidth; TreeOctNode* temp; int splatDepth=0; TreeNodeData::UseIndex=1; neighborKey.set(maxDepth); splatDepth=kernelDepth; if(splatDepth<0) { splatDepth=0; } // Get the center and scale double bounds[6]; data->GetBounds(bounds); //xmin, xmax, ymin, ymax, zmin, zmax min.coords[0] = bounds[0]; max.coords[0] = bounds[1]; min.coords[1] = bounds[2]; max.coords[1] = bounds[3]; min.coords[2] = bounds[4]; max.coords[2] = bounds[5]; DumpOutput("Setting bounding box\n"); for(unsigned int i = 0; i < DIMENSION; i++) { if(scale0) { DumpOutput("Setting sample weights\n"); for(vtkIdType p = 0; p < data->GetNumberOfPoints(); p++) { double coordinate[3]; data->GetPoint(p, coordinate); double n[3]; dataNormals->GetTuple(p, n); for(unsigned int dim = 0; dim < DIMENSION; dim++) { position.coords[dim]=(coordinate[dim]-center.coords[dim])/scale; normal.coords[dim]=n[dim]; } myCenter.coords[0]=myCenter.coords[1]=myCenter.coords[2]=Real(0.5); myWidth=Real(1.0); for(unsigned int dim = 0; dim < DIMENSION; dim++) { if(position.coords[dim]myCenter.coords[dim]+myWidth/2.0) { break; } } temp=&tree; int d=0; Real weight=Real(1.0); if(useConfidence) { weight=Real(Length(normal)); } while(dchildren) { temp->initChildren(); } int cIndex=TreeOctNode::CornerIndex(myCenter,position); temp=&temp->children[cIndex]; myWidth/=2; if(cIndex&1) { myCenter.coords[0]+=myWidth/2; } else { myCenter.coords[0]-=myWidth/2; } if(cIndex&2) { myCenter.coords[1]+=myWidth/2; } else { myCenter.coords[1]-=myWidth/2; } if(cIndex&4) { myCenter.coords[2]+=myWidth/2; } else { myCenter.coords[2]-=myWidth/2; } d++; } NonLinearUpdateWeightContribution(temp,position,weight); } } DumpOutput("Adding Points and Normals\n"); this->normals=new std::vector >(); for(vtkIdType p = 0; p < data->GetNumberOfPoints(); p++) { double coordinate[3]; data->GetPoint(p, coordinate); double n[3]; dataNormals->GetTuple(p, n); for(unsigned int dim = 0; dim < DIMENSION; dim++) { position.coords[dim]=(coordinate[dim]-center.coords[dim])/scale; normal.coords[dim]=n[dim]; } myCenter.coords[0]=myCenter.coords[1]=myCenter.coords[2]=Real(0.5); myWidth=Real(1.0); for(unsigned int dim = 0; dim < DIMENSION; dim++) { if(position.coords[dim]myCenter.coords[dim]+myWidth/2.0) { break; } } Real l=Real(Length(normal)); if(l0 && splatDepth) { NonLinearSplatOrientedPoint(position,normal,splatDepth,samplesPerNode,1,maxDepth); } else { Real alpha=1; temp=&tree; int d=0; if(splatDepth) { while(dchildren[cIndex]; myWidth/=2; if(cIndex&1){myCenter.coords[0]+=myWidth/2;} else {myCenter.coords[0]-=myWidth/2;} if(cIndex&2){myCenter.coords[1]+=myWidth/2;} else {myCenter.coords[1]-=myWidth/2;} if(cIndex&4){myCenter.coords[2]+=myWidth/2;} else {myCenter.coords[2]-=myWidth/2;} d++; } alpha=NonLinearGetSampleWeight(temp,position); } for(unsigned int dim = 0; dim < DIMENSION; dim++) { normal.coords[dim] *= alpha; } while(dchildren) { temp->initChildren(); } int cIndex=TreeOctNode::CornerIndex(myCenter,position); temp=&temp->children[cIndex]; myWidth/=2; if(cIndex&1) { myCenter.coords[0]+=myWidth/2; } else { myCenter.coords[0]-=myWidth/2; } if(cIndex&2) { myCenter.coords[1]+=myWidth/2; } else { myCenter.coords[1]-=myWidth/2; } if(cIndex&4) { myCenter.coords[2]+=myWidth/2; } else { myCenter.coords[2]-=myWidth/2; } d++; } NonLinearSplatOrientedPoint(temp,position,normal); } } return 1; //success? used to return cnt } template inline void Octree::setFunctionData(const PPolynomial& ReconstructionFunction, const int& maxDepth,const int& normalize,const Real& normalSmooth) { radius=Real(fabs(ReconstructionFunction.polys[0].start)); width=int(double(radius+0.5-EPSILON)*2); if(normalSmooth>0){postNormalSmooth=normalSmooth;} fData.set(maxDepth,ReconstructionFunction,normalize,1); } template inline void Octree::finalize1(const int& refineNeighbors) { TreeOctNode* temp; if(refineNeighbors>=0){ RefineFunction rf; temp=tree.nextNode(); while(temp){ if(temp->nodeData.nodeIndex>=0 && Length((*normals)[temp->nodeData.nodeIndex])>EPSILON){ rf.depth=temp->depth()-refineNeighbors; TreeOctNode::ProcessMaxDepthNodeAdjacentNodes(fData.depth,temp,2*width,&tree,1,temp->depth()-refineNeighbors,&rf); } temp=tree.nextNode(temp); } } else if(refineNeighbors==-1234){ temp=tree.nextLeaf(); while(temp){ if(!temp->children && temp->depth()initChildren();} temp=tree.nextLeaf(temp); } } } template inline void Octree::finalize2(const int& refineNeighbors) { TreeOctNode* temp; if(refineNeighbors>=0){ RefineFunction rf; temp=tree.nextNode(); while(temp){ if(fabs(temp->nodeData.value)>EPSILON){ rf.depth=temp->depth()-refineNeighbors; TreeOctNode::ProcessMaxDepthNodeAdjacentNodes(fData.depth,temp,2*width,&tree,1,temp->depth()-refineNeighbors,&rf); } temp=tree.nextNode(temp); } } } template inline Real Octree::GetDivergence(const int idx[DIMENSION],const Point3D& normal) const { double dot=fData.dotTable[idx[0]]*fData.dotTable[idx[1]]*fData.dotTable[idx[2]]; return Real(dot*(fData.dDotTable[idx[0]]*normal.coords[0]+fData.dDotTable[idx[1]]*normal.coords[1]+fData.dDotTable[idx[2]]*normal.coords[2])); } template inline Real Octree::GetLaplacian(const int idx[DIMENSION]) const { return Real(fData.dotTable[idx[0]]*fData.dotTable[idx[1]]*fData.dotTable[idx[2]]*(fData.d2DotTable[idx[0]]+fData.d2DotTable[idx[1]]+fData.d2DotTable[idx[2]])); } template inline Real Octree::GetDotProduct(const int idx[DIMENSION]) const { return Real(fData.dotTable[idx[0]]*fData.dotTable[idx[1]]*fData.dotTable[idx[2]]); } template inline int Octree::GetFixedDepthLaplacian(SparseSymmetricMatrix& matrix,const int& depth,const SortedTreeNodes& sNodes) { LaplacianMatrixFunction mf; mf.ot=this; mf.offset=sNodes.nodeCount[depth]; matrix.Resize(sNodes.nodeCount[depth+1]-sNodes.nodeCount[depth]); mf.rowElements=(MatrixEntry*)malloc(sizeof(MatrixEntry)*matrix.rows); for(int i=sNodes.nodeCount[depth];id); mf.x2=int(sNodes.treeNodes[i]->off[0]); mf.y2=int(sNodes.treeNodes[i]->off[1]); mf.z2=int(sNodes.treeNodes[i]->off[2]); mf.index[0]=mf.x2; mf.index[1]=mf.y2; mf.index[2]=mf.z2; TreeOctNode::ProcessTerminatingNodeAdjacentNodes(fData.depth,sNodes.treeNodes[i],2*width-1,&tree,1,&mf); matrix.SetRowSize(i-sNodes.nodeCount[depth],mf.elementCount); memcpy(matrix.m_ppElements[i-sNodes.nodeCount[depth]],mf.rowElements,sizeof(MatrixEntry)*mf.elementCount); } free(mf.rowElements); return 1; } template inline int Octree::GetRestrictedFixedDepthLaplacian(SparseSymmetricMatrix& matrix,const int& depth,const int* entries,const int& entryCount, const TreeOctNode* rNode,const Real& iRadius, const SortedTreeNodes& sNodes){ (void) depth; int i; RestrictedLaplacianMatrixFunction mf; //NOTE: myRadius was unused (so I commented it) //Real myRadius=int(2*iRadius-ROUND_EPS)+ROUND_EPS; mf.ot=this; mf.radius=iRadius; rNode->depthAndOffset(mf.depth,mf.offset); matrix.Resize(entryCount); mf.rowElements=(MatrixEntry*)malloc(sizeof(MatrixEntry)*matrix.rows); for(i=0;inodeData.nodeIndex=i;} for(i=0;ioff[0]); mf.index[1]=int(sNodes.treeNodes[entries[i]]->off[1]); mf.index[2]=int(sNodes.treeNodes[entries[i]]->off[2]); TreeOctNode::ProcessTerminatingNodeAdjacentNodes(fData.depth,sNodes.treeNodes[entries[i]],2*width-1,&tree,1,&mf); matrix.SetRowSize(i,mf.elementCount); memcpy(matrix.m_ppElements[i],mf.rowElements,sizeof(MatrixEntry)*mf.elementCount); } for(i=0;inodeData.nodeIndex=entries[i];} free(mf.rowElements); return 1; } template inline int Octree::LaplacianMatrixIteration(const int& subdivideDepth) { int i,iter=0; SortedTreeNodes sNodes; fData.setDotTables(fData.D2_DOT_FLAG); sNodes.set(tree,1); SparseMatrix::SetAllocator(MEMORY_ALLOCATOR_BLOCK_SIZE); sNodes.treeNodes[0]->nodeData.value=0; for(i=1;i0) { iter+=SolveFixedDepthMatrix(i,subdivideDepth,sNodes); } else { iter+=SolveFixedDepthMatrix(i,sNodes); } } SparseMatrix::MatrixAllocator.reset(); fData.clearDotTables(fData.DOT_FLAG | fData.D_DOT_FLAG | fData.D2_DOT_FLAG); return iter; } template inline int Octree::SolveFixedDepthMatrix(const int& depth,const SortedTreeNodes& sNodes) { int i,iter=0; Vector V,Solution; SparseSymmetricMatrix matrix; Vector Diagonal; V.Resize(sNodes.nodeCount[depth+1]-sNodes.nodeCount[depth]); for(i=sNodes.nodeCount[depth];inodeData.value; } SparseSymmetricMatrix::MatrixAllocator.rollBack(); GetFixedDepthLaplacian(matrix,depth,sNodes); //DumpOutput("\tMatrix entries: %d / %d^2 = %.4f%%\n",matrix.Entries(),matrix.rows,100.0*(matrix.Entries()/double(matrix.rows))/matrix.rows); // DumpOutput("\tMemory Usage: %.3f MB\n",float(MemoryUsage())); iter+=SparseSymmetricMatrix::Solve(matrix,V,int(pow(matrix.rows,ITERATION_POWER)),Solution,double(EPSILON),1); for(i=sNodes.nodeCount[depth];inodeData.value=Real(Solution[i-sNodes.nodeCount[depth]]); } Real myRadius=Real(radius+ROUND_EPS-0.5); myRadius /=(1<children){continue;} x1=int(node1->off[0]); y1=int(node1->off[1]); z1=int(node1->off[2]); for(int j=0;joff[0]); y2=int(node2->off[1]); z2=int(node2->off[2]); pf.value=Solution[idx2]; pf.index[0]=x2; pf.index[1]=y2; pf.index[2]=z2; dx=Real(x2-x1)/(1<processNodeNodes(node2,&pf,0); } else { TreeOctNode::ProcessNodeAdjacentNodes(fData.depth,node2,width,node1,width,&pf,0); } } } // Second pass: idx1 is the solution coefficient propogated for(i=0;ioff[0]); y1=int(node1->off[1]); z1=int(node1->off[2]); pf.value=Solution[idx1]; pf.index[0]=x1; pf.index[1]=y1; pf.index[2]=z1; for(int j=0;jchildren) { x2=int(node2->off[0]); y2=int(node2->off[1]); z2=int(node2->off[2]); dx=Real(x1-x2)/(1<processNodeNodes(node1,&pf,0); } else { TreeOctNode::ProcessNodeAdjacentNodes(fData.depth,node1,width,node2,width,&pf,0); } } } } } //DumpOutput("\tGot / Solved / Updated in: %6.3f / %6.3f / %6.3f\n",gTime,sTime,uTime); return iter; } template inline int Octree::SolveFixedDepthMatrix(const int& depth,const int& startingDepth,const SortedTreeNodes& sNodes) { int i,j,d,iter=0; SparseSymmetricMatrix matrix; AdjacencySetFunction asf; AdjacencyCountFunction acf; Vector Values; Vector SubValues,SubSolution; Real dx,dy,dz; Vector Diagonal; if(startingDepth>=depth){return SolveFixedDepthMatrix(depth,sNodes);} Values.Resize(sNodes.nodeCount[depth+1]-sNodes.nodeCount[depth]); for(i=sNodes.nodeCount[depth];inodeData.value; sNodes.treeNodes[i]->nodeData.value=0; } Real myRadius=2*radius-Real(0.5); myRadius=int(myRadius-ROUND_EPS)+ROUND_EPS; Real myRadius2=Real(radius+ROUND_EPS-0.5); d=depth-startingDepth; for(i=sNodes.nodeCount[d];inextNode(); while(temp){ if(temp->depth()==depth){ acf.Function(temp,temp); temp=sNodes.treeNodes[i]->nextBranch(temp); } else{temp=sNodes.treeNodes[i]->nextNode(temp);} } for(j=sNodes.nodeCount[d];jnextNode(); while(temp){ if(temp->depth()==depth){ asf.Function(temp,temp); temp=sNodes.treeNodes[i]->nextBranch(temp); } else{temp=sNodes.treeNodes[i]->nextNode(temp);} } for(j=sNodes.nodeCount[d];jnodeData.value;} // Get the associated matrix SparseSymmetricMatrix::MatrixAllocator.rollBack(); GetRestrictedFixedDepthLaplacian(matrix,depth,asf.adjacencies,asf.adjacencyCount,sNodes.treeNodes[i],myRadius,sNodes); //DumpOutput("\t\tMatrix entries: %d / %d^2 = %.4f%%\n",matrix.Entries(),matrix.rows,100.0*(matrix.Entries()/double(matrix.rows))/matrix.rows); //DumpOutput("\t\tMemory Usage: %.3f MB\n",float(MemoryUsage())); // Solve the matrix iter+=SparseSymmetricMatrix::Solve(matrix,SubValues,int(pow(matrix.rows,ITERATION_POWER)),SubSolution,double(EPSILON),0); LaplacianProjectionFunction lpf; lpf.ot=this; // Update the solution for all nodes in the sub-tree for(j=0;jdepth()>sNodes.treeNodes[i]->depth()) { temp=temp->parent; } if(temp->nodeData.nodeIndex>=sNodes.treeNodes[i]->nodeData.nodeIndex) { sNodes.treeNodes[asf.adjacencies[j]]->nodeData.value=Real(SubSolution[j]); } } //NOTE: t was unused (so I commented it) //double t=Time(); // Update the values in the next depth if(depthchildren) { continue; } x1=int(node1->off[0]); y1=int(node1->off[1]); z1=int(node1->off[2]); for(int k=0;kdepth()>d) { temp=temp->parent; } if(temp!=sNodes.treeNodes[i]) { continue; } lpf.value=Real(SubSolution[matrix.m_ppElements[j][k].N]); x2=int(node2->off[0]); y2=int(node2->off[1]); z2=int(node2->off[2]); lpf.index[0]=x2; lpf.index[1]=y2; lpf.index[2]=z2; dx=Real(x2-x1)/(1<processNodeNodes(node2,&lpf,0); } else { TreeOctNode::ProcessNodeAdjacentNodes(fData.depth,node2,width,node1,width,&lpf,0); } } } // Second pass: idx1 is the solution coefficient propogated for(j=0;jdepth()>d) { temp=temp->parent; } if(temp!=sNodes.treeNodes[i]) { continue; } x1=int(node1->off[0]); y1=int(node1->off[1]); z1=int(node1->off[2]); lpf.value=Real(SubSolution[j]); lpf.index[0]=x1; lpf.index[1]=y1; lpf.index[2]=z1; for(int k=0;kchildren) { continue; } if(idx1!=idx2) { x2=int(node2->off[0]); y2=int(node2->off[1]); z2=int(node2->off[2]); dx=Real(x1-x2)/(1<processNodeNodes(node1,&lpf,0); } else { TreeOctNode::ProcessNodeAdjacentNodes(fData.depth,node1,width,node2,width,&lpf,0); } } } } } //DumpOutput("\t\tGot / Solved / Updated in: %6.3f / %6.3f / %6.3f\n",gTime,sTime,uTime); delete[] asf.adjacencies; } return iter; } template inline int Octree::HasNormals(TreeOctNode* node,const Real& epsilon) { int hasNormals=0; if(node->nodeData.nodeIndex>=0 && Length((*normals)[node->nodeData.nodeIndex])>epsilon) { hasNormals=1; } if(node->children) { for(int i=0;ichildren[i],epsilon); } } return hasNormals; } template inline void Octree::ClipTree(void) { TreeOctNode* temp; temp=tree.nextNode(); while(temp) { if(temp->children) { int hasNormals=0; for(int i=0;ichildren[i],EPSILON); } if(!hasNormals) { temp->children=NULL; } } temp=tree.nextNode(temp); } } template inline void Octree::SetLaplacianWeights(void) { TreeOctNode* temp; fData.setDotTables(fData.DOT_FLAG | fData.D_DOT_FLAG); DivergenceFunction df; df.ot=this; temp=tree.nextNode(); while(temp){ if(temp->nodeData.nodeIndex<0 || Length((*normals)[temp->nodeData.nodeIndex])<=EPSILON){ temp=tree.nextNode(temp); continue; } //NOTE: d was unused (so I commented it) // int d=temp->depth(); df.normal=(*normals)[temp->nodeData.nodeIndex]; df.index[0]=int(temp->off[0]); df.index[1]=int(temp->off[1]); df.index[2]=int(temp->off[2]); TreeOctNode::ProcessNodeAdjacentNodes(fData.depth,temp,width,&tree,width,&df); temp=tree.nextNode(temp); } fData.clearDotTables(fData.D_DOT_FLAG); temp=tree.nextNode(); while(temp){ if(temp->nodeData.nodeIndex<0){temp->nodeData.centerWeightContribution=0;} else{temp->nodeData.centerWeightContribution=Real(Length((*normals)[temp->nodeData.nodeIndex]));} temp=tree.nextNode(temp); } // MemoryUsage(); delete normals; normals=NULL; } template inline void Octree::DivergenceFunction::Function(TreeOctNode* node1,const TreeOctNode* node2) { (void) node2; Point3D n=normal; if(FunctionData::SymmetricIndex(index[0],int(node1->off[0]),scratch[0])){n.coords[0]=-n.coords[0];} if(FunctionData::SymmetricIndex(index[1],int(node1->off[1]),scratch[1])){n.coords[1]=-n.coords[1];} if(FunctionData::SymmetricIndex(index[2],int(node1->off[2]),scratch[2])){n.coords[2]=-n.coords[2];} double dot=ot->fData.dotTable[scratch[0]]*ot->fData.dotTable[scratch[1]]*ot->fData.dotTable[scratch[2]]; node1->nodeData.value+=Real(dot*(ot->fData.dDotTable[scratch[0]]*n.coords[0]+ot->fData.dDotTable[scratch[1]]*n.coords[1]+ot->fData.dDotTable[scratch[2]]*n.coords[2])); } template inline void Octree::LaplacianProjectionFunction::Function(TreeOctNode* node1,const TreeOctNode* node2) { (void) node2; scratch[0]=FunctionData::SymmetricIndex(index[0],int(node1->off[0])); scratch[1]=FunctionData::SymmetricIndex(index[1],int(node1->off[1])); scratch[2]=FunctionData::SymmetricIndex(index[2],int(node1->off[2])); node1->nodeData.value-=Real(ot->GetLaplacian(scratch)*value); } template inline void Octree::AdjacencyCountFunction::Function(const TreeOctNode* node1,const TreeOctNode* node2) { (void) node1; (void) node2; adjacencyCount++; } template inline void Octree::AdjacencySetFunction::Function(const TreeOctNode* node1,const TreeOctNode* node2) { (void) node2; adjacencies[adjacencyCount++]=node1->nodeData.nodeIndex; } template inline void Octree::RefineFunction::Function(TreeOctNode* node1,const TreeOctNode* node2) { (void) node2; if(!node1->children && node1->depth()initChildren();} } template inline void Octree::FaceEdgesFunction::Function(const TreeOctNode* node1,const TreeOctNode* node2) { (void) node2; if(!node1->children && MarchingCubes::HasRoots(node1->nodeData.mcIndex)){ RootInfo ri1,ri2; hash_map >::iterator iter; int isoTri[DIMENSION*MarchingCubes::MAX_TRIANGLES]; int count=MarchingCubes::AddTriangleIndices(node1->nodeData.mcIndex,isoTri); for(int j=0;jpush_back(std::pair(ri2.key,ri1.key)); iter=vertexCount->find(ri1.key); if(iter==vertexCount->end()){ (*vertexCount)[ri1.key].first=ri1; (*vertexCount)[ri1.key].second=0; } iter=vertexCount->find(ri2.key); if(iter==vertexCount->end()){ (*vertexCount)[ri2.key].first=ri2; (*vertexCount)[ri2.key].second=0; } (*vertexCount)[ri1.key].second--; (*vertexCount)[ri2.key].second++; } else{fprintf(stderr,"Bad Edge 1: %lld %lld\n",ri1.key,ri2.key);} } } } } } template inline void Octree::PointIndexValueFunction::Function(const TreeOctNode* node) { int idx[DIMENSION]; idx[0]=index[0]+int(node->off[0]); idx[1]=index[1]+int(node->off[1]); idx[2]=index[2]+int(node->off[2]); value+=node->nodeData.value* Real( valueTables[idx[0]]* valueTables[idx[1]]* valueTables[idx[2]]); } template inline void Octree::PointIndexValueAndNormalFunction::Function(const TreeOctNode* node) { int idx[DIMENSION]; idx[0]=index[0]+int(node->off[0]); idx[1]=index[1]+int(node->off[1]); idx[2]=index[2]+int(node->off[2]); value+= node->nodeData.value* Real( valueTables[idx[0]]* valueTables[idx[1]]* valueTables[idx[2]]); normal.coords[0]+= node->nodeData.value* Real(dValueTables[idx[0]]* valueTables[idx[1]]* valueTables[idx[2]]); normal.coords[1]+= node->nodeData.value* Real( valueTables[idx[0]]*dValueTables[idx[1]]* valueTables[idx[2]]); normal.coords[2]+= node->nodeData.value* Real( valueTables[idx[0]]* valueTables[idx[1]]*dValueTables[idx[2]]); } template inline int Octree::LaplacianMatrixFunction::Function(const TreeOctNode* node1,const TreeOctNode* node2) { Real temp; int d1=int(node1->d); int x1,y1,z1; x1=int(node1->off[0]); y1=int(node1->off[1]); z1=int(node1->off[2]); int dDepth=d2-d1; int d; d=(x2>>dDepth)-x1; if(d<0){return 0;} if(!dDepth){ if(!d){ d=y2-y1; if(d<0){return 0;} else if(!d){ d=z2-z1; if(d<0){return 0;} } } scratch[0]=FunctionData::SymmetricIndex(index[0],x1); scratch[1]=FunctionData::SymmetricIndex(index[1],y1); scratch[2]=FunctionData::SymmetricIndex(index[2],z1); temp=ot->GetLaplacian(scratch); if(node1==node2){temp/=2;} if(fabs(temp)>EPSILON){ rowElements[elementCount].Value=temp; rowElements[elementCount].N=node1->nodeData.nodeIndex-offset; elementCount++; } return 0; } return 1; } template inline int Octree::RestrictedLaplacianMatrixFunction::Function(const TreeOctNode* node1,const TreeOctNode* node2) { int d1,d2,off1[3],off2[3]; node1->depthAndOffset(d1,off1); node2->depthAndOffset(d2,off2); int dDepth=d2-d1; int d; d=(off2[0]>>dDepth)-off1[0]; if(d<0){return 0;} if(!dDepth){ if(!d){ d=off2[1]-off1[1]; if(d<0){return 0;} else if(!d){ d=off2[2]-off1[2]; if(d<0){return 0;} } } // Since we are getting the restricted matrix, we don't want to propogate out to terms that don't contribute... if(!TreeOctNode::Overlap2(depth,offset,0.5,d1,off1,radius)){return 0;} scratch[0]=FunctionData::SymmetricIndex(index[0],BinaryNode::Index(d1,off1[0])); scratch[1]=FunctionData::SymmetricIndex(index[1],BinaryNode::Index(d1,off1[1])); scratch[2]=FunctionData::SymmetricIndex(index[2],BinaryNode::Index(d1,off1[2])); Real temp=ot->GetLaplacian(scratch); if(node1==node2){temp/=2;} if(fabs(temp)>EPSILON){ rowElements[elementCount].Value=temp; rowElements[elementCount].N=node1->nodeData.nodeIndex; elementCount++; } return 0; } return 1; } template inline void Octree::GetMCIsoTriangles(const Real& isoValue,CoredMeshData* mesh,const int& fullDepthIso,const int& nonLinearFit, bool addBarycenter) { TreeOctNode* temp; hash_map roots; hash_map > > *normalHash=new hash_map > >(); SetIsoSurfaceCorners(isoValue,0,fullDepthIso); // At the point all of the corner values have been set and all nodes are valid. Now it's just a matter // of running marching cubes. fData.setValueTables(fData.VALUE_FLAG | fData.D_VALUE_FLAG,0,postNormalSmooth); temp=tree.nextLeaf(); while(temp) { SetMCRootPositions(temp,0,isoValue,roots,NULL,*normalHash,NULL,NULL,mesh,nonLinearFit); temp=tree.nextLeaf(temp); } // MemoryUsage(); //DumpOutput("Normal Size: %.2f MB\n",double(sizeof(Point3D)*normalHash->size())/1000000); //DumpOutput("Set %d root positions in: %f\n",mesh->inCorePoints.size(),Time()-t); //DumpOutput("Memory Usage: %.3f MB\n",float(MemoryUsage())); fData.clearValueTables(); delete normalHash; //DumpOutput("Post deletion size: %.3f MB\n",float(MemoryUsage())); // Now get the iso-surfaces, running from finest nodes to coarsest in order to allow for edge propogation from // finer faces to coarser ones. temp=tree.nextLeaf(); while(temp) { GetMCIsoTriangles(temp,mesh,roots,NULL,NULL,0,0,addBarycenter); temp=tree.nextLeaf(temp); } //DumpOutput("Added triangles in: %f\n",Time()-t); //DumpOutput("Memory Usage: %.3f MB\n",float(MemoryUsage())); } template inline void Octree::GetMCIsoTriangles(const Real& isoValue,const int& subdivideDepth,CoredMeshData* mesh,const int& fullDepthIso,const int& nonLinearFit, bool addBarycenter) { TreeOctNode* temp; hash_map boundaryRoots,*interiorRoots; hash_map > > *boundaryNormalHash,*interiorNormalHash; std::vector >* interiorPoints; int sDepth; if(subdivideDepth<=0) { sDepth=0; } else { sDepth=fData.depth-subdivideDepth; } if(sDepth<0) { sDepth=0; } SetIsoSurfaceCorners(isoValue,sDepth,fullDepthIso); // At this point all of the corner values have been set and all nodes are valid. // Now it's just a matter of running marching cubes. boundaryNormalHash=new hash_map > >(); int offSet=0; SortedTreeNodes sNodes; sNodes.set(tree,0); fData.setValueTables(fData.VALUE_FLAG | fData.D_VALUE_FLAG,0,postNormalSmooth); // Set the root positions for all leaf nodes below the subdivide threshold SetBoundaryMCRootPositions(sDepth,isoValue,boundaryRoots,*boundaryNormalHash,mesh,nonLinearFit); for(int i=sNodes.nodeCount[sDepth];i(); interiorNormalHash=new hash_map > >(); interiorPoints=new std::vector >(); temp=sNodes.treeNodes[i]->nextLeaf(); while(temp){ if(MarchingCubes::HasRoots(temp->nodeData.mcIndex)){ SetMCRootPositions(temp,sDepth,isoValue,boundaryRoots,interiorRoots,*boundaryNormalHash,interiorNormalHash,interiorPoints,mesh,nonLinearFit); } temp=sNodes.treeNodes[i]->nextLeaf(temp); } delete interiorNormalHash; temp=sNodes.treeNodes[i]->nextLeaf(); while(temp){ GetMCIsoTriangles(temp,mesh,boundaryRoots,interiorRoots,interiorPoints,offSet,sDepth,addBarycenter); temp=sNodes.treeNodes[i]->nextLeaf(temp); } delete interiorRoots; delete interiorPoints; offSet=mesh->outOfCorePointCount(); } delete boundaryNormalHash; temp=tree.nextLeaf(); while(temp){ if(temp->depth() inline Real Octree::getCenterValue(const TreeOctNode* node) { int idx[3]; Real value=0; neighborKey2.getNeighbors(node); VertexData::CenterIndex(node,fData.depth,idx); idx[0]*=fData.res; idx[1]*=fData.res; idx[2]*=fData.res; for(int i=0;i<=node->depth();i++){ for(int j=0;j<3;j++){ for(int k=0;k<3;k++){ for(int l=0;l<3;l++){ const TreeOctNode* n=neighborKey2.neighbors[i].neighbors[j][k][l]; if(n){ Real temp=n->nodeData.value; value+=temp*Real( fData.valueTables[idx[0]+int(n->off[0])]* fData.valueTables[idx[1]+int(n->off[1])]* fData.valueTables[idx[2]+int(n->off[2])]); } } } } } if(node->children){ for(int i=0;ichildren[i]; while(1){ value+=n->nodeData.value*Real( fData.valueTables[idx[0]+int(n->off[0])]* fData.valueTables[idx[1]+int(n->off[1])]* fData.valueTables[idx[2]+int(n->off[2])]); if(n->children){n=&n->children[ii];} else{break;} } } } return value; } template inline Real Octree::getCornerValue(const TreeOctNode* node,const int& corner) { int idx[3]; Real value=0; neighborKey2.getNeighbors(node); VertexData::CornerIndex(node,corner,fData.depth,idx); idx[0]*=fData.res; idx[1]*=fData.res; idx[2]*=fData.res; for(int i=0;i<=node->depth();i++){ for(int j=0;j<3;j++){ for(int k=0;k<3;k++){ for(int l=0;l<3;l++){ const TreeOctNode* n=neighborKey2.neighbors[i].neighbors[j][k][l]; if(n){ Real temp=n->nodeData.value; value+=temp*Real( fData.valueTables[idx[0]+int(n->off[0])]* fData.valueTables[idx[1]+int(n->off[1])]* fData.valueTables[idx[2]+int(n->off[2])]); } } } } } int x(0),y(0),z(0),d=node->depth(); Cube::FactorCornerIndex(corner,x,y,z); for(int i=0;i<2;i++){ for(int j=0;j<2;j++){ for(int k=0;k<2;k++){ const TreeOctNode* n=neighborKey2.neighbors[d].neighbors[x+i][y+j][z+k]; if(n){ int ii=Cube::AntipodalCornerIndex(Cube::CornerIndex(i,j,k)); while(n->children){ n=&n->children[ii]; value+=n->nodeData.value*Real( fData.valueTables[idx[0]+int(n->off[0])]* fData.valueTables[idx[1]+int(n->off[1])]* fData.valueTables[idx[2]+int(n->off[2])]); } } } } } return value; } template inline void Octree::getCornerValueAndNormal(const TreeOctNode* node,const int& corner,Real& value,Point3D& normal) { int idx[3],index[3]; value=normal.coords[0]=normal.coords[1]=normal.coords[2]=0; neighborKey2.getNeighbors(node); VertexData::CornerIndex(node,corner,fData.depth,idx); idx[0]*=fData.res; idx[1]*=fData.res; idx[2]*=fData.res; for(int i=0;i<=node->depth();i++){ for(int j=0;j<3;j++){ for(int k=0;k<3;k++){ for(int l=0;l<3;l++){ const TreeOctNode* n=neighborKey2.neighbors[i].neighbors[j][k][l]; if(n){ Real temp=n->nodeData.value; index[0]=idx[0]+int(n->off[0]); index[1]=idx[1]+int(n->off[1]); index[2]=idx[2]+int(n->off[2]); value+=temp*Real(fData.valueTables[index[0]]*fData.valueTables[index[1]]*fData.valueTables[index[2]]); normal.coords[0]+=temp*Real(fData.dValueTables[index[0]]* fData.valueTables[index[1]]* fData.valueTables[index[2]]); normal.coords[1]+=temp*Real( fData.valueTables[index[0]]*fData.dValueTables[index[1]]* fData.valueTables[index[2]]); normal.coords[2]+=temp*Real( fData.valueTables[index[0]]* fData.valueTables[index[1]]*fData.dValueTables[index[2]]); } } } } } int x(0),y(0),z(0),d=node->depth(); Cube::FactorCornerIndex(corner,x,y,z); for(int i=0;i<2;i++){ for(int j=0;j<2;j++){ for(int k=0;k<2;k++){ const TreeOctNode* n=neighborKey2.neighbors[d].neighbors[x+i][y+j][z+k]; if(n){ int ii=Cube::AntipodalCornerIndex(Cube::CornerIndex(i,j,k)); while(n->children){ n=&n->children[ii]; Real temp=n->nodeData.value; index[0]=idx[0]+int(n->off[0]); index[1]=idx[1]+int(n->off[1]); index[2]=idx[2]+int(n->off[2]); value+=temp*Real(fData.valueTables[index[0]]*fData.valueTables[index[1]]*fData.valueTables[index[2]]); normal.coords[0]+=temp*Real(fData.dValueTables[index[0]]* fData.valueTables[index[1]]* fData.valueTables[index[2]]); normal.coords[1]+=temp*Real( fData.valueTables[index[0]]*fData.dValueTables[index[1]]* fData.valueTables[index[2]]); normal.coords[2]+=temp*Real( fData.valueTables[index[0]]* fData.valueTables[index[1]]*fData.dValueTables[index[2]]); } } } } } } template inline Real Octree::GetIsoValue(void) { if(this->width<=3){ TreeOctNode* temp; Real isoValue,weightSum,w; neighborKey2.set(fData.depth); fData.setValueTables(fData.VALUE_FLAG,0); isoValue=weightSum=0; temp=tree.nextNode(); while(temp){ w=temp->nodeData.centerWeightContribution; if(w>EPSILON){ isoValue+=getCenterValue(temp)*w; weightSum+=w; } temp=tree.nextNode(temp); } return isoValue/weightSum; } else{ const TreeOctNode* temp; Real isoValue,weightSum,w; PointIndexValueFunction cf; fData.setValueTables(fData.VALUE_FLAG,0); cf.valueTables=fData.valueTables; cf.res2=fData.res2; isoValue=weightSum=0; temp=tree.nextNode(); while(temp){ w=temp->nodeData.centerWeightContribution; if(w>EPSILON){ cf.value=0; int idx[3]; VertexData::CenterIndex(temp,fData.depth,idx); cf.index[0]=idx[0]*fData.res; cf.index[1]=idx[1]*fData.res; cf.index[2]=idx[2]*fData.res; TreeOctNode::ProcessPointAdjacentNodes(fData.depth,idx,&tree,width,&cf); isoValue+=cf.value*w; weightSum+=w; } temp=tree.nextNode(temp); } return isoValue/weightSum; } } template inline void Octree::SetIsoSurfaceCorners(const Real& isoValue,const int& subdivideDepth,const int& fullDepthIso) { (void) fullDepthIso; int i,j; hash_map values; Real cornerValues[Cube::CORNERS]; PointIndexValueFunction cf; TreeOctNode* temp; //NOTE: leafCount was unused (so I commented it) //int leafCount=tree.leaves(); long long key; SortedTreeNodes *sNodes=new SortedTreeNodes(); sNodes->set(tree,0); temp=tree.nextNode(); while(temp){ temp->nodeData.mcIndex=0; temp=tree.nextNode(temp); } TreeNodeData::UseIndex=0; // Start by setting the corner values of all the nodes cf.valueTables=fData.valueTables; cf.res2=fData.res2; for(i=0;inodeCount[subdivideDepth];i++){ temp=sNodes->treeNodes[i]; if(!temp->children){ for(j=0;jwidth<=3){cornerValues[j]=getCornerValue(temp,j);} else{ cf.value=0; int idx[3]; VertexData::CornerIndex(temp,j,fData.depth,idx); cf.index[0]=idx[0]*fData.res; cf.index[1]=idx[1]*fData.res; cf.index[2]=idx[2]*fData.res; TreeOctNode::ProcessPointAdjacentNodes(fData.depth,idx,&tree,width,&cf); cornerValues[j]=cf.value; } } temp->nodeData.mcIndex=MarchingCubes::GetIndex(cornerValues,isoValue); if(temp->parent){ TreeOctNode* parent=temp->parent; int c=int(temp-temp->parent->children); int mcid=temp->nodeData.mcIndex&(1<nodeData.mcIndex|=mcid; while(1){ if(parent->parent && (parent-parent->parent->children)==c){ parent->parent->nodeData.mcIndex|=mcid; parent=parent->parent; } else{break;} } } } } } // MemoryUsage(); for(i=sNodes->nodeCount[subdivideDepth];inodeCount[subdivideDepth+1];i++) { temp=sNodes->treeNodes[i]->nextLeaf(); while(temp) { for(j=0;jwidth<=3) { values[key]=cornerValues[j]=getCornerValue(temp,j); } else { cf.value=0; TreeOctNode::ProcessPointAdjacentNodes(fData.depth,idx,&tree,width,&cf); values[key]=cf.value; cornerValues[j]=cf.value; } } } temp->nodeData.mcIndex=MarchingCubes::GetIndex(cornerValues,isoValue); if(temp->parent){ TreeOctNode* parent=temp->parent; int c=int(temp-temp->parent->children); int mcid=temp->nodeData.mcIndex&(1<nodeData.mcIndex|=mcid; while(1){ if(parent->parent && (parent-parent->parent->children)==c){ parent->parent->nodeData.mcIndex|=mcid; parent=parent->parent; } else{break;} } } } temp=sNodes->treeNodes[i]->nextLeaf(temp); } values.clear(); } delete sNodes; //DumpOutput("Set corner values in: %f\n",Time()-t); //DumpOutput("Memory Usage: %.3f MB\n",float(MemoryUsage())); if(subdivideDepth) { PreValidate(isoValue,fData.depth,subdivideDepth); } } template inline void Octree::Subdivide(TreeOctNode* node,const Real& isoValue,const int& maxDepth) { int i,j,c[4]; Real value; int cornerIndex2[Cube::CORNERS]; PointIndexValueFunction cf; cf.valueTables=fData.valueTables; cf.res2=fData.res2; node->initChildren(); // Since we are allocating blocks, it is possible that some of the memory was pre-allocated with // the wrong initialization // Now set the corner values for the new children // Copy old corner values for(i=0;inodeData.mcIndex&(1<width<=3){value=getCenterValue(node);} else{ TreeOctNode::ProcessPointAdjacentNodes(fData.depth,idx,&tree,width,&cf); value=cf.value; } if(valuechildren[i].nodeData.mcIndex=cornerIndex2[i];} } template inline int Octree::InteriorFaceRootCount(const TreeOctNode* node,const int &faceIndex,const int& maxDepth) { int cnt=0; if(node->children) { int corners[Cube::CORNERS/2]; int e1,e2,dir,off; Cube::FaceCorners(faceIndex,corners[0],corners[1],corners[2],corners[3]); Cube::FactorFaceIndex(faceIndex,dir,off); int c1=corners[0]; int c2=corners[3]; switch(dir) { case 0: e1=Cube::EdgeIndex(1,off,1); e2=Cube::EdgeIndex(2,off,1); break; case 1: e1=Cube::EdgeIndex(0,off,1); e2=Cube::EdgeIndex(2,1,off); break; case 2: e1=Cube::EdgeIndex(0,1,off); e2=Cube::EdgeIndex(1,1,off); break; }; cnt+=EdgeRootCount(&node->children[c1],e1,maxDepth)+EdgeRootCount(&node->children[c1],e2,maxDepth); switch(dir) { case 0: e1=Cube::EdgeIndex(1,off,0); e2=Cube::EdgeIndex(2,off,0); break; case 1: e1=Cube::EdgeIndex(0,off,0); e2=Cube::EdgeIndex(2,0,off); break; case 2: e1=Cube::EdgeIndex(0,0,off); e2=Cube::EdgeIndex(1,0,off); break; }; cnt+=EdgeRootCount(&node->children[c2],e1,maxDepth)+EdgeRootCount(&node->children[c2],e2,maxDepth); for(int i=0;ichildren[corners[i]].children) { cnt+=InteriorFaceRootCount(&node->children[corners[i]],faceIndex,maxDepth); } } } return cnt; } template inline int Octree::EdgeRootCount(const TreeOctNode* node,const int& edgeIndex,const int& maxDepth) { int f1(0),f2(0),c1(0),c2(0); const TreeOctNode* temp; Cube::FacesAdjacentToEdge(edgeIndex,f1,f2); int eIndex; const TreeOctNode* finest=node; eIndex=edgeIndex; if(node->depth()faceNeighbor(f1); if(temp && temp->children){ finest=temp; eIndex=Cube::FaceReflectEdgeIndex(edgeIndex,f1); } else{ temp=node->faceNeighbor(f2); if(temp && temp->children){ finest=temp; eIndex=Cube::FaceReflectEdgeIndex(edgeIndex,f2); } else{ temp=node->edgeNeighbor(edgeIndex); if(temp && temp->children){ finest=temp; eIndex=Cube::EdgeReflectEdgeIndex(edgeIndex); } } } } Cube::EdgeCorners(eIndex,c1,c2); if(finest->children){return EdgeRootCount(&finest->children[c1],eIndex,maxDepth)+EdgeRootCount(&finest->children[c2],eIndex,maxDepth);} else{return MarchingCubes::HasEdgeRoots(finest->nodeData.mcIndex,eIndex);} } template inline int Octree::IsBoundaryFace(const TreeOctNode* node,const int& faceIndex,const int& subdivideDepth) { int dir(0),offset(0),d(0),o[3],idx(0); if(subdivideDepth<0){return 0;} if(node->d<=subdivideDepth){return 1;} Cube::FactorFaceIndex(faceIndex,dir,offset); node->depthAndOffset(d,o); idx=(int(o[dir])<<1) + (offset<<1); return !(idx%(2<<(int(node->d)-subdivideDepth))); } template inline int Octree::IsBoundaryEdge(const TreeOctNode* node,const int& edgeIndex,const int& subdivideDepth) { int dir(0),x(0),y(0); Cube::FactorEdgeIndex(edgeIndex,dir,x,y); return IsBoundaryEdge(node,dir,x,y,subdivideDepth); } template inline int Octree::IsBoundaryEdge(const TreeOctNode* node,const int& dir,const int& x,const int& y,const int& subdivideDepth) { int d=0,o[3],idx1=0,idx2=0,mask=0; if(subdivideDepth<0){return 0;} if(node->d<=subdivideDepth){return 1;} node->depthAndOffset(d,o); switch(dir){ case 0: idx1=(int(o[1])<<1) + (x<<1); idx2=(int(o[2])<<1) + (y<<1); break; case 1: idx1=(int(o[0])<<1) + (x<<1); idx2=(int(o[2])<<1) + (y<<1); break; case 2: idx1=(int(o[0])<<1) + (x<<1); idx2=(int(o[1])<<1) + (y<<1); break; } mask=2<<(int(node->d)-subdivideDepth); return !(idx1%(mask)) || !(idx2%(mask)); } template inline void Octree::PreValidate(TreeOctNode* node,const Real& isoValue,const int& maxDepth,const int& subdivideDepth) { int sub=0; if(node->children){printf("Bad Pre-Validate\n");} // if(int(node->d)faceNeighbor(i); if(neighbor && neighbor->children){ if(IsBoundaryFace(node,i,subdivideDepth) && InteriorFaceRootCount(neighbor,Cube::FaceReflectFaceIndex(i,i),maxDepth)){sub=1;} } } if(sub){ Subdivide(node,isoValue,maxDepth); for(int i=0;ifaceNeighbor(i); while(neighbor && !neighbor->children){ PreValidate(neighbor,isoValue,maxDepth,subdivideDepth); neighbor=node->faceNeighbor(i); } } } } } template inline void Octree::PreValidate(const Real& isoValue,const int& maxDepth,const int& subdivideDepth) { TreeOctNode* temp; temp=tree.nextLeaf(); while(temp){ PreValidate(temp,isoValue,maxDepth,subdivideDepth); temp=tree.nextLeaf(temp); } } template inline void Octree::Validate(TreeOctNode* node,const Real& isoValue,const int& maxDepth,const int& fullDepthIso) { int i,sub=0; TreeOctNode* treeNode=node; TreeOctNode* neighbor; if(node->depth()>=maxDepth || node->children){return;} // Check if full-depth extraction is enabled and we have an iso-node that is not at maximum depth if(!sub && fullDepthIso && MarchingCubes::HasRoots(node->nodeData.mcIndex)){sub=1;} // Check if the node has faces that are ambiguous and are adjacent to finer neighbors for(i=0;ifaceNeighbor(i); if(neighbor && neighbor->children){if(MarchingCubes::IsAmbiguous(node->nodeData.mcIndex,i)){sub=1;}} } // Check if the node has edges with more than one root for(i=0;i1){sub=1;}} for(i=0;ifaceNeighbor(i); if( neighbor && neighbor->children && !MarchingCubes::HasFaceRoots(node->nodeData.mcIndex,i) && InteriorFaceRootCount(neighbor,Cube::FaceReflectFaceIndex(i,i),maxDepth)){sub=1;} } if(sub){ Subdivide(node,isoValue,maxDepth); for(i=0;ifaceNeighbor(i); if(neighbor && !neighbor->children){Validate(neighbor,isoValue,maxDepth,fullDepthIso);} } for(i=0;iedgeNeighbor(i); if(neighbor && !neighbor->children){Validate(neighbor,isoValue,maxDepth,fullDepthIso);} } for(i=0;ichildren[i].children){Validate(&node->children[i],isoValue,maxDepth,fullDepthIso);}} } } template inline void Octree::Validate(TreeOctNode* node,const Real& isoValue,const int& maxDepth,const int& fullDepthIso,const int& subdivideDepth) { int i,sub=0; TreeOctNode* treeNode=node; TreeOctNode* neighbor; if(node->depth()>=maxDepth || node->children){return;} // Check if full-depth extraction is enabled and we have an iso-node that is not at maximum depth if(!sub && fullDepthIso && MarchingCubes::HasRoots(node->nodeData.mcIndex)){sub=1;} // Check if the node has faces that are ambiguous and are adjacent to finer neighbors for(i=0;ifaceNeighbor(i); if(neighbor && neighbor->children){if(MarchingCubes::IsAmbiguous(node->nodeData.mcIndex,i) || IsBoundaryFace(node,i,subdivideDepth)){sub=1;}} } // Check if the node has edges with more than one root for(i=0;i1){sub=1;}} for(i=0;ifaceNeighbor(i); if( neighbor && neighbor->children && !MarchingCubes::HasFaceRoots(node->nodeData.mcIndex,i) && InteriorFaceRootCount(neighbor,Cube::FaceReflectFaceIndex(i,i),maxDepth)){sub=1;} } if(sub){ Subdivide(node,isoValue,maxDepth); for(i=0;ifaceNeighbor(i); if(neighbor && !neighbor->children){Validate(neighbor,isoValue,maxDepth,fullDepthIso,subdivideDepth);} } for(i=0;iedgeNeighbor(i); if(neighbor && !neighbor->children){Validate(neighbor,isoValue,maxDepth,fullDepthIso,subdivideDepth);} } for(i=0;ichildren[i].children){Validate(&node->children[i],isoValue,maxDepth,fullDepthIso,subdivideDepth);}} } } ////////////////////////////////////////////////////////////////////////////////////// // The assumption made when calling this code is that the edge has at most one root // ////////////////////////////////////////////////////////////////////////////////////// template inline int Octree::GetRoot(const RootInfo& ri,const Real& isoValue,Point3D & position,hash_map > >& normalHash,const int& nonLinearFit) { int c1(0),c2(0); Cube::EdgeCorners(ri.edgeIndex,c1,c2); if(!MarchingCubes::HasEdgeRoots(ri.node->nodeData.mcIndex,ri.edgeIndex)){return 0;} long long key; Point3D n[2]; PointIndexValueAndNormalFunction cnf; cnf.valueTables=fData.valueTables; cnf.dValueTables=fData.dValueTables; cnf.res2=fData.res2; int i(0),o(0),i1(0),i2(0),rCount=0; Polynomial<2> P; std::vector roots; double x0,x1; Real center,twidth; Real averageRoot=0; Cube::FactorEdgeIndex(ri.edgeIndex,o,i1,i2); int idx[3]; key=VertexData::CornerIndex(ri.node,c1,fData.depth,idx); cnf.index[0]=idx[0]*fData.res; cnf.index[1]=idx[1]*fData.res; cnf.index[2]=idx[2]*fData.res; if(normalHash.find(key)==normalHash.end()){ cnf.value=0; cnf.normal.coords[0]=cnf.normal.coords[1]=cnf.normal.coords[2]=0; // Careful here as the normal isn't quite accurate... (i.e. postNormalSmooth is ignored) if(this->width<=3){getCornerValueAndNormal(ri.node,c1,cnf.value,cnf.normal);} else{TreeOctNode::ProcessPointAdjacentNodes(fData.depth,idx,&tree,this->width,&cnf);} normalHash[key]=std::pair >(cnf.value,cnf.normal); } x0=normalHash[key].first; n[0]=normalHash[key].second; key=VertexData::CornerIndex(ri.node,c2,fData.depth,idx); cnf.index[0]=idx[0]*fData.res; cnf.index[1]=idx[1]*fData.res; cnf.index[2]=idx[2]*fData.res; if(normalHash.find(key)==normalHash.end()){ cnf.value=0; cnf.normal.coords[0]=cnf.normal.coords[1]=cnf.normal.coords[2]=0; if(this->width<=3){getCornerValueAndNormal(ri.node,c2,cnf.value,cnf.normal);} else{TreeOctNode::ProcessPointAdjacentNodes(fData.depth,idx,&tree,this->width,&cnf);} normalHash[key]=std::pair >(cnf.value,cnf.normal); } x1=normalHash[key].first; n[1]=normalHash[key].second; Point3D c; ri.node->centerAndWidth(c,twidth); center=c.coords[o]; for(i=0;i=0 && roots[i]<=1){ averageRoot+=Real(roots[i]); rCount++; } } if(rCount && nonLinearFit) {averageRoot/=rCount;} else {averageRoot=Real((x0-isoValue)/(x0-x1));} if( averageRoot > 1 ) { averageRoot = 1;} if( averageRoot < -1 ) { averageRoot = -1;} position.coords[o]=Real(center-twidth/2+twidth*averageRoot); return 1; } template inline int Octree::GetRoot(const RootInfo& ri,const Real& isoValue,const int& maxDepth,Point3D& position,hash_map > >& Normals, Point3D* normal,const int& nonLinearFit) { (void) maxDepth; (void) normal; if(!MarchingCubes::HasRoots(ri.node->nodeData.mcIndex)){return 0;} return GetRoot(ri,isoValue,position,Normals,nonLinearFit); } template inline int Octree::GetRootIndex(const TreeOctNode* node,const int& edgeIndex,const int& maxDepth,const int& sDepth,RootInfo& ri) { int c1(0),c2(0),f1(0),f2(0); const TreeOctNode *temp,*finest; int finestIndex; Cube::FacesAdjacentToEdge(edgeIndex,f1,f2); finest=node; finestIndex=edgeIndex; if(node->depth()faceNeighbor(f1);} if(temp && temp->children){ finest=temp; finestIndex=Cube::FaceReflectEdgeIndex(edgeIndex,f1); } else{ if(IsBoundaryFace(node,f2,sDepth)){temp=NULL;} else{temp=node->faceNeighbor(f2);} if(temp && temp->children){ finest=temp; finestIndex=Cube::FaceReflectEdgeIndex(edgeIndex,f2); } else{ if(IsBoundaryEdge(node,edgeIndex,sDepth)){temp=NULL;} else{temp=node->edgeNeighbor(edgeIndex);} if(temp && temp->children){ finest=temp; finestIndex=Cube::EdgeReflectEdgeIndex(edgeIndex); } } } } Cube::EdgeCorners(finestIndex,c1,c2); if(finest->children){ if (GetRootIndex(&finest->children[c1],finestIndex,maxDepth,sDepth,ri)) {return 1;} else if (GetRootIndex(&finest->children[c2],finestIndex,maxDepth,sDepth,ri)) {return 1;} else {return 0;} } else{ if(!(MarchingCubes::edgeMask[finest->nodeData.mcIndex] & (1<depthAndOffset(d,off); ri.node=finest; ri.edgeIndex=finestIndex; int eIndex[2],offset; offset=BinaryNode::Index(d,off[o]); switch(o){ case 0: eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i1); eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); break; case 1: eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); break; case 2: eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i2); break; } ri.key = (long long)(o) | (long long)(eIndex[0])<<5 | (long long)(eIndex[1])<<25 | (long long)(offset)<<45; return 1; } } template inline int Octree::GetRootIndex(const TreeOctNode* node,const int& edgeIndex,const int& maxDepth,RootInfo& ri) { int c1(0),c2(0),f1(0),f2(0); const TreeOctNode *temp,*finest; int finestIndex; // The assumption is that the super-edge has a root along it. if(!(MarchingCubes::edgeMask[node->nodeData.mcIndex] & (1<depth()faceNeighbor(f1); if(temp && temp->children){ finest=temp; finestIndex=Cube::FaceReflectEdgeIndex(edgeIndex,f1); } else{ temp=node->faceNeighbor(f2); if(temp && temp->children){ finest=temp; finestIndex=Cube::FaceReflectEdgeIndex(edgeIndex,f2); } else{ temp=node->edgeNeighbor(edgeIndex); if(temp && temp->children){ finest=temp; finestIndex=Cube::EdgeReflectEdgeIndex(edgeIndex); } } } } Cube::EdgeCorners(finestIndex,c1,c2); if(finest->children){ if (GetRootIndex(&finest->children[c1],finestIndex,maxDepth,ri)) {return 1;} else if (GetRootIndex(&finest->children[c2],finestIndex,maxDepth,ri)) {return 1;} else {return 0;} } else{ int o,i1,i2; Cube::FactorEdgeIndex(finestIndex,o,i1,i2); int d,off[3]; finest->depthAndOffset(d,off); ri.node=finest; ri.edgeIndex=finestIndex; int offset,eIndex[2]; eIndex[0] = 0; eIndex[1] = 0; offset=BinaryNode::Index(d,off[o]); switch(o){ case 0: eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i1); eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); break; case 1: eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); break; case 2: eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i2); break; } ri.key= (long long)(o) | (long long)(eIndex[0])<<5 | (long long)(eIndex[1])<<25 | (long long)(offset)<<45; return 1; } } template inline int Octree::GetRootPair(const RootInfo& ri,const int& maxDepth,RootInfo& pair) { const TreeOctNode* node=ri.node; int c1(0),c2(0),c(0); Cube::EdgeCorners(ri.edgeIndex,c1,c2); while(node->parent){ c=int(node-node->parent->children); if(c!=c1 && c!=c2){return 0;} if(!MarchingCubes::HasEdgeRoots(node->parent->nodeData.mcIndex,ri.edgeIndex)){ if(c==c1){return GetRootIndex(&node->parent->children[c2],ri.edgeIndex,maxDepth,pair);} else{return GetRootIndex(&node->parent->children[c1],ri.edgeIndex,maxDepth,pair);} } node=node->parent; } return 0; } template inline int Octree::GetRootIndex(const long long& key,hash_map& boundaryRoots,hash_map* interiorRoots,CoredPointIndex& index) { hash_map::iterator rootIter=boundaryRoots.find(key); if(rootIter!=boundaryRoots.end()){ index.inCore=1; index.index=rootIter->second; return 1; } else if(interiorRoots){ rootIter=interiorRoots->find(key); if(rootIter!=interiorRoots->end()){ index.inCore=0; index.index=rootIter->second; return 1; } } return 0; } template inline int Octree::SetMCRootPositions(TreeOctNode* node,const int& sDepth,const Real& isoValue, hash_map& boundaryRoots,hash_map* interiorRoots, hash_map > >& boundaryNormalHash,hash_map > >* interiorNormalHash, std::vector >* interiorPositions, CoredMeshData* mesh,const int& nonLinearFit) { Point3D position; RootInfo ri; int count=0; if( MarchingCubes::HasRoots(node->nodeData.mcIndex) ) { for(int i=0;iinCorePoints.push_back(position); boundaryRoots[key]=int(mesh->inCorePoints.size())-1; ++count; } } else { if(interiorRoots->find(key)==interiorRoots->end()) { GetRoot(ri,isoValue,fData.depth,position,*interiorNormalHash,NULL,nonLinearFit); (*interiorRoots)[key]=mesh->addOutOfCorePoint(position); interiorPositions->push_back(position); ++count; } } } } } } } return count; } template inline int Octree::SetBoundaryMCRootPositions(const int& sDepth,const Real& isoValue, hash_map& boundaryRoots,hash_map > >& boundaryNormalHash, CoredMeshData* mesh,const int& nonLinearFit) { Point3D position; int i,j,k,eIndex,hits=0; RootInfo ri; int count=0; TreeOctNode* node; node=tree.nextLeaf(); while(node) { if(MarchingCubes::HasRoots(node->nodeData.mcIndex)) { hits=0; for(i=0;iinCorePoints.push_back(position); boundaryRoots[key]=int(mesh->inCorePoints.size())-1; count++; } } } } } } } if(hits) { node=tree.nextLeaf(node); } else { node=tree.nextBranch(node); } } return count; } template inline void Octree::GetMCIsoEdges(TreeOctNode* node,hash_map& boundaryRoots,hash_map* interiorRoots,const int& sDepth, std::vector >& edges) { (void) boundaryRoots; (void) interiorRoots; TreeOctNode* temp; int count=0; int isoTri[DIMENSION*MarchingCubes::MAX_TRIANGLES]; FaceEdgesFunction fef; int ref,fIndex; hash_map >::iterator iter; hash_map > vertexCount; fef.edges=&edges; fef.maxDepth=fData.depth; fef.vertexCount=&vertexCount; count=MarchingCubes::AddTriangleIndices(node->nodeData.mcIndex,isoTri); for(fIndex=0;fIndexfaceNeighbor(fIndex); // If the face neighbor exists and has higher resolution than the current node, // get the iso-curve from the neighbor if(temp && temp->children && !IsBoundaryFace(node,fIndex,sDepth)){temp->processNodeFaces(temp,&fef,ref);} // Otherwise, get it from the node else{ RootInfo ri1,ri2; for(int j=0;j(ri1.key,ri2.key)); iter=vertexCount.find(ri1.key); if(iter==vertexCount.end()){ vertexCount[ri1.key].first=ri1; vertexCount[ri1.key].second=0; } iter=vertexCount.find(ri2.key); if(iter==vertexCount.end()){ vertexCount[ri2.key].first=ri2; vertexCount[ri2.key].second=0; } vertexCount[ri1.key].second++; vertexCount[ri2.key].second--; } else{fprintf(stderr,"Bad Edge 1: %lld %lld\n",ri1.key,ri2.key);} } } } } } for(int i=0;i(ri.key,edges[i].first)); vertexCount[ri.key].second++; vertexCount[edges[i].first].second--; } } iter=vertexCount.find(edges[i].second); if(iter==vertexCount.end()){printf("Could not find vertex: %lld\n",edges[i].second);} else if(vertexCount[edges[i].second].second){ RootInfo ri; GetRootPair(vertexCount[edges[i].second].first,fData.depth,ri); iter=vertexCount.find(ri.key); if(iter==vertexCount.end()){printf("Vertex pair not in list\n");} else{ edges.push_back(std::pair(edges[i].second,ri.key)); vertexCount[edges[i].second].second++; vertexCount[ri.key].second--; } } } } template inline int Octree::GetMCIsoTriangles(TreeOctNode* node,CoredMeshData* mesh,hash_map& boundaryRoots, hash_map* interiorRoots,std::vector >* interiorPositions,const int& offSet,const int& sDepth, bool addBarycenter) { int tris=0; std::vector > edges; std::vector > > edgeLoops; GetMCIsoEdges(node,boundaryRoots,interiorRoots,sDepth,edges); GetEdgeLoops(edges,edgeLoops); for(int i=0;i edgeIndices; for(int j=0;j inline int Octree::GetEdgeLoops(std::vector >& edges,std::vector > >& loops){ int loopSize=0; long long frontIdx,backIdx; std::pair e,temp; loops.clear(); while(edges.size()){ std::vector > front,back; e=edges[0]; loops.resize(loopSize+1); edges[0]=edges[edges.size()-1]; edges.pop_back(); frontIdx=e.second; backIdx=e.first; for(int j=int(edges.size())-1;j>=0;j--){ if(edges[j].first==frontIdx || edges[j].second==frontIdx){ if(edges[j].first==frontIdx) {temp=edges[j];} else {temp.first=edges[j].second;temp.second=edges[j].first;} frontIdx=temp.second; front.push_back(temp); edges[j]=edges[edges.size()-1]; edges.pop_back(); j=int(edges.size()); } else if(edges[j].first==backIdx || edges[j].second==backIdx){ if(edges[j].second==backIdx) {temp=edges[j];} else {temp.first=edges[j].second;temp.second=edges[j].first;} backIdx=temp.first; back.push_back(temp); edges[j]=edges[edges.size()-1]; edges.pop_back(); j=int(edges.size()); } } for(int j=int(back.size())-1;j>=0;j--){loops[loopSize].push_back(back[j]);} loops[loopSize].push_back(e); for(int j=0;j inline int Octree::AddTriangles(CoredMeshData* mesh,std::vector edges[3],std::vector >* interiorPositions,const int& offSet) { std::vector e; for(int i=0;i<3;i++){for(size_t j=0;j inline int Octree::AddTriangles(CoredMeshData* mesh,std::vector& edges,std::vector >* interiorPositions,const int& offSet, bool addBarycenter ) { if( edges.size()>3 ) { #if 1 bool isCoplanar = false; for( size_t i=0 ; i v1 , v2; if( edges[i].inCore ) for( int k=0 ; k<3 ; k++ ) v1.coords[k] = mesh->inCorePoints[ edges[i].index ].coords[k]; else for( int k=0 ; k<3 ; k++ ) v1.coords[k] = (*interiorPositions)[ edges[i].index-offSet ].coords[k]; if( edges[j].inCore ) for( int k=0 ; k<3 ; k++ ) v2.coords[k] = mesh->inCorePoints[ edges[j].index ].coords[k]; else for( int k=0 ; k<3 ; k++ ) v2.coords[k] = (*interiorPositions)[ edges[j].index-offSet ].coords[k]; for( int k=0 ; k<3 ; k++ ) if( v1.coords[k]==v2.coords[k] ) isCoplanar = true; } if( addBarycenter && isCoplanar ) #else if( addBarycenter ) #endif { Point3D< Real > c; c.coords[0] = c.coords[1] = c.coords[2] = 0; for( int i=0 ; i p; if(edges[i].inCore) for(int j=0 ; j<3 ; j++ ) p.coords[j] = mesh->inCorePoints[edges[i].index].coords[j]; else for(int j=0 ; j<3 ; j++ ) p.coords[j] =(*interiorPositions)[edges[i].index-offSet].coords[j]; c.coords[0] += p.coords[0] , c.coords[1] += p.coords[1] , c.coords[2] += p.coords[2]; } c.coords[0] /= edges.size() , c.coords[1] /= edges.size() , c.coords[2] /= edges.size(); int cIdx = mesh->addOutOfCorePoint( c ); for( int i=0 ; iaddTriangle( tri , inCoreFlag ); } return edges.size(); } else { Triangulation t; // Add the points to the triangulation for(int i=0;i p; if(edges[i].inCore) {for(int j=0;j<3;j++){p.coords[j]=mesh->inCorePoints[edges[i].index].coords[j];}} else {for(int j=0;j<3;j++){p.coords[j]=(*interiorPositions)[edges[i].index-offSet].coords[j];}} t.points.push_back(p); } // Create a fan triangulation for(int i=1;iaddTriangle(tri,inCoreFlag); } } } else if(edges.size()==3) { TriangleIndex tri; int inCoreFlag=0; for(int i=0;i<3;i++){ tri.idx[i]=edges[i].index; if(edges[i].inCore){inCoreFlag|=CoredMeshData::IN_CORE_FLAG[i];} } mesh->addTriangle(tri,inCoreFlag); } return int(edges.size())-2; } //////////////// // VertexData // //////////////// inline long long VertexData::CenterIndex(const TreeOctNode* node,const int& maxDepth) { int idx[DIMENSION]; return CenterIndex(node,maxDepth,idx); } inline long long VertexData::CenterIndex(const TreeOctNode* node,const int& maxDepth,int idx[DIMENSION]) { int d,o[3]; node->depthAndOffset(d,o); for(int i=0;i::CornerIndex(maxDepth+1,d+1,o[i]<<1,1);} return (long long)(idx[0]) | (long long)(idx[1])<<15 | (long long)(idx[2])<<30; } inline long long VertexData::CenterIndex(const int& depth,const int offSet[DIMENSION],const int& maxDepth,int idx[DIMENSION]) { for(int i=0;i::CornerIndex(maxDepth+1,depth+1,offSet[i]<<1,1);} return (long long)(idx[0]) | (long long)(idx[1])<<15 | (long long)(idx[2])<<30; } inline long long VertexData::CornerIndex(const TreeOctNode* node,const int& cIndex,const int& maxDepth) { int idx[DIMENSION]; return CornerIndex(node,cIndex,maxDepth,idx); } inline long long VertexData::CornerIndex(const TreeOctNode* node,const int& cIndex,const int& maxDepth,int idx[DIMENSION]) { int x[DIMENSION]; Cube::FactorCornerIndex(cIndex,x[0],x[1],x[2]); int d,o[3]; node->depthAndOffset(d,o); for(int i=0;i::CornerIndex(maxDepth+1,d,o[i],x[i]);} return (long long)(idx[0]) | (long long)(idx[1])<<15 | (long long)(idx[2])<<30; } inline long long VertexData::CornerIndex(const int& depth,const int offSet[DIMENSION],const int& cIndex,const int& maxDepth,int idx[DIMENSION]) { int x[DIMENSION]; Cube::FactorCornerIndex(cIndex,x[0],x[1],x[2]); for(int i=0;i::CornerIndex(maxDepth+1,depth,offSet[i],x[i]);} return (long long)(idx[0]) | (long long)(idx[1])<<15 | (long long)(idx[2])<<30; } inline long long VertexData::FaceIndex(const TreeOctNode* node,const int& fIndex,const int& maxDepth) { int idx[DIMENSION]; return FaceIndex(node,fIndex,maxDepth,idx); } inline long long VertexData::FaceIndex(const TreeOctNode* node,const int& fIndex,const int& maxDepth,int idx[DIMENSION]) { int dir(0),offset(0); Cube::FactorFaceIndex(fIndex,dir,offset); int d,o[3]; node->depthAndOffset(d,o); for(int i=0;i::CornerIndex(maxDepth+1,d+1,o[i]<<1,1);} idx[dir]=BinaryNode::CornerIndex(maxDepth+1,d,o[dir],offset); return (long long)(idx[0]) | (long long)(idx[1])<<15 | (long long)(idx[2])<<30; } inline long long VertexData::EdgeIndex(const TreeOctNode* node,const int& eIndex,const int& maxDepth) { int idx[DIMENSION]; return EdgeIndex(node,eIndex,maxDepth,idx); } inline long long VertexData::EdgeIndex(const TreeOctNode* node,const int& eIndex,const int& maxDepth,int idx[DIMENSION]) { int o,i1,i2; int d,off[3]; node->depthAndOffset(d,off); for(int i=0;i::CornerIndex(maxDepth+1,d+1,off[i]<<1,1);} Cube::FactorEdgeIndex(eIndex,o,i1,i2); switch(o){ case 0: idx[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i1); idx[2]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); break; case 1: idx[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); idx[2]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); break; case 2: idx[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); idx[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i2); break; }; return (long long)(idx[0]) | (long long)(idx[1])<<15 | (long long)(idx[2])<<30; } GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/PPolynomial.inl0000644000175000017500000003322611667757442026174 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "Factor.h" //////////////////////// // StartingPolynomial // //////////////////////// template template inline StartingPolynomial StartingPolynomial::operator * (const StartingPolynomial& iP) const { StartingPolynomial sp; if(start>iP.start){sp.start=start;} else{sp.start=iP.start;} sp.p=this->p*iP.p; return sp; } template inline StartingPolynomial StartingPolynomial::scale(const double& s) const { StartingPolynomial q; q.start=start*s; q.p=p.scale(s); return q; } template inline StartingPolynomial StartingPolynomial::shift(const double& s) const { StartingPolynomial q; q.start=start+s; q.p=p.shift(s); return q; } template inline int StartingPolynomial::operator < (const StartingPolynomial& sp) const { if(start inline int StartingPolynomial::Compare(const void* v1,const void* v2) { double d=((StartingPolynomial*)(v1))->start-((StartingPolynomial*)(v2))->start; if (d<0) {return -1;} else if (d>0) {return 1;} else {return 0;} } ///////////////// // PPolynomial // ///////////////// template inline PPolynomial::PPolynomial(void) { polyCount=0; polys=NULL; } template inline PPolynomial::PPolynomial(const PPolynomial& p) { polyCount=0; polys=NULL; set(p.polyCount); memcpy(polys,p.polys,sizeof(StartingPolynomial)*p.polyCount); } template inline PPolynomial::~PPolynomial(void) { if(polyCount){free(polys);} polyCount=0; polys=NULL; } template inline void PPolynomial::set(StartingPolynomial* sps,const int& count) { int i,c=0; set(count); qsort(sps,count,sizeof(StartingPolynomial),StartingPolynomial::Compare); for(i=0;i inline int PPolynomial::size(void) const { return int(sizeof(StartingPolynomial)*polyCount); } template inline void PPolynomial::set(const size_t &iSize) { if(polyCount){free(polys);} polyCount=0; polys=NULL; polyCount=iSize; if(iSize){ polys=(StartingPolynomial*)malloc(sizeof(StartingPolynomial)*iSize); memset(polys,0,sizeof(StartingPolynomial)*iSize); } } template inline void PPolynomial::reset(const size_t& newSize) { polyCount=newSize; polys=(StartingPolynomial*)realloc(polys,sizeof(StartingPolynomial)*newSize); } template inline PPolynomial& PPolynomial::operator = (const PPolynomial& p) { set(p.polyCount); memcpy(polys,p.polys,sizeof(StartingPolynomial)*p.polyCount); return *this; } template template inline PPolynomial& PPolynomial::operator = (const PPolynomial& p) { set(p.polyCount); for(int i=0;i inline double PPolynomial::operator ()(const double& t) const { double v=0; for(int i=0;ipolys[i].start;i++) { v+=polys[i].p(t); } return v; } template inline double PPolynomial::integral(const double& tMin,const double& tMax) const { int m=1; double start,end,s,v=0; start=tMin; end=tMax; if(tMin>tMax){ m=-1; start=tMax; end=tMin; } for(int i=0;i inline double PPolynomial::Integral(void) const { return integral(polys[0].start,polys[polyCount-1].start); } template inline PPolynomial PPolynomial::operator + (const PPolynomial& p) const { PPolynomial q; int i,j; size_t idx=0; q.set(polyCount+p.polyCount); i=j=-1; while(idx=int(p.polyCount)-1) {q.polys[idx]= polys[++i];} else if (i>=int( polyCount)-1) {q.polys[idx]=p.polys[++j];} else if(polys[i+1].start inline PPolynomial PPolynomial::operator - (const PPolynomial& p) const { PPolynomial q; int i,j; size_t idx=0; q.set(polyCount+p.polyCount); i=j=-1; while(idx=int(p.polyCount)-1) {q.polys[idx]= polys[++i];} else if (i>=int( polyCount)-1) {q.polys[idx].start=p.polys[++j].start;q.polys[idx].p=p.polys[j].p*(-1.0);} else if(polys[i+1].start inline PPolynomial& PPolynomial::addScaled(const PPolynomial& p,const double& iScale) { int i,j; StartingPolynomial* oldPolys=polys; size_t idx=0,cnt=0,oldPolyCount=polyCount; polyCount=0; polys=NULL; set(oldPolyCount+p.polyCount); i=j=-1; while(cnt=int( p.polyCount)-1) {polys[idx]=oldPolys[++i];} else if (i>=int(oldPolyCount)-1) {polys[idx].start= p.polys[++j].start;polys[idx].p=p.polys[j].p*iScale;} else if (oldPolys[i+1].start template inline PPolynomial PPolynomial::operator * (const PPolynomial& p) const { PPolynomial q; StartingPolynomial *sp; int i,j,spCount=int(polyCount*p.polyCount); sp=(StartingPolynomial*)malloc(sizeof(StartingPolynomial)*spCount); for(i=0;i template inline PPolynomial PPolynomial::operator * (const Polynomial& p) const { PPolynomial q; q.set(polyCount); for(int i=0;i inline PPolynomial PPolynomial::scale(const double& s) const { PPolynomial q; q.set(polyCount); for(size_t i=0;i inline PPolynomial PPolynomial::shift(const double& s) const { PPolynomial q; q.set(polyCount); for(size_t i=0;i inline PPolynomial PPolynomial::derivative(void) const { PPolynomial q; q.set(polyCount); for(size_t i=0;i inline PPolynomial PPolynomial::integral(void) const { int i; PPolynomial q; q.set(polyCount); for(i=0;i inline PPolynomial& PPolynomial::operator += (const double &s) { polys[0].p+=s; } template inline PPolynomial& PPolynomial::operator -= (const double &s) { polys[0].p-=s; } template inline PPolynomial& PPolynomial::operator *= (const double &s) { for(int i=0;i inline PPolynomial& PPolynomial::operator /= (const double &s) { for(size_t i=0;i inline PPolynomial PPolynomial::operator + (const double& s) const { PPolynomial q=*this; q+=s; return q; } template inline PPolynomial PPolynomial::operator - (const double& s) const { PPolynomial q=*this; q-=s; return q; } template inline PPolynomial PPolynomial::operator * (const double& s) const { PPolynomial q=*this; q*=s; return q; } template inline PPolynomial PPolynomial::operator / (const double& s) const { PPolynomial q=*this; q/=s; return q; } template inline void PPolynomial::printnl(void) const { Polynomial p; if(!polyCount){ printf("[-Infinity,Infinity]\n"); } else{ for(size_t i=0;i inline PPolynomial PPolynomial::ConstantFunction(const double& radius) { if(Degree<0){ fprintf(stderr,"Could not set degree %d polynomial as constant\n",Degree); exit(0); } PPolynomial q; q.set(2); q.polys[0].start=-radius; q.polys[1].start= radius; q.polys[0].p.coefficients[0]= 1.0; q.polys[1].p.coefficients[0]=-1.0; return q; } template<> inline PPolynomial<0> PPolynomial<0>::GaussianApproximation(const double& width) { return ConstantFunction(width); } template inline PPolynomial PPolynomial::GaussianApproximation(const double& width) { return PPolynomial::GaussianApproximation().MovingAverage(width); } template inline PPolynomial PPolynomial::MovingAverage(const double& radius) { const int UDegree = Degree+1; PPolynomial A; Polynomial p; StartingPolynomial* sps; sps = (StartingPolynomial*) malloc( sizeof(StartingPolynomial ) * polyCount * 2); for(int i=0;i inline void PPolynomial::getSolutions(const double& c,std::vector& roots,const double& EPS,const double& min,const double& max) const { Polynomial p; std::vector tempRoots; p.setZero(); for(size_t i=0;imax){break;} if(ipolys[i].start && (i+1==polyCount || tempRoots[j]<=polys[i+1].start)){ if(tempRoots[j]>min && tempRoots[j] inline void PPolynomial::write(FILE* fp,const int& samples,const double& min,const double& max) const { fwrite(&samples,sizeof(int),1,fp); for(int i=0;iDelete(); } }; vtkStandardNewMacro(vtkNormalEstimationFilter); vtkNormalEstimationFilter::vtkNormalEstimationFilter() { this->RadiusRatio = 0.1; this->NeighborhoodSize = 25; } vtkNormalEstimationFilter::~vtkNormalEstimationFilter() { delete[] m_SurfacePoints; } // some simple routines for vector math void vtkCopyBToA(double *a, double *b) { for ( int i = 0; i < 3; i++ ) { a[i] = b[i]; } } void vtkSubtractBFromA(double *a, double *b) { for ( int i = 0; i < 3; i++ ) { a[i] -= b[i]; } } void vtkAddBToA(double *a, double *b) { for ( int i = 0; i < 3; i++ ) { a[i] += b[i]; } } void vtkMultiplyBy(double *a, double f) { for ( int i = 0; i < 3; i++ ) { a[i] *= f; } } // Routines for matrix creation void vtkSRFreeMatrix(double **m, long nrl, long nrh, long ncl, long nch); double ** vtkSRMatrix(long nrl, long nrh, long ncl, long nch); void vtkSRFreeVector(double *v, long nl, long nh); double * vtkSRVector(long nl, long nh); // set a matrix to zero void vtkSRMakeZero(double **m, long nrl, long nrh, long ncl, long nch) { long i, j; for ( i = nrl; i <= nrh; i++ ) { for ( j = ncl; j <= nch; j++ ) { m[i][j] = 0.0; } } } // add v*Transpose(v) to m, where v is 3x1 and m is 3x3 void vtkSRAddOuterProduct(double **m, double *v); // scalar multiply a matrix void vtkSRMultiply(double **m, double f, long nrl, long nrh, long ncl, long nch) { long i, j; for ( i = nrl; i <= nrh; i++ ) { for ( j = ncl; j <= nch; j++ ) { m[i][j] *= f; } } } //---------------------------------------------------------------------------- int vtkNormalEstimationFilter::FillInputPortInformation( int vtkNotUsed(port), vtkInformation *info) { info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet"); return 1; } int vtkNormalEstimationFilter::RequestInformation( vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *outputVector) { // get the info objects vtkInformation *outInfo = outputVector->GetInformationObject(0); // would be nice to compute the whole extent but we need more info to // compute it. outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), 0, 1, 0, 1, 0, 1); vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_FLOAT, 1); return 1; } void vtkNormalEstimationFilter::BuildLocalConnectivity(vtkDataSet *input) { vtkPointLocator *locator = vtkPointLocator::New(); locator->SetDataSet(input); double bounds[6]; input->GetBounds(bounds); double p0[3], p1[3]; for ( int ii = 0; ii < 3; ++ii ) { p0[ii] = bounds[2 * ii]; p1[ii] = bounds[2 * ii + 1]; } double sq_diagonal = vtkMath::Distance2BetweenPoints(p0, p1); double radius = this->RadiusRatio *sqrt(sq_diagonal); vtkIdList *locals = vtkIdList::New(); const vtkIdType COUNT = input->GetNumberOfPoints(); vtkIdType iNeighbor; // if a pair is close, add each one as a neighbor of the other for ( vtkIdType i = 0; i < COUNT; i++ ) { SurfacePoint *p = &m_SurfacePoints[i]; vtkCopyBToA( p->loc, input->GetPoint(i) ); //locator->FindClosestNPoints(this->NeighborhoodSize, p->loc, locals); locator->FindClosestNPoints(radius, p->loc, locals); if ( locals->GetNumberOfIds() < this->NeighborhoodSize ) { locator->FindClosestNPoints(this->NeighborhoodSize, p->loc, locals); } for ( vtkIdType j = 0; j < locals->GetNumberOfIds(); j++ ) { iNeighbor = locals->GetId(j); if ( iNeighbor != i ) { p->neighbors->InsertNextId(iNeighbor); m_SurfacePoints[iNeighbor].neighbors->InsertNextId(i); } } } locator->Delete(); locals->Delete(); } void vtkNormalEstimationFilter::EstimatePlanes(vtkDataSet *input) { double * pointi; double **covar, *v3d, *eigenvalues, **eigenvectors; covar = vtkSRMatrix(0, 2, 0, 2); v3d = vtkSRVector(0, 2); eigenvalues = vtkSRVector(0, 2); eigenvectors = vtkSRMatrix(0, 2, 0, 2); const vtkIdType COUNT = input->GetNumberOfPoints(); vtkIdType i, j; int k; for ( i = 0; i < COUNT; i++ ) { SurfacePoint *p = &m_SurfacePoints[i]; // first find the centroid of the neighbors vtkCopyBToA(p->o, p->loc); int number = 1; vtkIdType neighborIndex; for ( j = 0; j < p->neighbors->GetNumberOfIds(); j++ ) { neighborIndex = p->neighbors->GetId(j); pointi = input->GetPoint(neighborIndex); vtkAddBToA(p->o, pointi); number++; } vtkMultiplyBy(p->o, 1. / number); // then compute the covariance matrix vtkSRMakeZero(covar, 0, 2, 0, 2); for ( k = 0; k < 3; k++ ) { v3d[k] = p->loc[k] - p->o[k]; } vtkSRAddOuterProduct(covar, v3d); for ( j = 0; j < p->neighbors->GetNumberOfIds(); j++ ) { neighborIndex = p->neighbors->GetId(j); pointi = input->GetPoint(neighborIndex); for ( k = 0; k < 3; k++ ) { v3d[k] = pointi[k] - p->o[k]; } vtkSRAddOuterProduct(covar, v3d); } vtkSRMultiply(covar, 1.0 / number, 0, 2, 0, 2); // then extract the third eigenvector vtkMath::Jacobi(covar, eigenvalues, eigenvectors); // third eigenvector (column 2, ordered by eigenvalue magnitude) is plane // normal for ( k = 0; k < 3; k++ ) { p->n[k] = eigenvectors[k][2]; } } vtkSRFreeMatrix(covar, 0, 2, 0, 2); vtkSRFreeVector(v3d, 0, 2); vtkSRFreeVector(eigenvalues, 0, 2); vtkSRFreeMatrix(eigenvectors, 0, 2, 0, 2); } void vtkNormalEstimationFilter::ComputeCostForMST(vtkDataSet *input) { const vtkIdType COUNT = input->GetNumberOfPoints(); vtkIdType i, j; for ( i = 0; i < COUNT; i++ ) { SurfacePoint *p = &m_SurfacePoints[i]; p->costs = new double[p->neighbors->GetNumberOfIds()]; // compute cost between all its neighbors // (bit inefficient to do this for every point, as cost is symmetric) for ( j = 0; j < p->neighbors->GetNumberOfIds(); j++ ) { p->costs[j] = 1.0 - fabs( vtkMath::Dot(p->n, m_SurfacePoints[p->neighbors->GetId(j)].n) ); } } } int vtkNormalEstimationFilter::ConsistencyPropagation() { int orientationPropagation = 1; vtkIdType i, j; if ( orientationPropagation ) { // set to false if you don't want // orientation propagation (for // testing) vtkIdList *nearby = vtkIdList::New(); // list of nearby, unvisited points // start with some vertex int first = 0; // index of starting vertex m_SurfacePoints[first].isVisited = true; // add all the neighbors of the starting vertex into nearby for ( j = 0; j < m_SurfacePoints[first].neighbors->GetNumberOfIds(); j++ ) { nearby->InsertNextId( m_SurfacePoints[first].neighbors->GetId(j) ); } double cost, lowestCost; int cheapestNearby = 0, connectedVisited = 0; // repeat until nearby is empty: while ( nearby->GetNumberOfIds() > 0 ) { // for each nearby point: vtkIdType iNearby, iNeighbor; lowestCost = VTK_DOUBLE_MAX; for ( i = 0; i < nearby->GetNumberOfIds(); i++ ) { iNearby = nearby->GetId(i); // test cost against all neighbors that are members of visited for ( j = 0; j < m_SurfacePoints[iNearby].neighbors->GetNumberOfIds(); j++ ) { iNeighbor = m_SurfacePoints[iNearby].neighbors->GetId(j); if ( m_SurfacePoints[iNeighbor].isVisited ) { cost = m_SurfacePoints[iNearby].costs[j]; // pick lowest cost for this nearby point if ( cost < lowestCost ) { lowestCost = cost; cheapestNearby = iNearby; connectedVisited = iNeighbor; // optional: can break out if satisfied with parallelness if ( lowestCost < 0.1 ) { i = nearby->GetNumberOfIds(); break; } } } } } if ( connectedVisited == cheapestNearby ) { vtkErrorMacro (<< "Internal error in vtkNormalEstimationFilter"); nearby->Delete(); return 0; } // correct the orientation of the point if necessary if ( vtkMath::Dot(m_SurfacePoints[cheapestNearby].n, m_SurfacePoints[connectedVisited].n) < 0.0F ) { // flip this normal vtkMultiplyBy(m_SurfacePoints[cheapestNearby].n, -1); } // add this nearby point to visited if ( m_SurfacePoints[cheapestNearby].isVisited ) { vtkErrorMacro (<< "Internal error in vtkNormalEstimationFilter"); nearby->Delete(); return 0; } m_SurfacePoints[cheapestNearby].isVisited = true; // remove from nearby nearby->DeleteId(cheapestNearby); // add all new nearby points to nearby for ( j = 0; j < m_SurfacePoints[cheapestNearby].neighbors->GetNumberOfIds(); j++ ) { iNeighbor = m_SurfacePoints[cheapestNearby].neighbors->GetId(j); if ( !m_SurfacePoints[iNeighbor].isVisited ) { nearby->InsertUniqueId(iNeighbor); } } } nearby->Delete(); } return 1; } //----------------------------------------------------------------------------- int vtkNormalEstimationFilter::RequestData( vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector) { // get the input vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); vtkDataSet * input = vtkDataSet::SafeDownCast( inInfo->Get( vtkDataObject::DATA_OBJECT() ) ); // get the output vtkInformation *outInfo = outputVector->GetInformationObject(0); vtkPolyData * output = vtkPolyData::SafeDownCast( outInfo->Get( vtkDataObject::DATA_OBJECT() ) ); const vtkIdType COUNT = input->GetNumberOfPoints(); if ( COUNT < 1 ) { vtkErrorMacro(<< "No points to reconstruct"); return 1; } m_SurfacePoints = new SurfacePoint[COUNT]; vtkDebugMacro(<< "Reconstructing " << COUNT << " points"); //time_t start_time,t1,t2,t3,t4; //time(&start_time); // -------------------------------------------------------------------------- // 1. Build local connectivity graph // ------------------------------------------------------------------------- BuildLocalConnectivity(input); //time(&t1); // -------------------------------------------------------------------------- // 2. Estimate a plane at each point using local points // -------------------------------------------------------------------------- EstimatePlanes(input); //time(&t2); //-------------------------------------------------------------------------- // 3a. Compute a cost between every pair of neighbors for the MST // -------------------------------------------------------------------------- // cost = 1 - |normal1.normal2| // ie. cost is 0 if planes are parallel, 1 if orthogonal (least parallel) ComputeCostForMST(input); // -------------------------------------------------------------------------- // 3b. Ensure consistency in plane direction between neighbors // -------------------------------------------------------------------------- // method: guess first one, then walk through tree along most-parallel // neighbors MST, flipping the new normal if inconsistent // to walk minimal spanning tree, keep record of vertices visited and list // of those near to any visited point but not themselves visited. Start // with just one vertex as visited. Pick the vertex in the neighbors list // that has the lowest cost connection with a visited vertex. Record this // vertex as visited, add any new neighbors to the neighbors list. int ok = ConsistencyPropagation(); vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New(); points->SetNumberOfPoints( input->GetNumberOfPoints() ); vtkFloatArray *normals = vtkFloatArray::New(); normals->SetNumberOfComponents(3); normals->SetNumberOfTuples( input->GetNumberOfPoints() ); normals->SetName("Normals"); for ( vtkIdType i = 0; i < input->GetNumberOfPoints(); i++ ) { points->SetPoint( i, input->GetPoint(i) ); normals->SetTuple(i, m_SurfacePoints[i].n); } output->SetPoints(points); output->GetPointData()->SetNormals(normals); normals->Delete(); return ok; } void vtkNormalEstimationFilter::PrintSelf(ostream & os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "Radius Ratio: " << this->RadiusRatio << std::endl; os << indent << "Neighborhood Size: " << this->NeighborhoodSize << std::endl; } void vtkSRAddOuterProduct(double **m, double *v) { int i, j; for ( i = 0; i < 3; i++ ) { for ( j = 0; j < 3; j++ ) { m[i][j] += v[i] * v[j]; } } } #define VTK_NR_END 1 #define VTK_FREE_ARG char * // allocate a float vector with subscript range v[nl..nh] double * vtkSRVector(long nl, long nh) { double *v; v = new double[nh - nl + 1 + VTK_NR_END]; if ( !v ) { vtkGenericWarningMacro(<< "allocation failure in vector()"); return NULL; } return ( v - nl + VTK_NR_END ); } // allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] double ** vtkSRMatrix(long nrl, long nrh, long ncl, long nch) { long i, nrow = nrh - nrl + 1, ncol = nch - ncl + 1; double **m; // allocate pointers to rows m = new double *[nrow + VTK_NR_END]; if ( !m ) { vtkGenericWarningMacro(<< "allocation failure 1 in Matrix()"); return NULL; } m += VTK_NR_END; m -= nrl; // allocate rows and set pointers to them m[nrl] = new double[nrow * ncol + VTK_NR_END]; if ( !m[nrl] ) { vtkGenericWarningMacro("allocation failure 2 in Matrix()"); return NULL; } m[nrl] += VTK_NR_END; m[nrl] -= ncl; for ( i = nrl + 1; i <= nrh; i++ ) { m[i] = m[i - 1] + ncol; } // return pointer to array of pointers to rows return m; } // free a double vector allocated with SRVector() void vtkSRFreeVector( double *v, long nl, long vtkNotUsed(nh) ) { delete[] ( v + nl - VTK_NR_END ); } // free a double matrix allocated by Matrix() void vtkSRFreeMatrix( double **m, long nrl, long vtkNotUsed(nrh), long ncl, long vtkNotUsed(nch) ) { delete[] ( m[nrl] + ncl - VTK_NR_END ); delete[] ( m + nrl - VTK_NR_END ); } #undef VTK_NR_END #undef VTK_FREE_ARG GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Allocator.h0000644000175000017500000001476711667757442025327 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef ALLOCATOR_INCLUDED #define ALLOCATOR_INCLUDED #include #include class AllocatorState { public: int index, remains; }; /** This templated class assists in memory allocation and is well suited * for instances when it is known that the sequence of memory allocations * is performed in a stack-based manner, so that memory allocated last is * released first. It also preallocates memory in chunks so that multiple * requests for small chunks of memory do not require separate system calls * to the memory manager. * The allocator is templated off of the class of objects that we would * like it to allocate, ensuring that appropriate constructors and * destructors are called as necessary. * * \ingroup PoissonReconstruction */ template< class T > class Allocator { int blockSize; int index, remains; std::vector< T * > memory; public: Allocator(void) { blockSize = index = remains = 0; } ~Allocator(void) { reset(); } /** This method is the allocators destructor. * It frees up any of the memory that it has allocated. */ void reset(void) { for ( size_t i = 0; i < memory.size(); i++ ) { delete[] memory[i]; } memory.clear(); blockSize = index = remains = 0; } /** This method returns the memory state of the allocator. */ AllocatorState getState(void) const { AllocatorState s; s.index = index; s.remains = remains; return s; } /** This method rolls back the allocator so that it makes all of the * memory previously allocated available for re-allocation. Note that it * does it not call the constructor again, so after this method has been * called, assumptions about the state of the values in memory are no * longer valid. */ void rollBack(void) { if ( memory.size() ) { for ( size_t i = 0; i < memory.size(); i++ ) { for ( int j = 0; j < blockSize; j++ ) { memory[i][j].~T(); new ( &memory[i][j] )T(); } } index = 0; remains = blockSize; } } /** This method rolls back the allocator to the previous memory state * and makes all of the memory previously allocated available for * re-allocation. Note that it does it not call the constructor again, * so after this method has been called, assumptions about the state of * the values in memory are no longer valid. */ void rollBack(const AllocatorState & state) { if ( state.index < index || ( state.index == index && state.remains < remains ) ) { if ( state.index < index ) { for ( int j = state.remains; j < blockSize; j++ ) { memory[state.index][j].~T(); new ( &memory[state.index][j] )T(); } for ( int i = state.index + 1; i < index - 1; i++ ) { for ( int j = 0; j < blockSize; j++ ) { memory[i][j].~T(); new ( &memory[i][j] )T(); } } for ( int j = 0; j < remains; j++ ) { memory[index][j].~T(); new ( &memory[index][j] )T(); } index = state.index; remains = state.remains; } else { for ( int j = 0; j < state.remains; j++ ) { memory[index][j].~T(); new ( &memory[index][j] )T(); } remains = state.remains; } } } /** This method initiallizes the constructor and the blockSize variable * specifies the the number of objects that should be pre-allocated at a * time. */ void set(const int & iBlockSize) { reset(); this->blockSize = iBlockSize; index = -1; remains = 0; } /** This method returns a pointer to an array of elements objects. If * there is left over pre-allocated memory, this method simply returns a * pointer to the next free piece of memory, otherwise it pre-allocates * more memory. Note that if the number of objects requested is larger * than the value blockSize with which the allocator was initialized, the * request for memory will fail. */ T * newElements(const int & elements = 1) { T *mem; if ( !elements ) { return NULL; } if ( elements > blockSize ) { fprintf(stderr, "Allocator Error, elements bigger than block-size: %d>%d\n", elements, blockSize); return NULL; } if ( remains < elements ) { if ( index == static_cast< int >( memory.size() - 1 ) ) { mem = new T[blockSize]; if ( !mem ) { fprintf(stderr, "Failed to allocate memory\n"); exit(0); } memory.push_back(mem); } index++; remains = blockSize; } mem = &( memory[index][blockSize - remains] ); remains -= elements; return mem; } }; #endif // ALLOCATOR_INCLUDE GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Geometry.h0000644000175000017500000001631011667757442025164 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef GEOMETRY_INCLUDED #define GEOMETRY_INCLUDED #include #include #include "Hash.h" #include "PoissonReconstructionConfigure.h" template< class Real > Real Random(void); template< class Real > struct Point3D { Real coords[3]; }; template< class Real > Point3D< Real > RandomBallPoint(void); template< class Real > Point3D< Real > RandomSpherePoint(void); template< class Real > double Length(const Point3D< Real > & p); template< class Real > double SquareLength(const Point3D< Real > & p); template< class Real > double Distance(const Point3D< Real > & p1, const Point3D< Real > & p2); template< class Real > double SquareDistance(const Point3D< Real > & p1, const Point3D< Real > & p2); template< class Real > void CrossProduct(const Point3D< Real > & p1, const Point3D< Real > & p2, Point3D< Real > & p); class Edge { public: double p[2][2]; double Length(void) const { double d[2]; d[0] = p[0][0] - p[1][0]; d[1] = p[0][1] - p[1][1]; return sqrt(d[0] * d[0] + d[1] * d[1]); } }; class Triangle { public: double p[3][3]; double Area(void) const { double v1[3], v2[3], v[3]; for ( int d = 0; d < 3; d++ ) { v1[d] = p[1][d] - p[0][d]; v2[d] = p[2][d] - p[0][d]; } v[0] = v1[1] * v2[2] - v1[2] * v2[1]; v[1] = -v1[0] * v2[2] + v1[2] * v2[0]; v[2] = v1[0] * v2[1] - v1[1] * v2[0]; return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) / 2; } double AspectRatio(void) const { double d = 0; int i, j; for ( i = 0; i < 3; i++ ) { for ( i = 0; i < 3; i++ ) { for ( j = 0; j < 3; j++ ) { d += ( p[( i + 1 ) % 3][j] - p[i][j] ) * ( p[( i + 1 ) % 3][j] - p[i][j] ); } } } return Area() / d; } }; class CoredPointIndex { public: int index; char inCore; int operator==(const CoredPointIndex & cpi) const { return ( index == cpi.index ) && ( inCore == cpi.inCore ); } int operator!=(const CoredPointIndex & cpi) const { return ( index != cpi.index ) || ( inCore != cpi.inCore ); } }; class EdgeIndex { public: int idx[2]; }; class CoredEdgeIndex { public: CoredPointIndex idx[2]; }; class TriangleIndex { public: int idx[3]; }; class TriangulationEdge { public: TriangulationEdge(void); int pIndex[2]; int tIndex[2]; }; class TriangulationTriangle { public: TriangulationTriangle(void); int eIndex[3]; }; template< class Real > class Triangulation { public: std::vector< Point3D< Real > > points; std::vector< TriangulationEdge > edges; std::vector< TriangulationTriangle > triangles; int factor(const int & tIndex, int & p1, int & p2, int & p3); double area(void); double area(const int & tIndex); double area(const int & p1, const int & p2, const int & p3); int flipMinimize(const int & eIndex); int addTriangle(const int & p1, const int & p2, const int & p3); protected: hash_map< long long, int > edgeMap; static long long EdgeIndex(const int & p1, const int & p2); double area(const Triangle & t); }; template< class Real > void EdgeCollapse(const Real & edgeRatio, std::vector< TriangleIndex > & triangles, std::vector< Point3D< Real > > & positions, std::vector< Point3D< Real > > *normals); template< class Real > void TriangleCollapse(const Real & edgeRatio, std::vector< TriangleIndex > & triangles, std::vector< Point3D< Real > > & positions, std::vector< Point3D< Real > > *normals); class CoredMeshData { public: CoredMeshData() {} virtual ~CoredMeshData() {} std::vector< Point3D< float > > inCorePoints; const static int IN_CORE_FLAG[3]; virtual void resetIterator(void) = 0; virtual int addOutOfCorePoint(const Point3D< float > & p) = 0; virtual int addTriangle( const TriangleIndex & t, const int & icFlag = ( IN_CORE_FLAG[0] | IN_CORE_FLAG[1] | IN_CORE_FLAG[2] ) ) = 0; virtual int nextOutOfCorePoint(Point3D< float > & p) = 0; virtual int nextTriangle(TriangleIndex & t, int & inCoreFlag) = 0; virtual int outOfCorePointCount(void) = 0; virtual int triangleCount(void) = 0; }; class CoredVectorMeshData:public CoredMeshData { std::vector< Point3D< float > > oocPoints; std::vector< TriangleIndex > triangles; int oocPointIndex, triangleIndex; public: CoredVectorMeshData(); void resetIterator(); int addOutOfCorePoint(const Point3D< float > & p); int addTriangle( const TriangleIndex & t, const int & inCoreFlag = ( CoredMeshData::IN_CORE_FLAG[0] | CoredMeshData::IN_CORE_FLAG[1] | CoredMeshData::IN_CORE_FLAG[2] ) ); int nextOutOfCorePoint(Point3D< float > & p); int nextTriangle(TriangleIndex & t, int & inCoreFlag); int outOfCorePointCount(void); int triangleCount(void); }; class CoredFileMeshData:public CoredMeshData { FILE *oocPointFile, *triangleFile; int oocPoints, triangles; public: CoredFileMeshData(void); ~CoredFileMeshData(void); void resetIterator(void); int addOutOfCorePoint(const Point3D< float > & p); int addTriangle( const TriangleIndex & t, const int & inCoreFlag = ( CoredMeshData::IN_CORE_FLAG[0] | CoredMeshData::IN_CORE_FLAG[1] | CoredMeshData::IN_CORE_FLAG[2] ) ); int nextOutOfCorePoint(Point3D< float > & p); int nextTriangle(TriangleIndex & t, int & inCoreFlag); int outOfCorePointCount(void); int triangleCount(void); }; #include "Geometry.inl" #endif // GEOMETRY_INCLUDED GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/PoissonReconstructionConfigure.h.in0000644000175000017500000000072211667757442032234 0ustar mathieumathieu#ifndef __PoissonReconstructionConfigure_h #define __PoissonReconstructionConfigure_h #include "vtkConfigure.h" /* Whether we are building shared libraries. */ #if defined ( WIN32 ) && defined ( GOFIGURE2_BUILD_SHARED_LIBS ) #if defined ( PoissonReconstruction_EXPORTS ) #define PoissonReconstruction_EXPORT __declspec(dllexport) #else #define PoissonReconstruction_EXPORT __declspec(dllimport) #endif #else #define PoissonReconstruction_EXPORT #endif #endifGoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/CMakeLists.txt0000644000175000017500000000360411667757442025762 0ustar mathieumathieuIF( WIN32 ) IF( NOT CYGWIN ) IF( NOT MINGW ) IF( BUILD_SHARED_LIBS ) ADD_DEFINITIONS( -DPoissonReconstruction_EXPORTS ) ENDIF( BUILD_SHARED_LIBS ) ENDIF( NOT MINGW ) ENDIF( NOT CYGWIN ) ENDIF( WIN32 ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/PoissonReconstructionConfigure.h.in ${CMAKE_CURRENT_BINARY_DIR}/PoissonReconstructionConfigure.h @ONLY IMMEDIATE ) ADD_LIBRARY( PoissonReconstruction vtkNormalEstimationFilter.cxx vtkPoissonReconstruction.cxx Factor.cpp Geometry.cpp MarchingCubes.cpp MultiGridOctest.cpp MultiGridOctreeData.cpp ) TARGET_LINK_LIBRARIES( PoissonReconstruction vtkHybrid ) # ADD_TEST( PoissonReconstructionTest # ${PoissonReconstruction_BINARY_DIR}/PoissonReconstruction # ${PoissonReconstruction_SOURCE_DIR}/data/horsePoints.vtp # 5 # temp.vtp # ) # # INCLUDE( CTest ) SET_TARGET_PROPERTIES( PoissonReconstruction PROPERTIES VERSION ${GOFIGURE2_LIB_VERSION} SOVERSION ${GOFIGURE2_LIB_VERSION} ) # Runtime INSTALL( TARGETS PoissonReconstruction EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} NAMELINK_SKIP COMPONENT Libraries ) # Development INSTALL( TARGETS PoissonReconstruction EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries NAMELINK_ONLY ) FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE( GLOB __source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/*.inl" ) INSTALL( FILES ${__source_file_h} ${__source_file_txx} ${CMAKE_CURRENT_BINARY_DIR}/PoissonReconstructionConfigure.h DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/MultiGridOctest.cpp0000644000175000017500000001053111667757442027005 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include #include "MarchingCubes.h" #include "Octree.h" #include "SparseMatrix.h" #include "FunctionData.h" #include "MultiGridOctest.h" #include "MultiGridOctreeData.h" #define SCALE 1.25 #include char* outputFile=NULL; int echoStdout=0; void DumpOutput(const char* format,...) { if(outputFile) { FILE* fp=fopen(outputFile,"a"); va_list args; va_start(args,format); vfprintf(fp,format,args); fclose(fp); va_end(args); } if(echoStdout) { va_list args; va_start(args,format); vprintf(format,args); va_end(args); } } void DumpOutput2(char* str,const char* format,...) { if(outputFile) { FILE* fp=fopen(outputFile,"a"); va_list args; va_start(args,format); vfprintf(fp,format,args); fclose(fp); va_end(args); } if(echoStdout) { va_list args; va_start(args,format); vprintf(format,args); va_end(args); } va_list args; va_start(args,format); vsprintf(str,format,args); va_end(args); if(str[strlen(str)-1]=='\n'){str[strlen(str)-1]=0;} } void ShowUsage(char* ex) { printf("Usage: %s\n",ex); printf("\t--in \n"); printf("\t--out \n"); printf("\t[--depth ]\n"); printf("\t\t Running at depth d corresponds to solving on a 2^d x 2^d x 2^d\n"); printf("\t\t voxel grid.\n"); printf("\t[--scale ]\n"); printf("\t\t Specifies the factor of the bounding cube that the input\n"); printf("\t\t samples should fit into.\n"); printf("\t[--binary]\n"); printf("\t\t If this flag is enabled, the point set is read in in\n"); printf("\t\t binary format.\n"); printf("\t[--solverDivide ]\n"); printf("\t\t The depth at which a block Gauss-Seidel solver is used\n"); printf("\t\t to solve the Laplacian.\n"); printf("\t[--samplesPerNode \n"); printf("\t\t This parameter specifies the minimum number of points that\n"); printf("\t\t should fall within an octree node.\n"); printf("\t[--confidence]\n"); printf("\t\t If this flag is enabled, the size of a sample's normals is\n"); printf("\t\t used as a confidence value, affecting the sample's\n"); printf("\t\t constribution to the reconstruction process.\n"); printf("\t[--manifold]\n"); printf("\t\t If this flag is enabled, the isosurface extraction is performed\n"); printf("\t\t by adding a polygon's barycenter in order to ensure that the output\n"); printf("\t\t mesh is manifold.\n"); printf("\t[--verbose]\n"); } GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/PPolynomial.h0000644000175000017500000001113211667757442025631 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef P_POLYNOMIAL_INCLUDED #define P_POLYNOMIAL_INCLUDED #include #include "Polynomial.h" template< int Degree > class StartingPolynomial { public: Polynomial< Degree > p; double start; template< int Degree2 > StartingPolynomial< Degree + Degree2 > operator *(const StartingPolynomial< Degree2 > & p) const; StartingPolynomial scale(const double & s) const; StartingPolynomial shift(const double & t) const; int operator<(const StartingPolynomial & sp) const; static int Compare(const void *v1, const void *v2); }; template< int Degree > class PPolynomial { public: size_t polyCount; StartingPolynomial< Degree > *polys; PPolynomial(void); PPolynomial(const PPolynomial< Degree > & p); ~PPolynomial(void); PPolynomial & operator=(const PPolynomial & p); int size(void) const; void set(const size_t & size); // Note: this method will sort the elements in sps void set(StartingPolynomial< Degree > *sps, const int & count); void reset(const size_t & newSize); double operator()(const double & t) const; double integral(const double & tMin, const double & tMax) const; double Integral(void) const; template< int Degree2 > PPolynomial< Degree > & operator=(const PPolynomial< Degree2 > & p); PPolynomial operator+(const PPolynomial & p) const; PPolynomial operator-(const PPolynomial & p) const; template< int Degree2 > PPolynomial< Degree + Degree2 > operator*(const Polynomial< Degree2 > & p) const; template< int Degree2 > PPolynomial< Degree + Degree2 > operator *(const PPolynomial< Degree2 > & p) const; PPolynomial & operator+=(const double & s); PPolynomial & operator-=(const double & s); PPolynomial & operator*=(const double & s); PPolynomial & operator/=(const double & s); PPolynomial operator+(const double & s) const; PPolynomial operator-(const double & s) const; PPolynomial operator *(const double & s) const; PPolynomial operator/(const double & s) const; PPolynomial & addScaled(const PPolynomial & poly, const double & scale); PPolynomial scale(const double & s) const; PPolynomial shift(const double & t) const; PPolynomial< Degree - 1 > derivative(void) const; PPolynomial< Degree + 1 > integral(void) const; void getSolutions(const double & c, std::vector< double > & roots, const double & EPS, const double & min = -DBL_MAX, const double & max = DBL_MAX) const; void printnl(void) const; PPolynomial< Degree + 1 > MovingAverage(const double & radius); static PPolynomial ConstantFunction(const double & width = 0.5); static PPolynomial GaussianApproximation(const double & width = 0.5); void write(FILE *fp, const int & samples, const double & min, const double & max) const; }; #include "PPolynomial.inl" #endif // P_POLYNOMIAL_INCLUDED GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Factor.cpp0000644000175000017500000001646611667757442025156 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ ////////////////////// // Polynomial Roots // ////////////////////// #include #include "Factor.h" int Factor(double a1,double a0,double roots[1][2],const double& EPS){ if(fabs(a1)<=EPS){return 0;} roots[0][0]=-a0/a1; roots[0][1]=0; return 1; } int Factor(double a2,double a1,double a0,double roots[2][2],const double& EPS){ double d; if(fabs(a2)<=EPS){return Factor(a1,a0,roots,EPS);} d=a1*a1-4*a0*a2; a1/=(2*a2); if(d<0){ d=sqrt(-d)/(2*a2); roots[0][0]=roots[1][0]=-a1; roots[0][1]=-d; roots[1][1]= d; } else{ d=sqrt(d)/(2*a2); roots[0][1]=roots[1][1]=0; roots[0][0]=-a1-d; roots[1][0]=-a1+d; } return 2; } // Solution taken from: http://mathworld.wolfram.com/CubicFormula.html // and http://www.csit.fsu.edu/~burkardt/f_src/subpak/subpak.f90 int Factor(double a3,double a2,double a1,double a0,double roots[3][2],const double& EPS){ double q,r,r2,q3; if(fabs(a3)<=EPS){return Factor(a2,a1,a0,roots,EPS);} a2/=a3; a1/=a3; a0/=a3; q=-(3*a1-a2*a2)/9; r=-(9*a2*a1-27*a0-2*a2*a2*a2)/54; r2=r*r; q3=q*q*q; if(r20){return PI/2.0;} else{return -PI/2.0;} } if(x>=0){return atan(y/x);} else{ if(y>=0){return atan(y/x)+PI;} else{return atan(y/x)-PI;} } } double Angle(const double in[2]){ if((in[0]*in[0]+in[1]*in[1])==0.0){return 0;} else{return ArcTan2(in[1],in[0]);} } void Sqrt(const double in[2],double out[2]){ double r=sqrt(sqrt(in[0]*in[0]+in[1]*in[1])); double a=Angle(in)*0.5; out[0]=r*cos(a); out[1]=r*sin(a); } void Add(const double in1[2],const double in2[2],double out[2]){ out[0]=in1[0]+in2[0]; out[1]=in1[1]+in2[1]; } void Subtract(const double in1[2],const double in2[2],double out[2]){ out[0]=in1[0]-in2[0]; out[1]=in1[1]-in2[1]; } void Multiply(const double in1[2],const double in2[2],double out[2]){ out[0]=in1[0]*in2[0]-in1[1]*in2[1]; out[1]=in1[0]*in2[1]+in1[1]*in2[0]; } void Divide(const double in1[2],const double in2[2],double out[2]){ double temp[2]; double l=in2[0]*in2[0]+in2[1]*in2[1]; temp[0]= in2[0]/l; temp[1]=-in2[1]/l; Multiply(in1,temp,out); } // Solution taken from: http://mathworld.wolfram.com/QuarticEquation.html // and http://www.csit.fsu.edu/~burkardt/f_src/subpak/subpak.f90 int Factor(double a4,double a3,double a2,double a1,double a0,double roots[4][2],const double& EPS){ double R[2],D[2],E[2],R2[2]; if(fabs(a4)10e-8){ double temp1[2],temp2[2]; double p1[2],p2[2]; p1[0]=a3*a3*0.75-2.0*a2-R2[0]; p1[1]=0; temp2[0]=((4.0*a3*a2-8.0*a1-a3*a3*a3)/4.0); temp2[1]=0; Divide(temp2,R,p2); Add (p1,p2,temp1); Subtract(p1,p2,temp2); Sqrt(temp1,D); Sqrt(temp2,E); } else{ R[0]=R[1]=0; double temp1[2],temp2[2]; temp1[0]=roots[0][0]*roots[0][0]-4.0*a0; temp1[1]=0; Sqrt(temp1,temp2); temp1[0]=a3*a3*0.75-2.0*a2+2.0*temp2[0]; temp1[1]= 2.0*temp2[1]; Sqrt(temp1,D); temp1[0]=a3*a3*0.75-2.0*a2-2.0*temp2[0]; temp1[1]= -2.0*temp2[1]; Sqrt(temp1,E); } roots[0][0]=-a3/4.0+R[0]/2.0+D[0]/2.0; roots[0][1]= R[1]/2.0+D[1]/2.0; roots[1][0]=-a3/4.0+R[0]/2.0-D[0]/2.0; roots[1][1]= R[1]/2.0-D[1]/2.0; roots[2][0]=-a3/4.0-R[0]/2.0+E[0]/2.0; roots[2][1]= -R[1]/2.0+E[1]/2.0; roots[3][0]=-a3/4.0-R[0]/2.0-E[0]/2.0; roots[3][1]= -R[1]/2.0-E[1]/2.0; return 4; } int Solve(const double* eqns,const double* values,double* solutions,const int& dim){ int i,j,eIndex; double v,m; int *index=new int[dim]; int *set=new int[dim]; double* myEqns=new double[dim*dim]; double* myValues=new double[dim]; for(i=0;im){ m=fabs(myEqns[j*dim+i]); eIndex=j; } } if(eIndex==-1){ delete[] index; delete[] myValues; delete[] myEqns; delete[] set; return 0; } // The position in which the solution for the i-th variable can be found index[i]=eIndex; set[eIndex]=1; // Normalize the equation v=myEqns[eIndex*dim+i]; for(j=0;j #include "MarchingCubes.h" //////////// // Square // //////////// int Square::CornerIndex(const int& x,const int& y){return (y<<1)|x;} void Square::FactorCornerIndex(const int& idx,int& x,int& y){ x=(idx>>0)%2; y=(idx>>1)%2; } int Square::EdgeIndex(const int& orientation,const int& i){ switch(orientation){ case 0: // x if(!i) {return 0;} // (0,0) -> (1,0) else {return 2;} // (0,1) -> (1,1) case 1: // y if(!i) {return 3;} // (0,0) -> (0,1) else {return 1;} // (1,0) -> (1,1) }; return -1; } void Square::FactorEdgeIndex(const int& idx,int& orientation,int& i){ switch(idx){ case 0: case 2: orientation=0; i=idx/2; return; case 1: case 3: orientation=1; i=((idx/2)+1)%2; return; }; } void Square::EdgeCorners(const int& idx,int& c1,int& c2){ int orientation=0,i=0; FactorEdgeIndex(idx,orientation,i); switch(orientation){ case 0: c1=CornerIndex(0,i); c2=CornerIndex(1,i); break; case 1: c1=CornerIndex(i,0); c2=CornerIndex(i,1); break; }; } int Square::ReflectEdgeIndex(const int& idx,const int& edgeIndex){ int orientation=edgeIndex%2; int o=0,i=0; FactorEdgeIndex(idx,o,i); if(o!=orientation){return idx;} else{return EdgeIndex(o,(i+1)%2);} } int Square::ReflectCornerIndex(const int& idx,const int& edgeIndex){ int orientation=edgeIndex%2; int x,y; FactorCornerIndex(idx,x,y); switch(orientation){ case 0: return CornerIndex((x+1)%2,y); case 1: return CornerIndex(x,(y+1)%2); }; return -1; } ////////// // Cube // ////////// int Cube::CornerIndex(const int& x,const int& y,const int& z){return (z<<2)|(y<<1)|x;} void Cube::FactorCornerIndex(const int& idx,int& x,int& y,int& z){ x=(idx>>0)%2; y=(idx>>1)%2; z=(idx>>2)%2; } int Cube::EdgeIndex(const int& orientation,const int& i,const int& j){return (i | (j<<1))|(orientation<<2);} void Cube::FactorEdgeIndex(const int& idx,int& orientation,int& i,int &j){ orientation=idx>>2; i=idx&1; j=(idx&2)>>1; } int Cube::FaceIndex(const int& x,const int& y,const int& z){ if (x<0) {return 0;} else if (x>0) {return 1;} else if (y<0) {return 2;} else if (y>0) {return 3;} else if (z<0) {return 4;} else if (z>0) {return 5;} else {return -1;} } int Cube::FaceIndex(const int& dir,const int& offSet){return (dir<<1)|offSet;} void Cube::FactorFaceIndex(const int& idx,int& x,int& y,int& z){ x=y=z=0; switch(idx){ case 0: x=-1; break; case 1: x= 1; break; case 2: y=-1; break; case 3: y= 1; break; case 4: z=-1; break; case 5: z= 1; break; }; } void Cube::FactorFaceIndex(const int& idx,int& dir,int& offSet){ dir = idx>>1; offSet=idx &1; } int Cube::FaceAdjacentToEdges(const int& eIndex1,const int& eIndex2){ int f1(0),f2(0),g1(0),g2(0); FacesAdjacentToEdge(eIndex1,f1,f2); FacesAdjacentToEdge(eIndex2,g1,g2); if(f1==g1 || f1==g2){return f1;} if(f2==g1 || f2==g2){return f2;} return -1; } void Cube::FacesAdjacentToEdge(const int& eIndex,int& f1Index,int& f2Index){ int orientation,i1,i2; FactorEdgeIndex(eIndex,orientation,i1,i2); i1<<=1; i2<<=1; i1--; i2--; switch(orientation){ case 0: f1Index=FaceIndex( 0,i1, 0); f2Index=FaceIndex( 0, 0,i2); break; case 1: f1Index=FaceIndex(i1, 0, 0); f2Index=FaceIndex( 0, 0,i2); break; case 2: f1Index=FaceIndex(i1, 0, 0); f2Index=FaceIndex( 0,i2, 0); break; }; } void Cube::EdgeCorners(const int& idx,int& c1,int& c2){ int orientation,i1,i2; FactorEdgeIndex(idx,orientation,i1,i2); switch(orientation){ case 0: c1=CornerIndex(0,i1,i2); c2=CornerIndex(1,i1,i2); break; case 1: c1=CornerIndex(i1,0,i2); c2=CornerIndex(i1,1,i2); break; case 2: c1=CornerIndex(i1,i2,0); c2=CornerIndex(i1,i2,1); break; }; } void Cube::FaceCorners(const int& idx,int& c1,int& c2,int& c3,int& c4){ int i=idx%2; switch(idx/2){ case 0: c1=CornerIndex(i,0,0); c2=CornerIndex(i,1,0); c3=CornerIndex(i,0,1); c4=CornerIndex(i,1,1); return; case 1: c1=CornerIndex(0,i,0); c2=CornerIndex(1,i,0); c3=CornerIndex(0,i,1); c4=CornerIndex(1,i,1); return; case 2: c1=CornerIndex(0,0,i); c2=CornerIndex(1,0,i); c3=CornerIndex(0,1,i); c4=CornerIndex(1,1,i); return; } } int Cube::AntipodalCornerIndex(const int& idx){ int x(0),y(0),z(0); FactorCornerIndex(idx,x,y,z); return CornerIndex((x+1)%2,(y+1)%2,(z+1)%2); } int Cube::FaceReflectFaceIndex(const int& idx,const int& faceIndex){ if(idx/2!=faceIndex/2){return idx;} else{ if(idx%2) {return idx-1;} else {return idx+1;} } } int Cube::FaceReflectEdgeIndex(const int& idx,const int& faceIndex){ int orientation=faceIndex/2; int o(0),i(0),j(0); FactorEdgeIndex(idx,o,i,j); if(o==orientation){return idx;} switch(orientation){ case 0: return EdgeIndex(o,(i+1)%2,j); case 1: switch(o){ case 0: return EdgeIndex(o,(i+1)%2,j); case 2: return EdgeIndex(o,i,(j+1)%2); }; case 2: return EdgeIndex(o,i,(j+1)%2); }; return -1; } int Cube::FaceReflectCornerIndex(const int& idx,const int& faceIndex){ int orientation=faceIndex/2; int x(0),y(0),z(0); FactorCornerIndex(idx,x,y,z); switch(orientation){ case 0: return CornerIndex((x+1)%2,y,z); case 1: return CornerIndex(x,(y+1)%2,z); case 2: return CornerIndex(x,y,(z+1)%2); }; return -1; } int Cube::EdgeReflectCornerIndex(const int& idx,const int& edgeIndex){ int orientation,x,y,z; FactorEdgeIndex(edgeIndex,orientation,x,y); FactorCornerIndex(idx,x,y,z); switch(orientation){ case 0: return CornerIndex( x ,(y+1)%2,(z+1)%2); case 1: return CornerIndex((x+1)%2, y ,(z+1)%2); case 2: return CornerIndex((x+1)%2,(y+1)%2, z ); }; return -1; } int Cube::EdgeReflectEdgeIndex(const int& edgeIndex){ int o(0),i1(0),i2(0); FactorEdgeIndex(edgeIndex,o,i1,i2); return Cube::EdgeIndex(o,(i1+1)%2,(i2+1)%2); } ///////////////////// // MarchingSquares // ///////////////////// /* 0} // (0,0) -> (1,0) 1} // (1,0) -> (1,1) 2} // (0,1) -> (1,1) 3} // (0,0) -> (0,1) */ const int MarchingSquares::edgeMask[1< -> -> 9, // 1 -> 0 -> (0,0) -> 0,3 -> 9 3, // 2 -> 1 -> (1,0) -> 0,1 -> 3 10, // 3 -> 0,1 -> (0,0) (1,0) -> 1,3 -> 10 12, // 4 -> 2 -> (0,1) -> 2,3 -> 12 5, // 5 -> 0,2 -> (0,0) (0,1) -> 0,2 -> 5 15, // 6 -> 1,2 -> (1,0) (0,1) -> 0,1,2,3 -> 15 6, // 7 -> 0,1,2 -> (0,0) (1,0) (0,1) -> 1,2 -> 6 6, // 8 -> 3 -> (1,1) -> 1,2 -> 6 15, // 9 -> 0,3 -> (0,0) (1,1) -> 0,1,2,3 -> 15 5, // 10 -> 1,3 -> (1,0) (1,1) -> 0,2 -> 5 12, // 11 -> 0,1,3 -> (0,0) (1,0) (1,1) -> 2,3 -> 12 10, // 12 -> 2,3 -> (0,1) (1,1) -> 1,3 -> 10 3, // 13 -> 0,2,3 -> (0,0) (0,1) (1,1) -> 0,1 -> 3 9, // 14 -> 1,2,3 -> (1,0) (0,1) (1,1) -> 0,3 -> 9 0, // 15 -> 0,1,2,3 -> (0,0) (1,0) (0,1) (1,1) -> }; const int MarchingSquares::edges[1<0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=values[Cube::CornerIndex(1,i,j)];}}} else if (y<0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=values[Cube::CornerIndex(i,0,j)];}}} else if (y>0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=values[Cube::CornerIndex(i,1,j)];}}} else if (z<0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=values[Cube::CornerIndex(i,j,0)];}}} else if (z>0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=values[Cube::CornerIndex(i,j,1)];}}} if (v[0][0] < iso) idx |= 1; if (v[1][0] < iso) idx |= 2; if (v[1][1] < iso) idx |= 4; if (v[0][1] < iso) idx |= 8; return idx; } int MarchingCubes::IsAmbiguous(const double v[Cube::CORNERS],const double& isoValue,const int& faceIndex){ int idx=GetFaceIndex(v,isoValue,faceIndex); return (idx==5) || (idx==10); } int MarchingCubes::HasRoots(const double v[Cube::CORNERS],const double& isoValue,const int& faceIndex){ int idx=GetFaceIndex(v,isoValue,faceIndex); return (idx!=0) && (idx !=15); } int MarchingCubes::HasRoots(const double v[Cube::CORNERS],const double& isoValue){ int idx=GetIndex(v,isoValue); if(idx==0 || idx==255){return 0;} else{return 1;} } int MarchingCubes::HasRoots(const int& mcIndex){ if(mcIndex==0 || mcIndex==255){return 0;} else{return 1;} } int MarchingCubes::AddTriangles(const double v[Cube::CORNERS],const double& iso,Triangle* isoTriangles){ int idx,ntriang=0; Triangle tri; idx=GetIndex(v,iso); /* Cube is entirely in/out of the surface */ if (!edgeMask[idx]) return 0; /* Find the vertices where the surface intersects the cube */ int i,j,ii=1; for(i=0;i<12;i++){ if(edgeMask[idx] & ii){SetVertex(i,v,iso);} ii<<=1; } /* Create the triangle */ for (i=0;triangles[idx][i]!=-1;i+=3) { for(j=0;j<3;j++){ tri.p[0][j]=vertexList[triangles[idx][i+0]][j]; tri.p[1][j]=vertexList[triangles[idx][i+1]][j]; tri.p[2][j]=vertexList[triangles[idx][i+2]][j]; } isoTriangles[ntriang++]=tri; } return ntriang; } int MarchingCubes::AddTriangleIndices(const double v[Cube::CORNERS],const double& iso,int* isoIndices){ int idx,ntriang=0; idx=GetIndex(v,iso); /* Cube is entirely in/out of the surface */ if (!edgeMask[idx]) return 0; /* Create the triangle */ for(int i=0;triangles[idx][i]!=-1;i+=3){ for(int j=0;j<3;j++){isoIndices[i+j]=triangles[idx][i+j];} ntriang++; } return ntriang; } void MarchingCubes::SetVertex(const int& e,const double values[Cube::CORNERS],const double& iso){ double t; switch(e){ case 0: t=Interpolate(values[Cube::CornerIndex(0,0,0)]-iso,values[Cube::CornerIndex(1,0,0)]-iso); vertexList[e][0]=t; vertexList[e][1]=0.0; vertexList[e][2]=0.0; break; case 1: t=Interpolate(values[Cube::CornerIndex(1,0,0)]-iso,values[Cube::CornerIndex(1,1,0)]-iso); vertexList[e][0]=1.0; vertexList[e][1]=t; vertexList[e][2]=0.0; break; case 2: t=Interpolate(values[Cube::CornerIndex(1,1,0)]-iso,values[Cube::CornerIndex(0,1,0)]-iso); vertexList[e][0]=(1.0-t); vertexList[e][1]=1.0; vertexList[e][2]=0.0; break; case 3: t=Interpolate(values[Cube::CornerIndex(0,1,0)]-iso,values[Cube::CornerIndex(0,0,0)]-iso); vertexList[e][0]=0.0; vertexList[e][1]=(1.0-t); vertexList[e][2]=0.0; break; case 4: t=Interpolate(values[Cube::CornerIndex(0,0,1)]-iso,values[Cube::CornerIndex(1,0,1)]-iso); vertexList[e][0]=t; vertexList[e][1]=0.0; vertexList[e][2]=1.0; break; case 5: t=Interpolate(values[Cube::CornerIndex(1,0,1)]-iso,values[Cube::CornerIndex(1,1,1)]-iso); vertexList[e][0]=1.0; vertexList[e][1]=t; vertexList[e][2]=1.0; break; case 6: t=Interpolate(values[Cube::CornerIndex(1,1,1)]-iso,values[Cube::CornerIndex(0,1,1)]-iso); vertexList[e][0]=(1.0-t); vertexList[e][1]=1.0; vertexList[e][2]=1.0; break; case 7: t=Interpolate(values[Cube::CornerIndex(0,1,1)]-iso,values[Cube::CornerIndex(0,0,1)]-iso); vertexList[e][0]=0.0; vertexList[e][1]=(1.0-t); vertexList[e][2]=1.0; break; case 8: t=Interpolate(values[Cube::CornerIndex(0,0,0)]-iso,values[Cube::CornerIndex(0,0,1)]-iso); vertexList[e][0]=0.0; vertexList[e][1]=0.0; vertexList[e][2]=t; break; case 9: t=Interpolate(values[Cube::CornerIndex(1,0,0)]-iso,values[Cube::CornerIndex(1,0,1)]-iso); vertexList[e][0]=1.0; vertexList[e][1]=0.0; vertexList[e][2]=t; break; case 10: t=Interpolate(values[Cube::CornerIndex(1,1,0)]-iso,values[Cube::CornerIndex(1,1,1)]-iso); vertexList[e][0]=1.0; vertexList[e][1]=1.0; vertexList[e][2]=t; break; case 11: t=Interpolate(values[Cube::CornerIndex(0,1,0)]-iso,values[Cube::CornerIndex(0,1,1)]-iso); vertexList[e][0]=0.0; vertexList[e][1]=1.0; vertexList[e][2]=t; break; }; } double MarchingCubes::Interpolate(const double& v1,const double& v2){return v1/(v1-v2);} /////////////////////////////////// int MarchingCubes::GetIndex(const float v[Cube::CORNERS],const float& iso){ int idx=0; if (v[Cube::CornerIndex(0,0,0)] < iso) idx |= 1; if (v[Cube::CornerIndex(1,0,0)] < iso) idx |= 2; if (v[Cube::CornerIndex(1,1,0)] < iso) idx |= 4; if (v[Cube::CornerIndex(0,1,0)] < iso) idx |= 8; if (v[Cube::CornerIndex(0,0,1)] < iso) idx |= 16; if (v[Cube::CornerIndex(1,0,1)] < iso) idx |= 32; if (v[Cube::CornerIndex(1,1,1)] < iso) idx |= 64; if (v[Cube::CornerIndex(0,1,1)] < iso) idx |= 128; return idx; } int MarchingCubes::GetFaceIndex(const float values[Cube::CORNERS],const float& iso,const int& faceIndex){ int i(0),j(0),x(0),y(0),z(0),idx(0); double v[2][2] = {{0, 0}, {0, 0}}; Cube::FactorFaceIndex(faceIndex,x,y,z); if (x<0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=values[Cube::CornerIndex(0,i,j)];}}} else if (x>0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=values[Cube::CornerIndex(1,i,j)];}}} else if (y<0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=values[Cube::CornerIndex(i,0,j)];}}} else if (y>0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=values[Cube::CornerIndex(i,1,j)];}}} else if (z<0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=values[Cube::CornerIndex(i,j,0)];}}} else if (z>0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=values[Cube::CornerIndex(i,j,1)];}}} if (v[0][0] < iso) idx |= 1; if (v[1][0] < iso) idx |= 2; if (v[1][1] < iso) idx |= 4; if (v[0][1] < iso) idx |= 8; return idx; } int MarchingCubes::GetFaceIndex(const int& mcIndex,const int& faceIndex){ int i(0),j(0),x(0),y(0),z(0),idx(0); int v[2][2] = {{0, 0}, {0, 0}}; Cube::FactorFaceIndex(faceIndex,x,y,z); if (x<0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=mcIndex&(1<0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=mcIndex&(1<0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=mcIndex&(1<0){for(i=0;i<2;i++){for(j=0;j<2;j++){v[i][j]=mcIndex&(1< inline Vector::Vector() { m_N = 0; m_pV = 0; } template inline Vector::Vector( const Vector& V ) { m_N = 0; m_pV = 0; Resize(V.m_N); memcpy( m_pV, V.m_pV, m_N*sizeof(T) ); } template inline Vector::Vector( size_t N ) { m_N=0; m_pV=0; Resize(N); } template inline void Vector::Resize( size_t N ) { if(m_N!=N){ if(m_N){delete[] m_pV;} m_pV=NULL; m_N = N; if(N){m_pV = new T[N];} } memset( m_pV, 0, N*sizeof(T) ); } template inline Vector::Vector( size_t N, T* pV ) { Resize(N); memcpy( m_pV, pV, N*sizeof(T) ); } template inline Vector::~Vector() { Resize(0); } template inline Vector& Vector::operator = (const Vector& V) { Resize(V.m_N); memcpy( m_pV, V.m_pV, m_N*sizeof(T) ); return *this; } template inline size_t Vector::Dimensions() const { return m_N; } template inline void Vector::SetZero(void) { for (size_t i=0; i inline const T& Vector::operator () (size_t i) const { assert( i < m_N ); return m_pV[i]; } template inline T& Vector::operator () (size_t i) { return m_pV[i]; } template inline const T& Vector::operator [] (size_t i) const { return m_pV[i]; } template inline T& Vector::operator [] (size_t i) { return m_pV[i]; } template inline Vector Vector::operator * (const T& A) const { Vector V(*this); for (size_t i=0; i inline Vector& Vector::operator *= (const T& A) { for (size_t i=0; i inline Vector Vector::operator / (const T& A) const { Vector V(*this); for (size_t i=0; i inline Vector& Vector::operator /= (const T& A) { for (size_t i=0; i inline Vector Vector::operator + (const Vector& V0) const { Vector V(m_N); for (size_t i=0; i inline Vector& Vector::AddScaled(const Vector& V,const T& scale) { for (size_t i=0; i inline Vector& Vector::SubtractScaled(const Vector& V,const T& scale) { for (size_t i=0; i inline void Vector::Add(const Vector& V1,const T& scale1,const Vector& V2,const T& scale2,Vector& Out){ for (size_t i=0; i inline void Vector::Add(const Vector& V1,const T& scale1,const Vector& V2,Vector& Out){ for (size_t i=0; i inline Vector& Vector::operator += (const Vector& V) { for (size_t i=0; i inline Vector Vector::operator - (const Vector& V0) const { Vector V(m_N); for (size_t i=0; i inline Vector Vector::operator - (void) const { Vector V(m_N); for (size_t i=0; i inline Vector& Vector::operator -= (const Vector& V) { for (size_t i=0; i inline T Vector::Norm( size_t Ln ) const { T N = T(); for (size_t i = 0; i inline void Vector::Normalize() { T N = 1.0f/Norm(2); for (size_t i = 0; i inline T Vector::Length() const { T N = T(); for (size_t i = 0; i inline T Vector::Dot( const Vector& V ) const { T V0 = T(); for (size_t i=0; i inline NVector::NVector() { m_N = 0; m_pV = 0; } template inline NVector::NVector( const NVector& V ) { m_N = 0; m_pV = 0; Resize(V.m_N); memcpy( m_pV, V.m_pV, m_N*sizeof(T)*Dim ); } template inline NVector::NVector( size_t N ) { m_N=0; m_pV=0; Resize(N); } template inline void NVector::Resize( size_t N ) { if(m_N!=N){ if(m_N){delete[] m_pV;} m_pV=NULL; m_N = N; if(N){m_pV = new T[Dim*N];} } memset( m_pV, 0, N*sizeof(T)*Dim ); } template inline NVector::NVector( size_t N, T* pV ) { Resize(N); memcpy( m_pV, pV, N*sizeof(T)*Dim ); } template inline NVector::~NVector() { Resize(0); } template inline NVector& NVector::operator = (const NVector& V) { Resize(V.m_N); memcpy( m_pV, V.m_pV, m_N*sizeof(T)*Dim ); return *this; } template inline size_t NVector::Dimensions() const { return m_N; } template inline void NVector::SetZero(void) { for (size_t i=0; i inline const T* NVector::operator () (size_t i) const { assert( i < m_N ); return &m_pV[i*Dim]; } template inline T* NVector::operator () (size_t i) { return &m_pV[i*Dim]; } template inline const T* NVector::operator [] (size_t i) const { return &m_pV[i*Dim]; } template inline T* NVector::operator [] (size_t i) { return &m_pV[i*Dim]; } template inline NVector NVector::operator * (const T& A) const { NVector V(*this); for (size_t i=0; i inline NVector& NVector::operator *= (const T& A) { for (size_t i=0; i inline NVector NVector::operator / (const T& A) const { NVector V(*this); for (size_t i=0; i inline NVector& NVector::operator /= (const T& A) { for (size_t i=0; i inline NVector NVector::operator + (const NVector& V0) const { NVector V(m_N); for (size_t i=0; i inline NVector& NVector::AddScaled(const NVector& V,const T& scale) { for (size_t i=0; i inline NVector& NVector::SubtractScaled(const NVector& V,const T& scale) { for (size_t i=0; i inline void NVector::Add(const NVector& V1,const T& scale1,const NVector& V2,const T& scale2,NVector& Out){ for (size_t i=0; i inline void NVector::Add(const NVector& V1,const T& scale1,const NVector& V2,NVector& Out){ for (size_t i=0; i inline NVector& NVector::operator += (const NVector& V) { for (size_t i=0; i inline NVector NVector::operator - (const NVector& V0) const { NVector V(m_N); for (size_t i=0; i inline NVector NVector::operator - (void) const { NVector V(m_N); for (size_t i=0; i inline NVector& NVector::operator -= (const NVector& V) { for (size_t i=0; i inline T NVector::Norm( size_t Ln ) const { T N = T(); for (size_t i = 0; i inline void NVector::Normalize() { T N = 1.0f/Norm(2); for (size_t i = 0; i inline T NVector::Length() const { T N = T(); for (size_t i = 0; i inline T NVector::Dot( const NVector& V ) const { T V0 = T(); for (size_t i=0; i #include typedef float Real; typedef float FunctionDataReal; typedef OctNode< class TreeNodeData, Real > TreeOctNode; class RootInfo { public: const TreeOctNode *node; int edgeIndex; long long key; }; class VertexData { public: static long long EdgeIndex(const TreeOctNode * node, const int &eIndex, const int &maxDepth, int index[DIMENSION]); static long long EdgeIndex(const TreeOctNode *node, const int & eIndex, const int & maxDepth); static long long FaceIndex(const TreeOctNode * node, const int &fIndex, const int &maxDepth, int index[DIMENSION]); static long long FaceIndex(const TreeOctNode *node, const int & fIndex, const int & maxDepth); static long long CornerIndex(const int &depth, const int offSet[DIMENSION], const int &cIndex, const int &maxDepth, int index[DIMENSION]); static long long CornerIndex(const TreeOctNode * node, const int &cIndex, const int &maxDepth, int index[DIMENSION]); static long long CornerIndex(const TreeOctNode *node, const int & cIndex, const int & maxDepth); static long long CenterIndex(const int &depth, const int offSet[DIMENSION], const int &maxDepth, int index[DIMENSION]); static long long CenterIndex(const TreeOctNode * node, const int &maxDepth, int index[DIMENSION]); static long long CenterIndex(const TreeOctNode *node, const int & maxDepth); }; class SortedTreeNodes { public: TreeOctNode **treeNodes; int * nodeCount; int maxDepth; SortedTreeNodes(void); ~SortedTreeNodes(void); void set(TreeOctNode & root, const int & setIndex); }; class TreeNodeData { public: static int UseIndex; union { int mcIndex; struct { int nodeIndex; Real centerWeightContribution; }; }; Real value; TreeNodeData(); ~TreeNodeData(); }; template< int Degree > class Octree { TreeOctNode::NeighborKey neighborKey; TreeOctNode::NeighborKey2 neighborKey2; Real radius; int width; void setNodeIndices(TreeOctNode & tree, int & idx); Real GetDotProduct(const int index[DIMENSION]) const; Real GetLaplacian(const int index[DIMENSION]) const; Real GetDivergence(const int index[DIMENSION], const Point3D< Real > & normal) const; class DivergenceFunction { public: Point3D< Real > normal; Octree< Degree > *ot; int index[DIMENSION], scratch[DIMENSION]; void Function(TreeOctNode *node1, const TreeOctNode *node2); }; class LaplacianProjectionFunction { public: double value; Octree< Degree > *ot; int index[DIMENSION], scratch[DIMENSION]; void Function(TreeOctNode *node1, const TreeOctNode *node2); }; class LaplacianMatrixFunction { public: int x2, y2, z2, d2; Octree< Degree > * ot; int index[DIMENSION], scratch[DIMENSION]; int elementCount, offset; MatrixEntry< float > *rowElements; int Function(const TreeOctNode *node1, const TreeOctNode *node2); }; class RestrictedLaplacianMatrixFunction { public: int depth, offset[3]; Octree< Degree > * ot; Real radius; int index[DIMENSION], scratch[DIMENSION]; int elementCount; MatrixEntry< float > *rowElements; int Function(const TreeOctNode *node1, const TreeOctNode *node2); }; /////////////////////////// // Evaluation Functions // /////////////////////////// class PointIndexValueFunction { public: int res2; FunctionDataReal *valueTables; int index[DIMENSION]; Real value; void Function(const TreeOctNode *node); }; class PointIndexValueAndNormalFunction { public: int res2; FunctionDataReal *valueTables; FunctionDataReal *dValueTables; Real value; Point3D< Real > normal; int index[DIMENSION]; void Function(const TreeOctNode *node); }; class AdjacencyCountFunction { public: int adjacencyCount; void Function(const TreeOctNode *node1, const TreeOctNode *node2); }; class AdjacencySetFunction { public: int *adjacencies, adjacencyCount; void Function(const TreeOctNode *node1, const TreeOctNode *node2); }; class RefineFunction { public: int depth; void Function(TreeOctNode *node1, const TreeOctNode *node2); }; class FaceEdgesFunction { public: int fIndex, maxDepth; std::vector< std::pair< long long, long long > > * edges; hash_map< long long, std::pair< RootInfo, int > > *vertexCount; void Function(const TreeOctNode *node1, const TreeOctNode *node2); }; int SolveFixedDepthMatrix(const int & depth, const SortedTreeNodes & sNodes); int SolveFixedDepthMatrix(const int & depth, const int & startingDepth, const SortedTreeNodes & sNodes); int GetFixedDepthLaplacian(SparseSymmetricMatrix< float > & matrix, const int & depth, const SortedTreeNodes & sNodes); int GetRestrictedFixedDepthLaplacian(SparseSymmetricMatrix< float > & matrix, const int & depth, const int *entries, const int & entryCount, const TreeOctNode *rNode, const Real & radius, const SortedTreeNodes & sNodes); void SetIsoSurfaceCorners(const Real & isoValue, const int & subdivisionDepth, const int & fullDepthIso); static int IsBoundaryFace(const TreeOctNode *node, const int & faceIndex, const int & subdivideDepth); static int IsBoundaryEdge(const TreeOctNode *node, const int & edgeIndex, const int & subdivideDepth); static int IsBoundaryEdge(const TreeOctNode *node, const int & dir, const int & x, const int & y, const int & subidivideDepth); void PreValidate(const Real & isoValue, const int & maxDepth, const int & subdivideDepth); void PreValidate(TreeOctNode *node, const Real & isoValue, const int & maxDepth, const int & subdivideDepth); void Validate(TreeOctNode *node, const Real & isoValue, const int & maxDepth, const int & fullDepthIso, const int & subdivideDepth); void Validate(TreeOctNode *node, const Real & isoValue, const int & maxDepth, const int & fullDepthIso); void Subdivide(TreeOctNode *node, const Real & isoValue, const int & maxDepth); int SetBoundaryMCRootPositions(const int & sDepth, const Real & isoValue, hash_map< long long, int > & boundaryRoots, hash_map< long long, std::pair< Real, Point3D< Real > > > & boundaryNormalHash, CoredMeshData *mesh, const int & nonLinearFit); int SetMCRootPositions(TreeOctNode *node, const int & sDepth, const Real & isoValue, hash_map< long long, int > & boundaryRoots, hash_map< long long, int > *interiorRoots, hash_map< long long, std::pair< Real, Point3D< Real > > > & boundaryNormalHash, hash_map< long long, std::pair< Real, Point3D< Real > > > *interiorNormalHash, std::vector< Point3D< float > > *interiorPositions, CoredMeshData *mesh, const int & nonLinearFit); int GetMCIsoTriangles(TreeOctNode *node, CoredMeshData *mesh, hash_map< long long, int > & boundaryRoots, hash_map< long long, int > *interiorRoots, std::vector< Point3D< float > > *interiorPositions, const int & offSet, const int & sDepth, bool addBarycenter); static int AddTriangles(CoredMeshData *mesh, std::vector< CoredPointIndex > edges[3], std::vector< Point3D< float > > *interiorPositions, const int & offSet); static int AddTriangles(CoredMeshData *mesh, std::vector< CoredPointIndex > & edges, std::vector< Point3D< float > > *interiorPositions, const int & offSet, bool addBarycenter); void GetMCIsoEdges(TreeOctNode *node, hash_map< long long, int > & boundaryRoots, hash_map< long long, int > *interiorRoots, const int & sDepth, std::vector< std::pair< long long, long long > > & edges); static int GetEdgeLoops(std::vector< std::pair< long long, long long > > & edges, std::vector< std::vector< std::pair< long long, long long > > > & loops); static int InteriorFaceRootCount(const TreeOctNode *node, const int & faceIndex, const int & maxDepth); static int EdgeRootCount(const TreeOctNode *node, const int & edgeIndex, const int & maxDepth); int GetRoot(const RootInfo & ri, const Real & isoValue, const int & maxDepth, Point3D< Real > & position, hash_map< long long, std::pair< Real, Point3D< Real > > > & normalHash, Point3D< Real > *normal, const int & nonLinearFit); int GetRoot(const RootInfo & ri, const Real & isoValue, Point3D< Real > & position, hash_map< long long, std::pair< Real, Point3D< Real > > > & normalHash, const int & nonLinearFit); static int GetRootIndex(const TreeOctNode *node, const int & edgeIndex, const int & maxDepth, RootInfo & ri); static int GetRootIndex(const TreeOctNode *node, const int & edgeIndex, const int & maxDepth, const int & sDepth, RootInfo & ri); static int GetRootIndex(const long long & key, hash_map< long long, int > & boundaryRoots, hash_map< long long, int > *interiorRoots, CoredPointIndex & index); static int GetRootPair(const RootInfo & root, const int & maxDepth, RootInfo & pair); int NonLinearUpdateWeightContribution( TreeOctNode *node, const Point3D< Real > & position, const Real & weight = Real( 1.0) ); Real NonLinearGetSampleWeight(TreeOctNode *node, const Point3D< Real > & position); void NonLinearGetSampleDepthAndWeight(TreeOctNode *node, const Point3D< Real > & position, const Real & samplesPerNode, Real & depth, Real & weight); int NonLinearSplatOrientedPoint(TreeOctNode *node, const Point3D< Real > & point, const Point3D< Real > & normal); void NonLinearSplatOrientedPoint(const Point3D< Real > & point, const Point3D< Real > & normal, const int & kernelDepth, const Real & samplesPerNode, const int & minDepth, const int & maxDepth); int HasNormals(TreeOctNode *node, const Real & epsilon); Real getCenterValue(const TreeOctNode *node); Real getCornerValue(const TreeOctNode *node, const int & corner); void getCornerValueAndNormal(const TreeOctNode *node, const int & corner, Real & value, Point3D< Real > & normal); public: // static double maxMemoryUsage; //static double MemoryUsage(void); std::vector< Point3D< Real > > * normals; Real postNormalSmooth; TreeOctNode tree; FunctionData< Degree, FunctionDataReal > fData; Octree(void); void setFunctionData(const PPolynomial< Degree > & ReconstructionFunction, const int & maxDepth, const int & normalize, const Real & normalSmooth = -1); void finalize1(const int & refineNeighbors = -1); void finalize2(const int & refineNeighbors = -1); int setTree(vtkSmartPointer< vtkPolyData > data, const int & maxDepth, const int & kernelDepth, const Real & samplesPerNode, const Real & scaleFactor, Point3D< Real > & center, Real & scale, const int & resetSampleDepths, const int & useConfidence); void SetLaplacianWeights(void); void ClipTree(void); int LaplacianMatrixIteration(const int & subdivideDepth); Real GetIsoValue(void); void GetMCIsoTriangles(const Real & isoValue, CoredMeshData *mesh, const int & fullDepthIso = 0, const int & nonLinearFit = 1, bool addBarycenter=false); void GetMCIsoTriangles(const Real & isoValue, const int & subdivideDepth, CoredMeshData *mesh, const int & fullDepthIso = 0, const int & nonLinearFit = 1, bool addBarycenter=false); }; #include "MultiGridOctreeData.inl" #endif // MULTI_GRID_OCTREE_DATA_INCLUDED GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Polynomial.inl0000644000175000017500000002264211667757442026054 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "Factor.h" //////////////// // Polynomial // //////////////// template Polynomial::Polynomial(void){memset(coefficients,0,sizeof(double)*(Degree+1));} template template Polynomial::Polynomial(const Polynomial& P){ memset(coefficients,0,sizeof(double)*(Degree+1)); for(int i=0;i<=Degree && i<=Degree2;i++){coefficients[i]=P.coefficients[i];} } template template Polynomial& Polynomial::operator = (const Polynomial &p){ int d=Degree Polynomial Polynomial::derivative(void) const{ Polynomial p; for(int i=0;i Polynomial Polynomial::integral(void) const{ Polynomial p; p.coefficients[0]=0; for(int i=0;i<=Degree;i++){p.coefficients[i+1]=coefficients[i]/(i+1);} return p; } template double Polynomial::operator() (const double& t) const{ double temp=1; double v=0; for(int i=0;i<=Degree;i++){ v+=temp*coefficients[i]; temp*=t; } return v; } template double Polynomial::integral(const double& tMin,const double& tMax) const{ double v=0; double t1,t2; t1=tMin; t2=tMax; for(int i=0;i<=Degree;i++){ v+=coefficients[i]*(t2-t1)/(i+1); if(t1!=-DBL_MAX && t1!=DBL_MAX){t1*=tMin;} if(t2!=-DBL_MAX && t2!=DBL_MAX){t2*=tMax;} } return v; } template int Polynomial::operator == (const Polynomial& p) const{ for(int i=0;i<=Degree;i++){if(coefficients[i]!=p.coefficients[i]){return 0;}} return 1; } template int Polynomial::operator != (const Polynomial& p) const{ for(int i=0;i<=Degree;i++){if(coefficients[i]==p.coefficients[i]){return 0;}} return 1; } template int Polynomial::isZero(void) const{ for(int i=0;i<=Degree;i++){if(coefficients[i]!=0){return 0;}} return 1; } template void Polynomial::setZero(void){memset(coefficients,0,sizeof(double)*(Degree+1));} template Polynomial& Polynomial::addScaled(const Polynomial& p,const double& s){ for(int i=0;i<=Degree;i++){coefficients[i]+=p.coefficients[i]*s;} return *this; } template Polynomial& Polynomial::operator += (const Polynomial& p){ for(int i=0;i<=Degree;i++){coefficients[i]+=p.coefficients[i];} return *this; } template Polynomial& Polynomial::operator -= (const Polynomial& p){ for(int i=0;i<=Degree;i++){coefficients[i]-=p.coefficients[i];} return *this; } template Polynomial Polynomial::operator + (const Polynomial& p) const{ Polynomial q; for(int i=0;i<=Degree;i++){q.coefficients[i]=(coefficients[i]+p.coefficients[i]);} return q; } template Polynomial Polynomial::operator - (const Polynomial& p) const{ Polynomial q; for(int i=0;i<=Degree;i++) {q.coefficients[i]=coefficients[i]-p.coefficients[i];} return q; } template void Polynomial::Scale(const Polynomial& p,const double& w,Polynomial& q){ for(int i=0;i<=Degree;i++){q.coefficients[i]=p.coefficients[i]*w;} } template void Polynomial::AddScaled(const Polynomial& p1,const double& w1,const Polynomial& p2,const double& w2,Polynomial& q){ for(int i=0;i<=Degree;i++){q.coefficients[i]=p1.coefficients[i]*w1+p2.coefficients[i]*w2;} } template void Polynomial::AddScaled(const Polynomial& p1,const double& w1,const Polynomial& p2,Polynomial& q){ for(int i=0;i<=Degree;i++){q.coefficients[i]=p1.coefficients[i]*w1+p2.coefficients[i];} } template void Polynomial::AddScaled(const Polynomial& p1,const Polynomial& p2,const double& w2,Polynomial& q){ for(int i=0;i<=Degree;i++){q.coefficients[i]=p1.coefficients[i]+p2.coefficients[i]*w2;} } template void Polynomial::Subtract(const Polynomial &p1,const Polynomial& p2,Polynomial& q){ for(int i=0;i<=Degree;i++){q.coefficients[i]=p1.coefficients[i]-p2.coefficients[i];} } template void Polynomial::Negate(const Polynomial& in,Polynomial& out){ out=in; for(int i=0;i<=Degree;i++){out.coefficients[i]=-out.coefficients[i];} } template Polynomial Polynomial::operator - (void) const{ Polynomial q=*this; for(int i=0;i<=Degree;i++){q.coefficients[i]=-q.coefficients[i];} return q; } template template Polynomial Polynomial::operator * (const Polynomial& p) const{ Polynomial q; for(int i=0;i<=Degree;i++){for(int j=0;j<=Degree2;j++){q.coefficients[i+j]+=coefficients[i]*p.coefficients[j];}} return q; } template Polynomial& Polynomial::operator += (const double& s){ coefficients[0]+=s; return *this; } template Polynomial& Polynomial::operator -= (const double& s){ coefficients[0]-=s; return *this; } template Polynomial& Polynomial::operator *= (const double& s){ for(int i=0;i<=Degree;i++){coefficients[i]*=s;} return *this; } template Polynomial& Polynomial::operator /= (const double& s){ for(int i=0;i<=Degree;i++){coefficients[i]/=s;} return *this; } template Polynomial Polynomial::operator + (const double& s) const{ Polynomial q=*this; q.coefficients[0]+=s; return q; } template Polynomial Polynomial::operator - (const double& s) const{ Polynomial q=*this; q.coefficients[0]-=s; return q; } template Polynomial Polynomial::operator * (const double& s) const{ Polynomial q; for(int i=0;i<=Degree;i++){q.coefficients[i]=coefficients[i]*s;} return q; } template Polynomial Polynomial::operator / (const double& s) const{ Polynomial q(this->degree()); for(int i=0;i<=Degree;i++){q.coefficients[i]=coefficients[i]/s;} return q; } template Polynomial Polynomial::scale(const double& s) const{ Polynomial q=*this; double s2=1.0; for(int i=0;i<=Degree;i++){ q.coefficients[i]*=s2; s2/=s; } return q; } template Polynomial Polynomial::shift(const double& t) const{ Polynomial q; for(int i=0;i<=Degree;i++){ double temp=1; for(int j=i;j>=0;j--){ q.coefficients[j]+=coefficients[i]*temp; temp*=-t*j; temp/=(i-j+1); } } return q; } template void Polynomial::printnl(void) const{ for(int j=0;j<=Degree;j++){ printf("%6.4f x^%d ",coefficients[j],j); if(j=0){printf("+");} } printf("\n"); } template void Polynomial::getSolutions(const double& c,std::vector& roots,const double& EPS) const { double r[4][2]; int rCount=0; roots.clear(); switch(Degree){ case 1: rCount=Factor(coefficients[1],coefficients[0]-c,r,EPS); break; case 2: rCount=Factor(coefficients[2],coefficients[1],coefficients[0]-c,r,EPS); break; case 3: rCount=Factor(coefficients[3],coefficients[2],coefficients[1],coefficients[0]-c,r,EPS); break; // case 4: // rCount=Factor(coefficients[4],coefficients[3],coefficients[2],coefficients[1],coefficients[0]-c,r,EPS); // break; default: printf("Can't solve polynomial of degree: %d\n",Degree); } for(int i=0;i #include "Geometry.h" class Square { public: const static int CORNERS = 4, EDGES = 4, NEIGHBORS = 4; static int CornerIndex(const int & x, const int & y); static void FactorCornerIndex(const int & idx, int & x, int & y); static int EdgeIndex(const int & orientation, const int & i); static void FactorEdgeIndex(const int & idx, int & orientation, int & i); static int ReflectCornerIndex(const int & idx, const int & edgeIndex); static int ReflectEdgeIndex(const int & idx, const int & edgeIndex); static void EdgeCorners(const int & idx, int & c1, int & c2); }; class Cube { public: const static int CORNERS = 8, EDGES = 12, NEIGHBORS = 6; static int CornerIndex(const int & x, const int & y, const int & z); static void FactorCornerIndex(const int & idx, int & x, int & y, int & z); static int EdgeIndex(const int & orientation, const int & i, const int & j); static void FactorEdgeIndex(const int & idx, int & orientation, int & i, int & j); static int FaceIndex(const int & dir, const int & offSet); static int FaceIndex(const int & x, const int & y, const int & z); static void FactorFaceIndex(const int & idx, int & x, int & y, int & z); static void FactorFaceIndex(const int & idx, int & dir, int & offSet); static int AntipodalCornerIndex(const int & idx); static int FaceReflectCornerIndex(const int & idx, const int & faceIndex); static int FaceReflectEdgeIndex(const int & idx, const int & faceIndex); static int FaceReflectFaceIndex(const int & idx, const int & faceIndex); static int EdgeReflectCornerIndex(const int & idx, const int & edgeIndex); static int EdgeReflectEdgeIndex(const int & edgeIndex); static int FaceAdjacentToEdges(const int & eIndex1, const int & eIndex2); static void FacesAdjacentToEdge(const int & eIndex, int & f1Index, int & f2Index); static void EdgeCorners(const int & idx, int & c1, int & c2); static void FaceCorners(const int & idx, int & c1, int & c2, int & c3, int & c4); }; class MarchingSquares { static double Interpolate(const double & v1, const double & v2); static void SetVertex(const int & e, const double values[Square::CORNERS], const double & iso); public: const static int MAX_EDGES = 2; static const int edgeMask[1 << Square::CORNERS]; static const int edges[1 << Square::CORNERS][2 * MAX_EDGES + 1]; static double vertexList[Square::EDGES][2]; static int GetIndex(const double values[Square::CORNERS], const double & iso); static int IsAmbiguous(const double v[Square::CORNERS], const double & isoValue); static int AddEdges(const double v[Square::CORNERS], const double & isoValue, Edge *edges); static int AddEdgeIndices(const double v[Square::CORNERS], const double & isoValue, int *edges); }; class MarchingCubes { static double Interpolate(const double & v1, const double & v2); static void SetVertex(const int & e, const double values[Cube::CORNERS], const double & iso); static int GetFaceIndex(const double values[Cube::CORNERS], const double & iso, const int & faceIndex); static float Interpolate(const float & v1, const float & v2); static void SetVertex(const int & e, const float values[Cube::CORNERS], const float & iso); static int GetFaceIndex(const float values[Cube::CORNERS], const float & iso, const int & faceIndex); static int GetFaceIndex(const int & mcIndex, const int & faceIndex); public: const static int MAX_TRIANGLES = 5; static const int edgeMask[1 << Cube::CORNERS]; static const int triangles[1 << Cube::CORNERS][3 * MAX_TRIANGLES + 1]; static const int cornerMap[Cube::CORNERS]; static double vertexList[Cube::EDGES][3]; static int AddTriangleIndices(const int & mcIndex, int *triangles); static int GetIndex(const double values[Cube::CORNERS], const double & iso); static int IsAmbiguous(const double v[Cube::CORNERS], const double & isoValue, const int & faceIndex); static int HasRoots(const double v[Cube::CORNERS], const double & isoValue); static int HasRoots(const double v[Cube::CORNERS], const double & isoValue, const int & faceIndex); static int AddTriangles(const double v[Cube::CORNERS], const double & isoValue, Triangle *triangles); static int AddTriangleIndices(const double v[Cube::CORNERS], const double & isoValue, int *triangles); static int GetIndex(const float values[Cube::CORNERS], const float & iso); static int IsAmbiguous(const float v[Cube::CORNERS], const float & isoValue, const int & faceIndex); static int HasRoots(const float v[Cube::CORNERS], const float & isoValue); static int HasRoots(const float v[Cube::CORNERS], const float & isoValue, const int & faceIndex); static int AddTriangles(const float v[Cube::CORNERS], const float & isoValue, Triangle *triangles); static int AddTriangleIndices(const float v[Cube::CORNERS], const float & isoValue, int *triangles); static int IsAmbiguous(const int & mcIndex, const int & faceIndex); static int HasRoots(const int & mcIndex); static int HasFaceRoots(const int & mcIndex, const int & faceIndex); static int HasEdgeRoots(const int & mcIndex, const int & edgeIndex); }; #endif //MARCHING_CUBES_INCLUDED GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Polynomial.h0000644000175000017500000001022211667757442025510 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef POLYNOMIAL_INCLUDED #define POLYNOMIAL_INCLUDED #include template< int Degree > class Polynomial { public: double coefficients[Degree + 1]; Polynomial(void); template< int Degree2 > Polynomial(const Polynomial< Degree2 > & P); double operator()(const double & t) const; double integral(const double & tMin, const double & tMax) const; int operator==(const Polynomial & p) const; int operator!=(const Polynomial & p) const; int isZero(void) const; void setZero(void); template< int Degree2 > Polynomial & operator=(const Polynomial< Degree2 > & p); Polynomial & operator+=(const Polynomial & p); Polynomial & operator-=(const Polynomial & p); Polynomial operator-(void) const; Polynomial operator+(const Polynomial & p) const; Polynomial operator-(const Polynomial & p) const; template< int Degree2 > Polynomial< Degree + Degree2 > operator *(const Polynomial< Degree2 > & p) const; Polynomial & operator+=(const double & s); Polynomial & operator-=(const double & s); Polynomial & operator*=(const double & s); Polynomial & operator/=(const double & s); Polynomial operator+(const double & s) const; Polynomial operator-(const double & s) const; Polynomial operator *(const double & s) const; Polynomial operator/(const double & s) const; Polynomial scale(const double & s) const; Polynomial shift(const double & t) const; Polynomial< Degree - 1 > derivative(void) const; Polynomial< Degree + 1 > integral(void) const; void printnl(void) const; Polynomial & addScaled(const Polynomial & p, const double & scale); static void Negate(const Polynomial & in, Polynomial & out); static void Subtract(const Polynomial & p1, const Polynomial & p2, Polynomial & q); static void Scale(const Polynomial & p, const double & w, Polynomial & q); static void AddScaled(const Polynomial & p1, const double & w1, const Polynomial & p2, const double & w2, Polynomial & q); static void AddScaled(const Polynomial & p1, const Polynomial & p2, const double & w2, Polynomial & q); static void AddScaled(const Polynomial & p1, const double & w1, const Polynomial & p2, Polynomial & q); void getSolutions(const double & c, std::vector< double > & roots, const double & EPS) const; }; #include "Polynomial.inl" #endif // POLYNOMIAL_INCLUDED GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/MultiGridOctreeData.cpp0000644000175000017500000000350511667757442027562 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "MultiGridOctreeData.h" int TreeNodeData::UseIndex=1; GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/SparseMatrix.h0000644000175000017500000001333711667757442026021 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __SPARSEMATRIX_HPP #define __SPARSEMATRIX_HPP #include "Vector.h" #include "Allocator.h" template< class T > struct MatrixEntry { MatrixEntry(void) { N = -1; Value = 0; } MatrixEntry(int i) { N = i; Value = 0; } int N; T Value; }; template< class T, int Dim > struct NMatrixEntry { NMatrixEntry(void) { N = -1; memset(Value, 0, sizeof( T ) * Dim); } NMatrixEntry(int i) { N = i; memset(Value, 0, sizeof( T ) * Dim); } int N; T Value[Dim]; }; template< class T > class SparseMatrix { private: static int UseAlloc; public: static Allocator< MatrixEntry< T > > MatrixAllocator; static int UseAllocator(void); static void SetAllocator(const int & blockSize); int rows; int *rowSizes; MatrixEntry< T > **m_ppElements; SparseMatrix(); SparseMatrix(int rows); void Resize(int rows); void SetRowSize(int row, int count); int Entries(void); SparseMatrix(const SparseMatrix & M); ~SparseMatrix(); void SetZero(); void SetIdentity(); SparseMatrix< T > & operator=(const SparseMatrix< T > & M); SparseMatrix< T > operator *(const T & V) const; SparseMatrix< T > & operator*=(const T & V); SparseMatrix< T > operator*(const SparseMatrix< T > & M) const; SparseMatrix< T > Multiply(const SparseMatrix< T > & M) const; SparseMatrix< T > MultiplyTranspose(const SparseMatrix< T > & Mt) const; template< class T2 > Vector< T2 > operator*(const Vector< T2 > & V) const; template< class T2 > Vector< T2 > Multiply(const Vector< T2 > & V) const; template< class T2 > void Multiply(const Vector< T2 > & In, Vector< T2 > & Out) const; SparseMatrix< T > Transpose() const; static int Solve(const SparseMatrix< T > & M, const Vector< T > & b, const int & iters, Vector< T > & solution, const T eps = 1e-8); template< class T2 > static int SolveSymmetric(const SparseMatrix< T > & M, const Vector< T2 > & b, const int & iters, Vector< T2 > & solution, const T2 eps = 1e-8, const int & reset = 1); }; template< class T, int Dim > class SparseNMatrix { private: static int UseAlloc; public: static Allocator< NMatrixEntry< T, Dim > > NMatrixAllocator; static int UseAllocator(void); static void SetAllocator(const int & blockSize); int rows; int *rowSizes; NMatrixEntry< T, Dim > **m_ppElements; SparseNMatrix(); SparseNMatrix(int rows); void Resize(int rows); void SetRowSize(int row, int count); int Entries(void); SparseNMatrix(const SparseNMatrix & M); ~SparseNMatrix(); SparseNMatrix & operator=(const SparseNMatrix & M); SparseNMatrix operator *(const T & V) const; SparseNMatrix & operator*=(const T & V); template< class T2 > NVector< T2, Dim > operator*(const Vector< T2 > & V) const; template< class T2 > Vector< T2 > operator*(const NVector< T2, Dim > & V) const; }; template< class T > class SparseSymmetricMatrix:public SparseMatrix< T > { public: template< class T2 > Vector< T2 > operator*(const Vector< T2 > & V) const; template< class T2 > Vector< T2 > Multiply(const Vector< T2 > & V) const; template< class T2 > void Multiply(const Vector< T2 > & In, Vector< T2 > & Out) const; template< class T2 > static int Solve(const SparseSymmetricMatrix< T > & M, const Vector< T2 > & b, const int & iters, Vector< T2 > & solution, const T2 eps = 1e-8, const int & reset = 1); template< class T2 > static int Solve(const SparseSymmetricMatrix< T > & M, const Vector< T > & diagonal, const Vector< T2 > & b, const int & iters, Vector< T2 > & solution, const T2 eps = 1e-8, const int & reset = 1); }; #include "SparseMatrix.inl" #endif GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Geometry.inl0000644000175000017500000003342611667757442025526 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include template Real Random(void){return Real(rand())/RAND_MAX;} template Point3D RandomBallPoint(void){ Point3D p; while(1){ p.coords[0]=Real(1.0-2.0*Random()); p.coords[1]=Real(1.0-2.0*Random()); p.coords[2]=Real(1.0-2.0*Random()); double l=SquareLength(p); if(l<=1){return p;} } } template Point3D RandomSpherePoint(void){ Point3D p=RandomBallPoint(); Real l=Real(Length(p)); p.coords[0]/=l; p.coords[1]/=l; p.coords[2]/=l; return p; } template double SquareLength(const Point3D& p){return p.coords[0]*p.coords[0]+p.coords[1]*p.coords[1]+p.coords[2]*p.coords[2];} template double Length(const Point3D& p){return sqrt(SquareLength(p));} template double SquareDistance(const Point3D& p1,const Point3D& p2){ return (p1.coords[0]-p2.coords[0])*(p1.coords[0]-p2.coords[0])+(p1.coords[1]-p2.coords[1])*(p1.coords[1]-p2.coords[1])+(p1.coords[2]-p2.coords[2])*(p1.coords[2]-p2.coords[2]); } template double Distance(const Point3D& p1,const Point3D& p2){return sqrt(SquareDistance(p1,p2));} template void CrossProduct(const Point3D& p1,const Point3D& p2,Point3D& p){ p.coords[0]= p1.coords[1]*p2.coords[2]-p1.coords[2]*p2.coords[1]; p.coords[1]=-p1.coords[0]*p2.coords[2]+p1.coords[2]*p2.coords[0]; p.coords[2]= p1.coords[0]*p2.coords[1]-p1.coords[1]*p2.coords[0]; } template void EdgeCollapse(const Real& edgeRatio,std::vector& triangles,std::vector< Point3D >& positions,std::vector< Point3D >* normals){ int i,j,*remapTable,*pointCount,idx[3]; Point3D p[3],q[2],c; double d[3],a; double Ratio=12.0/sqrt(3.0); // (Sum of Squares Length / Area) for and equilateral triangle remapTable=new int[positions.size()]; pointCount=new int[positions.size()]; for(i=0;i=0;i--){ for(j=0;j<3;j++){ idx[j]=triangles[i].idx[j]; while(remapTable[idx[j]] a*Ratio){ // Find the smallest edge j=0; if(d[1]=0;i--){ for(j=0;j<3;j++){ idx[j]=triangles[i].idx[j]; while(remapTable[idx[j]] void TriangleCollapse(const Real& edgeRatio,std::vector& triangles,std::vector< Point3D >& positions,std::vector< Point3D >* normals){ int i,j,*remapTable,*pointCount,idx[3]; Point3D p[3],q[2],c; double d[3],a; double Ratio=12.0/sqrt(3.0); // (Sum of Squares Length / Area) for and equilateral triangle remapTable=new int[positions.size()]; pointCount=new int[positions.size()]; for(i=0;i=0;i--){ for(j=0;j<3;j++){ idx[j]=triangles[i].idx[j]; while(remapTable[idx[j]] a*Ratio){ // Find the smallest edge j=0; if(d[1]=0;i--){ for(j=0;j<3;j++){ idx[j]=triangles[i].idx[j]; while(remapTable[idx[j]] long long Triangulation::EdgeIndex(const int& p1,const int& p2){ if(p1>p2) {return ((long long)(p1)<<32) | ((long long)(p2));} else {return ((long long)(p2)<<32) | ((long long)(p1));} } template int Triangulation::factor(const int& tIndex,int& p1,int& p2,int & p3){ if(triangles[tIndex].eIndex[0]<0 || triangles[tIndex].eIndex[1]<0 || triangles[tIndex].eIndex[2]<0){return 0;} if(edges[triangles[tIndex].eIndex[0]].tIndex[0]==tIndex){p1=edges[triangles[tIndex].eIndex[0]].pIndex[0];} else {p1=edges[triangles[tIndex].eIndex[0]].pIndex[1];} if(edges[triangles[tIndex].eIndex[1]].tIndex[0]==tIndex){p2=edges[triangles[tIndex].eIndex[1]].pIndex[0];} else {p2=edges[triangles[tIndex].eIndex[1]].pIndex[1];} if(edges[triangles[tIndex].eIndex[2]].tIndex[0]==tIndex){p3=edges[triangles[tIndex].eIndex[2]].pIndex[0];} else {p3=edges[triangles[tIndex].eIndex[2]].pIndex[1];} return 1; } template double Triangulation::area(const int& p1,const int& p2,const int& p3){ Point3D q1,q2,q; for(int i=0;i<3;i++){ q1.coords[i]=points[p2].coords[i]-points[p1].coords[i]; q2.coords[i]=points[p3].coords[i]-points[p1].coords[i]; } CrossProduct(q1,q2,q); return Length(q); } template double Triangulation::area(const int& tIndex){ int p1,p2,p3; factor(tIndex,p1,p2,p3); return area(p1,p2,p3); } template double Triangulation::area(void){ double a=0; for(int i=0;i int Triangulation::addTriangle(const int& p1,const int& p2,const int& p3){ hash_map::iterator iter; int tIdx,eIdx,p[3]; p[0]=p1; p[1]=p2; p[2]=p3; triangles.push_back(TriangulationTriangle()); tIdx=int(triangles.size())-1; for(int i=0;i<3;i++) { long long e = EdgeIndex(p[i],p[(i+1)%3]); iter=edgeMap.find(e); if(iter==edgeMap.end()) { TriangulationEdge edge; edge.pIndex[0]=p[i]; edge.pIndex[1]=p[(i+1)%3]; edges.push_back(edge); eIdx=int(edges.size())-1; edgeMap[e]=eIdx; edges[eIdx].tIndex[0]=tIdx; } else{ eIdx=edgeMap[e]; if(edges[eIdx].pIndex[0]==p[i]){ if(edges[eIdx].tIndex[0]<0){edges[eIdx].tIndex[0]=tIdx;} else{printf("Edge Triangle in use 1\n");return 0;} } else{ if(edges[eIdx].tIndex[1]<0){edges[eIdx].tIndex[1]=tIdx;} else{printf("Edge Triangle in use 2\n");return 0;} } } triangles[tIdx].eIndex[i]=eIdx; } return tIdx; } template int Triangulation::flipMinimize(const int& eIndex){ double oldArea,newArea; int oldP[3],oldQ[3],newP[3],newQ[3]; TriangulationEdge newEdge; if(edges[eIndex].tIndex[0]<0 || edges[eIndex].tIndex[1]<0){return 0;} if(!factor(edges[eIndex].tIndex[0],oldP[0],oldP[1],oldP[2])){return 0;} if(!factor(edges[eIndex].tIndex[1],oldQ[0],oldQ[1],oldQ[2])){return 0;} oldArea=area(oldP[0],oldP[1],oldP[2])+area(oldQ[0],oldQ[1],oldQ[2]); int idxP,idxQ; for(idxP=0;idxP<3;idxP++){ int i; for(i=0;i<3;i++){if(oldP[idxP]==oldQ[i]){break;}} if(i==3){break;} } for(idxQ=0;idxQ<3;idxQ++){ int i; for(i=0;i<3;i++){if(oldP[i]==oldQ[idxQ]){break;}} if(i==3){break;} } if(idxP==3 || idxQ==3){return 0;} newP[0]=oldP[idxP]; newP[1]=oldP[(idxP+1)%3]; newP[2]=oldQ[idxQ]; newQ[0]=oldQ[idxQ]; newQ[1]=oldP[(idxP+2)%3]; newQ[2]=oldP[idxP]; newArea=area(newP[0],newP[1],newP[2])+area(newQ[0],newQ[1],newQ[2]); if(oldArea<=newArea){return 0;} // Remove the entry in the hash_table for the old edge edgeMap.erase(EdgeIndex(edges[eIndex].pIndex[0],edges[eIndex].pIndex[1])); // Set the new edge so that the zero-side is newQ edges[eIndex].pIndex[0]=newP[0]; edges[eIndex].pIndex[1]=newQ[0]; // Insert the entry into the hash_table for the new edge edgeMap[EdgeIndex(newP[0],newQ[0])]=eIndex; // Update the triangle information for(int i=0;i<3;i++){ int idx; idx=edgeMap[EdgeIndex(newQ[i],newQ[(i+1)%3])]; triangles[edges[eIndex].tIndex[0]].eIndex[i]=idx; if(idx!=eIndex){ if(edges[idx].tIndex[0]==edges[eIndex].tIndex[1]){edges[idx].tIndex[0]=edges[eIndex].tIndex[0];} if(edges[idx].tIndex[1]==edges[eIndex].tIndex[1]){edges[idx].tIndex[1]=edges[eIndex].tIndex[0];} } idx=edgeMap[EdgeIndex(newP[i],newP[(i+1)%3])]; triangles[edges[eIndex].tIndex[1]].eIndex[i]=idx; if(idx!=eIndex){ if(edges[idx].tIndex[0]==edges[eIndex].tIndex[0]){edges[idx].tIndex[0]=edges[eIndex].tIndex[1];} if(edges[idx].tIndex[1]==edges[eIndex].tIndex[0]){edges[idx].tIndex[1]=edges[eIndex].tIndex[1];} } } return 1; } GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Octree.inl0000644000175000017500000015355411667757442025161 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include ///////////// // OctNode // ///////////// template const int OctNode::DepthShift=5; template const int OctNode::OffsetShift=19; template const int OctNode::DepthMask=(1< const int OctNode::OffsetMask=(1< const int OctNode::OffsetShift1=DepthShift; template const int OctNode::OffsetShift2=OffsetShift1+OffsetShift; template const int OctNode::OffsetShift3=OffsetShift2+OffsetShift; template int OctNode::UseAlloc=0; template Allocator > OctNode::OctreeAllocator; template inline void OctNode::SetAllocator(int blockSize) { if(blockSize>0) { UseAlloc=1; OctreeAllocator.set(blockSize); } else{UseAlloc=0;} } template inline int OctNode::UseAllocator(void) { return UseAlloc; } template inline OctNode::OctNode(void) { parent=children=NULL; d=off[0]=off[1]=off[2]=0; } template inline OctNode::~OctNode(void) { if(!UseAlloc){if(children){delete[] children;}} parent=children=NULL; } template inline void OctNode::setFullDepth(const int& iMaxDepth) { if(iMaxDepth) { if(!children) { initChildren(); } for(int i=0;i<8;i++) { children[i].setFullDepth(iMaxDepth-1); } } } template inline int OctNode::initChildren(void) { int i,j,k; if(UseAlloc){children=OctreeAllocator.newElements(8);} else{ if(children){delete[] children;} children=NULL; children=new OctNode[Cube::CORNERS]; } if(!children){ fprintf(stderr,"Failed to initialize children in OctNode::initChildren\n"); exit(0); return 0; } int td,toff[3]; depthAndOffset(td,toff); for(i=0;i<2;i++){ for(j=0;j<2;j++){ for(k=0;k<2;k++){ int idx=Cube::CornerIndex(i,j,k); children[idx].parent=this; children[idx].children=NULL; int off2[3]; off2[0]=(toff[0]<<1)+i; off2[1]=(toff[1]<<1)+j; off2[2]=(toff[2]<<1)+k; Index(td+1,off2,children[idx].d,children[idx].off); } } } return 1; } template inline void OctNode::Index(const int& depth,const int offset[3],short& d,short off[3]) { d=short(depth); off[0]=short((1< inline void OctNode::depthAndOffset(int& oDepth,int offset[3]) const { oDepth=int(d); offset[0]=(int(off[0])+1)&(~(1< inline int OctNode::depth(void) const {return int(d);} template inline void OctNode::DepthAndOffset(const long long& index,int& depth,int offset[3]){ depth=int(index&DepthMask); offset[0]=(int((index>>OffsetShift1)&OffsetMask)+1)&(~(1<>OffsetShift2)&OffsetMask)+1)&(~(1<>OffsetShift3)&OffsetMask)+1)&(~(1< inline int OctNode::Depth(const long long& index){return int(index&DepthMask);} template void OctNode::centerAndWidth(Point3D& center,Real& oWidth) const{ int tdepth,offset[3]; tdepth=int(d); offset[0]=(int(off[0])+1)&(~(1< inline void OctNode::CenterAndWidth(const long long& index,Point3D& center,Real& width){ int depth,offset[3]; depth=index&DepthMask; offset[0]=(int((index>>OffsetShift1)&OffsetMask)+1)&(~(1<>OffsetShift2)&OffsetMask)+1)&(~(1<>OffsetShift3)&OffsetMask)+1)&(~(1< inline int OctNode::maxDepth(void) const { if(!children) { return 0; } else { int c = 0; int td = 0; for(int i=0;ic) { c=td; } } return c+1; } } template inline int OctNode::nodes(void) const { if(!children){return 1;} else{ int c=0; for(int i=0;i inline int OctNode::leaves(void) const { if(!children){return 1;} else{ int c=0; for(int i=0;i inline int OctNode::maxDepthLeaves(const int& iMaxDepth) const { if(depth()>iMaxDepth){return 0;} if(!children){return 1;} else{ int c=0; for(int i=0;i inline const OctNode* OctNode::root(void) const { const OctNode* temp=this; while(temp->parent){temp=temp->parent;} return temp; } template inline const OctNode* OctNode::nextBranch(const OctNode* current) const { if(!current->parent || current==this){return NULL;} if(current-current->parent->children==Cube::CORNERS-1){return nextBranch(current->parent);} else{return current+1;} } template inline OctNode* OctNode::nextBranch(OctNode* current) { if(!current->parent || current==this){return NULL;} if(current-current->parent->children==Cube::CORNERS-1){return nextBranch(current->parent);} else{return current+1;} } template const OctNode* OctNode::nextLeaf(const OctNode* current) const { if(!current){ const OctNode* temp=this; while(temp->children){temp=&temp->children[0];} return temp; } if(current->children){return current->nextLeaf();} const OctNode* temp=nextBranch(current); if(!temp){return NULL;} else{return temp->nextLeaf();} } template OctNode* OctNode::nextLeaf(OctNode* current){ if(!current){ OctNode* temp=this; while(temp->children){temp=&temp->children[0];} return temp; } if(current->children){return current->nextLeaf();} OctNode* temp=nextBranch(current); if(!temp){return NULL;} else{return temp->nextLeaf();} } template const OctNode* OctNode::nextNode(const OctNode* current) const { if(!current){return this;} else if(current->children){return ¤t->children[0];} else{return nextBranch(current);} } template OctNode* OctNode::nextNode(OctNode* current) { if(!current){return this;} else if(current->children){return ¤t->children[0];} else{return nextBranch(current);} } template void OctNode::printRange(void) const { Point3D center; Real twidth; centerAndWidth(center,twidth); for(int dim=0;dim void OctNode::AdjacencyCountFunction::Function(const OctNode* node1,const OctNode* node2) { count++; } template template void OctNode::processNodeNodes(OctNode* node,NodeAdjacencyFunction* F,const int& processCurrent) { if(processCurrent){F->Function(this,node);} if(children){__processNodeNodes(node,F);} } template template void OctNode::processNodeFaces(OctNode* node,NodeAdjacencyFunction* F,const int& fIndex,const int& processCurrent) { if(processCurrent){F->Function(this,node);} if(children){ int c1,c2,c3,c4; Cube::FaceCorners(fIndex,c1,c2,c3,c4); __processNodeFaces(node,F,c1,c2,c3,c4); } } template template void OctNode::processNodeEdges(OctNode* node,NodeAdjacencyFunction* F,const int& eIndex,const int& processCurrent){ if(processCurrent){F->Function(this,node);} if(children){ int c1,c2; Cube::EdgeCorners(eIndex,c1,c2); __processNodeEdges(node,F,c1,c2); } } template template void OctNode::processNodeCorners(OctNode* node,NodeAdjacencyFunction* F,const int& cIndex,const int& processCurrent){ if(processCurrent){F->Function(this,node);} OctNode* temp=this; while(temp->children){ temp=&temp->children[cIndex]; F->Function(temp,node); } } template template void OctNode::__processNodeNodes(OctNode* node,NodeAdjacencyFunction* F){ F->Function(&children[0],node); F->Function(&children[1],node); F->Function(&children[2],node); F->Function(&children[3],node); F->Function(&children[4],node); F->Function(&children[5],node); F->Function(&children[6],node); F->Function(&children[7],node); if(children[0].children){children[0].__processNodeNodes(node,F);} if(children[1].children){children[1].__processNodeNodes(node,F);} if(children[2].children){children[2].__processNodeNodes(node,F);} if(children[3].children){children[3].__processNodeNodes(node,F);} if(children[4].children){children[4].__processNodeNodes(node,F);} if(children[5].children){children[5].__processNodeNodes(node,F);} if(children[6].children){children[6].__processNodeNodes(node,F);} if(children[7].children){children[7].__processNodeNodes(node,F);} } template template void OctNode::__processNodeEdges(OctNode* node,NodeAdjacencyFunction* F,const int& cIndex1,const int& cIndex2){ F->Function(&children[cIndex1],node); F->Function(&children[cIndex2],node); if(children[cIndex1].children){children[cIndex1].__processNodeEdges(node,F,cIndex1,cIndex2);} if(children[cIndex2].children){children[cIndex2].__processNodeEdges(node,F,cIndex1,cIndex2);} } template template void OctNode::__processNodeFaces(OctNode* node,NodeAdjacencyFunction* F,const int& cIndex1,const int& cIndex2,const int& cIndex3,const int& cIndex4){ F->Function(&children[cIndex1],node); F->Function(&children[cIndex2],node); F->Function(&children[cIndex3],node); F->Function(&children[cIndex4],node); if(children[cIndex1].children){children[cIndex1].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);} if(children[cIndex2].children){children[cIndex2].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);} if(children[cIndex3].children){children[cIndex3].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);} if(children[cIndex4].children){children[cIndex4].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);} } template template void OctNode::ProcessNodeAdjacentNodes(const int& maxDepth,OctNode* node1,const int& width1,OctNode* node2,const int& width2,NodeAdjacencyFunction* F,const int& processCurrent){ int c1[3],c2[3],w1,w2; node1->centerIndex(maxDepth+1,c1); node2->centerIndex(maxDepth+1,c2); w1=node1->width(maxDepth+1); w2=node2->width(maxDepth+1); ProcessNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,F,processCurrent); } template template void OctNode::ProcessNodeAdjacentNodes(const int& dx,const int& dy,const int& dz, OctNode* node1,const int& radius1, OctNode* node2,const int& radius2,const int& width2, NodeAdjacencyFunction* F,const int& processCurrent){ if(!Overlap(dx,dy,dz,radius1+radius2)){return;} if(processCurrent){F->Function(node2,node1);} if(!node2->children){return;} __ProcessNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,F); } template template void OctNode::ProcessTerminatingNodeAdjacentNodes(const int& maxDepth,OctNode* node1,const int& width1,OctNode* node2,const int& width2,TerminatingNodeAdjacencyFunction* F,const int& processCurrent){ int c1[3],c2[3],w1,w2; node1->centerIndex(maxDepth+1,c1); node2->centerIndex(maxDepth+1,c2); w1=node1->width(maxDepth+1); w2=node2->width(maxDepth+1); ProcessTerminatingNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,F,processCurrent); } template template void OctNode::ProcessTerminatingNodeAdjacentNodes(const int& dx,const int& dy,const int& dz, OctNode* node1,const int& radius1, OctNode* node2,const int& radius2,const int& width2, TerminatingNodeAdjacencyFunction* F,const int& processCurrent) { if(!Overlap(dx,dy,dz,radius1+radius2)){return;} if(processCurrent){F->Function(node2,node1);} if(!node2->children){return;} __ProcessTerminatingNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,F); } template template void OctNode::ProcessPointAdjacentNodes(const int& maxDepth,const int c1[3],OctNode* node2,const int& width2,PointAdjacencyFunction* F,const int& processCurrent){ int c2[3],w2; node2->centerIndex(maxDepth+1,c2); w2=node2->width(maxDepth+1); ProcessPointAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node2,(width2*w2)>>1,w2,F,processCurrent); } template template void OctNode::ProcessPointAdjacentNodes(const int& dx,const int& dy,const int& dz, OctNode* node2,const int& radius2,const int& width2, PointAdjacencyFunction* F,const int& processCurrent) { if(!Overlap(dx,dy,dz,radius2)){return;} if(processCurrent){F->Function(node2);} if(!node2->children){return;} __ProcessPointAdjacentNodes(-dx,-dy,-dz,node2,radius2,width2>>1,F); } template template void OctNode::ProcessFixedDepthNodeAdjacentNodes(const int& maxDepth, OctNode* node1,const int& width1, OctNode* node2,const int& width2, const int& depth,NodeAdjacencyFunction* F,const int& processCurrent) { int c1[3],c2[3],w1,w2; node1->centerIndex(maxDepth+1,c1); node2->centerIndex(maxDepth+1,c2); w1=node1->width(maxDepth+1); w2=node2->width(maxDepth+1); ProcessFixedDepthNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,depth,F,processCurrent); } template template void OctNode::ProcessFixedDepthNodeAdjacentNodes(const int& dx,const int& dy,const int& dz, OctNode* node1,const int& radius1, OctNode* node2,const int& radius2,const int& width2, const int& depth,NodeAdjacencyFunction* F,const int& processCurrent) { int d=node2->depth(); if(d>depth){return;} if(!Overlap(dx,dy,dz,radius1+radius2)){return;} if(d==depth){if(processCurrent){F->Function(node2,node1);}} else{ if(!node2->children){return;} __ProcessFixedDepthNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,depth-1,F); } } template template void OctNode::ProcessMaxDepthNodeAdjacentNodes(const int& maxDepth, OctNode* node1,const int& width1, OctNode* node2,const int& width2, const int& depth,NodeAdjacencyFunction* F,const int& processCurrent) { int c1[3],c2[3],w1,w2; node1->centerIndex(maxDepth+1,c1); node2->centerIndex(maxDepth+1,c2); w1=node1->width(maxDepth+1); w2=node2->width(maxDepth+1); ProcessMaxDepthNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,depth,F,processCurrent); } template template void OctNode::ProcessMaxDepthNodeAdjacentNodes(const int& dx,const int& dy,const int& dz, OctNode* node1,const int& radius1, OctNode* node2,const int& radius2,const int& width2, const int& depth,NodeAdjacencyFunction* F,const int& processCurrent) { int d=node2->depth(); if(d>depth){return;} if(!Overlap(dx,dy,dz,radius1+radius2)){return;} if(processCurrent){F->Function(node2,node1);} if(dchildren){__ProcessMaxDepthNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2>>1,depth-1,F);} } template template void OctNode::__ProcessNodeAdjacentNodes(const int& dx,const int& dy,const int& dz, OctNode* node1,const int& radius1, OctNode* node2,const int& radius2,const int& cWidth2, NodeAdjacencyFunction* F) { int cWidth=cWidth2>>1; int radius=radius2>>1; int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth); if(o){ int dx1=dx-cWidth; int dx2=dx+cWidth; int dy1=dy-cWidth; int dy2=dy+cWidth; int dz1=dz-cWidth; int dz2=dz+cWidth; if(o& 1){F->Function(&node2->children[0],node1);if(node2->children[0].children){__ProcessNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,F);}} if(o& 2){F->Function(&node2->children[1],node1);if(node2->children[1].children){__ProcessNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,F);}} if(o& 4){F->Function(&node2->children[2],node1);if(node2->children[2].children){__ProcessNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,F);}} if(o& 8){F->Function(&node2->children[3],node1);if(node2->children[3].children){__ProcessNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,F);}} if(o& 16){F->Function(&node2->children[4],node1);if(node2->children[4].children){__ProcessNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,F);}} if(o& 32){F->Function(&node2->children[5],node1);if(node2->children[5].children){__ProcessNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,F);}} if(o& 64){F->Function(&node2->children[6],node1);if(node2->children[6].children){__ProcessNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,F);}} if(o&128){F->Function(&node2->children[7],node1);if(node2->children[7].children){__ProcessNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,F);}} } } template template void OctNode::__ProcessTerminatingNodeAdjacentNodes(const int& dx,const int& dy,const int& dz, OctNode* node1,const int& radius1, OctNode* node2,const int& radius2,const int& cWidth2, TerminatingNodeAdjacencyFunction* F) { int cWidth=cWidth2>>1; int radius=radius2>>1; int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth); if(o){ int dx1=dx-cWidth; int dx2=dx+cWidth; int dy1=dy-cWidth; int dy2=dy+cWidth; int dz1=dz-cWidth; int dz2=dz+cWidth; if(o& 1){if(F->Function(&node2->children[0],node1) && node2->children[0].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,F);}} if(o& 2){if(F->Function(&node2->children[1],node1) && node2->children[1].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,F);}} if(o& 4){if(F->Function(&node2->children[2],node1) && node2->children[2].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,F);}} if(o& 8){if(F->Function(&node2->children[3],node1) && node2->children[3].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,F);}} if(o& 16){if(F->Function(&node2->children[4],node1) && node2->children[4].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,F);}} if(o& 32){if(F->Function(&node2->children[5],node1) && node2->children[5].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,F);}} if(o& 64){if(F->Function(&node2->children[6],node1) && node2->children[6].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,F);}} if(o&128){if(F->Function(&node2->children[7],node1) && node2->children[7].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,F);}} } } template template void OctNode::__ProcessPointAdjacentNodes(const int& dx,const int& dy,const int& dz, OctNode* node2,const int& radius2,const int& cWidth2, PointAdjacencyFunction* F) { int cWidth=cWidth2>>1; int radius=radius2>>1; int o=ChildOverlap(dx,dy,dz,radius,cWidth); if(o){ int dx1=dx-cWidth; int dx2=dx+cWidth; int dy1=dy-cWidth; int dy2=dy+cWidth; int dz1=dz-cWidth; int dz2=dz+cWidth; if(o& 1){F->Function(&node2->children[0]);if(node2->children[0].children){__ProcessPointAdjacentNodes(dx1,dy1,dz1,&node2->children[0],radius,cWidth,F);}} if(o& 2){F->Function(&node2->children[1]);if(node2->children[1].children){__ProcessPointAdjacentNodes(dx2,dy1,dz1,&node2->children[1],radius,cWidth,F);}} if(o& 4){F->Function(&node2->children[2]);if(node2->children[2].children){__ProcessPointAdjacentNodes(dx1,dy2,dz1,&node2->children[2],radius,cWidth,F);}} if(o& 8){F->Function(&node2->children[3]);if(node2->children[3].children){__ProcessPointAdjacentNodes(dx2,dy2,dz1,&node2->children[3],radius,cWidth,F);}} if(o& 16){F->Function(&node2->children[4]);if(node2->children[4].children){__ProcessPointAdjacentNodes(dx1,dy1,dz2,&node2->children[4],radius,cWidth,F);}} if(o& 32){F->Function(&node2->children[5]);if(node2->children[5].children){__ProcessPointAdjacentNodes(dx2,dy1,dz2,&node2->children[5],radius,cWidth,F);}} if(o& 64){F->Function(&node2->children[6]);if(node2->children[6].children){__ProcessPointAdjacentNodes(dx1,dy2,dz2,&node2->children[6],radius,cWidth,F);}} if(o&128){F->Function(&node2->children[7]);if(node2->children[7].children){__ProcessPointAdjacentNodes(dx2,dy2,dz2,&node2->children[7],radius,cWidth,F);}} } } template template void OctNode::__ProcessFixedDepthNodeAdjacentNodes(const int& dx,const int& dy,const int& dz, OctNode* node1,const int& radius1, OctNode* node2,const int& radius2,const int& cWidth2, const int& depth,NodeAdjacencyFunction* F) { int cWidth=cWidth2>>1; int radius=radius2>>1; int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth); if(o){ int dx1=dx-cWidth; int dx2=dx+cWidth; int dy1=dy-cWidth; int dy2=dy+cWidth; int dz1=dz-cWidth; int dz2=dz+cWidth; if(node2->depth()==depth){ if(o& 1){F->Function(&node2->children[0],node1);} if(o& 2){F->Function(&node2->children[1],node1);} if(o& 4){F->Function(&node2->children[2],node1);} if(o& 8){F->Function(&node2->children[3],node1);} if(o& 16){F->Function(&node2->children[4],node1);} if(o& 32){F->Function(&node2->children[5],node1);} if(o& 64){F->Function(&node2->children[6],node1);} if(o&128){F->Function(&node2->children[7],node1);} } else{ if(o& 1){if(node2->children[0].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,depth,F);}} if(o& 2){if(node2->children[1].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,depth,F);}} if(o& 4){if(node2->children[2].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,depth,F);}} if(o& 8){if(node2->children[3].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,depth,F);}} if(o& 16){if(node2->children[4].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,depth,F);}} if(o& 32){if(node2->children[5].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,depth,F);}} if(o& 64){if(node2->children[6].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,depth,F);}} if(o&128){if(node2->children[7].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,depth,F);}} } } } template template void OctNode::__ProcessMaxDepthNodeAdjacentNodes(const int& dx,const int& dy,const int& dz, OctNode* node1,const int& radius1, OctNode* node2,const int& radius2,const int& cWidth2, const int& depth,NodeAdjacencyFunction* F) { int cWidth=cWidth2>>1; int radius=radius2>>1; int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth); if(o){ int dx1=dx-cWidth; int dx2=dx+cWidth; int dy1=dy-cWidth; int dy2=dy+cWidth; int dz1=dz-cWidth; int dz2=dz+cWidth; if(node2->depth()<=depth){ if(o& 1){F->Function(&node2->children[0],node1);} if(o& 2){F->Function(&node2->children[1],node1);} if(o& 4){F->Function(&node2->children[2],node1);} if(o& 8){F->Function(&node2->children[3],node1);} if(o& 16){F->Function(&node2->children[4],node1);} if(o& 32){F->Function(&node2->children[5],node1);} if(o& 64){F->Function(&node2->children[6],node1);} if(o&128){F->Function(&node2->children[7],node1);} } if(node2->depth()children[0].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,depth,F);}} if(o& 2){if(node2->children[1].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,depth,F);}} if(o& 4){if(node2->children[2].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,depth,F);}} if(o& 8){if(node2->children[3].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,depth,F);}} if(o& 16){if(node2->children[4].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,depth,F);}} if(o& 32){if(node2->children[5].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,depth,F);}} if(o& 64){if(node2->children[6].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,depth,F);}} if(o&128){if(node2->children[7].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,depth,F);}} } } } template inline int OctNode::ChildOverlap(const int& dx,const int& dy,const int& dz,const int& d,const int& cRadius2) { int w1=d-cRadius2; int w2=d+cRadius2; int overlap=0; int test=0,test1=0; if(dx-w1){test =1;} if(dx-w2){test|=2;} if(!test){return 0;} if(dz-w1){test1 =test;} if(dz-w2){test1|=test<<4;} if(!test1){return 0;} if(dy-w1){overlap =test1;} if(dy-w2){overlap|=test1<<2;} return overlap; } template OctNode* OctNode::getNearestLeaf(const Point3D& p){ Point3D center; Real twidth; OctNode* temp; int cIndex; if(!children){return this;} centerAndWidth(center,width); temp=this; while(temp->children){ cIndex=CornerIndex(center,p); temp=&temp->children[cIndex]; width/=2; if(cIndex&1){center.coords[0]+=twidth/2;} else {center.coords[0]-=twidth/2;} if(cIndex&2){center.coords[1]+=twidth/2;} else {center.coords[1]-=twidth/2;} if(cIndex&4){center.coords[2]+=twidth/2;} else {center.coords[2]-=twidth/2;} } return temp; } template const OctNode* OctNode::getNearestLeaf(const Point3D& p) const{ int nearest; Real temp,dist2; if(!children){return this;} for(int i=0;i int OctNode::CommonEdge(const OctNode* node1,const int& eIndex1,const OctNode* node2,const int& eIndex2){ int o1,o2,i1,i2,j1,j2; Cube::FactorEdgeIndex(eIndex1,o1,i1,j1); Cube::FactorEdgeIndex(eIndex2,o2,i2,j2); if(o1!=o2){return 0;} int dir[2]; int idx1[2]; int idx2[2]; switch(o1){ case 0: dir[0]=1; dir[1]=2; break; case 1: dir[0]=0; dir[1]=2; break; case 2: dir[0]=0; dir[1]=1; break; }; int d1,d2,off1[3],off2[3]; node1->depthAndOffset(d1,off1); node2->depthAndOffset(d2,off2); idx1[0]=off1[dir[0]]+(1<d2){ idx2[0]<<=(d1-d2); idx2[1]<<=(d1-d2); } else{ idx1[0]<<=(d2-d1); idx1[1]<<=(d2-d1); } if(idx1[0]==idx2[0] && idx1[1]==idx2[1]){return 1;} else {return 0;} } template int OctNode::CornerIndex(const Point3D& center,const Point3D& p){ int cIndex=0; if(p.coords[0]>center.coords[0]){cIndex|=1;} if(p.coords[1]>center.coords[1]){cIndex|=2;} if(p.coords[2]>center.coords[2]){cIndex|=4;} return cIndex; } template template OctNode& OctNode::operator = (const OctNode& node){ int i; if(children){delete[] children;} children=NULL; depth=node.depth; for(i=0;ioffset[i] = node.offset[i];} if(node.children){ initChildren(); for(i=0;i int OctNode::CompareForwardDepths(const void* v1,const void* v2){ return ((const OctNode*)v1)->depth-((const OctNode*)v2)->depth; } template int OctNode::CompareForwardPointerDepths(const void* v1,const void* v2){ const OctNode *n1,*n2; n1=(*(const OctNode**)v1); n2=(*(const OctNode**)v2); if(n1->d!=n2->d){return int(n1->d)-int(n2->d);} while(n1->parent != n2->parent){ n1=n1->parent; n2=n2->parent; } if(n1->off[0]!=n2->off[0]){return int(n1->off[0])-int(n2->off[0]);} if(n1->off[1]!=n2->off[1]){return int(n1->off[1])-int(n2->off[1]);} return int(n1->off[2])-int(n2->off[2]); return 0; } template int OctNode::CompareBackwardDepths(const void* v1,const void* v2){ return ((const OctNode*)v2)->depth-((const OctNode*)v1)->depth; } template int OctNode::CompareBackwardPointerDepths(const void* v1,const void* v2){ return (*(const OctNode**)v2)->depth()-(*(const OctNode**)v1)->depth(); } template inline int OctNode::Overlap2(const int &depth1,const int offSet1[DIMENSION],const Real& multiplier1,const int &depth2,const int offSet2[DIMENSION],const Real& multiplier2){ int d=depth2-depth1; Real w=multiplier2+multiplier1*(1<=w || fabs(Real(offSet2[1]-(offSet1[1]<=w || fabs(Real(offSet2[2]-(offSet1[2]<=w ){return 0;} return 1; } template inline int OctNode::Overlap(const int& c1,const int& c2,const int& c3,const int& dWidth){ if(c1>=dWidth || c1<=-dWidth || c2>=dWidth || c2<=-dWidth || c3>=dWidth || c3<=-dWidth){return 0;} else{return 1;} } template OctNode* OctNode::faceNeighbor(const int& faceIndex,const int& forceChildren){return __faceNeighbor(faceIndex>>1,faceIndex&1,forceChildren);} template const OctNode* OctNode::faceNeighbor(const int& faceIndex) const {return __faceNeighbor(faceIndex>>1,faceIndex&1);} template OctNode* OctNode::__faceNeighbor(const int& dir,const int& iOff,const int& forceChildren){ if(!parent){return NULL;} int pIndex=int(this-parent->children); pIndex^=(1<children[pIndex];} // if(!(((pIndex>>dir)^iOff)&1)){return &parent->children[pIndex];} else{ OctNode* temp=parent->__faceNeighbor(dir,iOff,forceChildren); if(!temp){return NULL;} if(!temp->children){ if(forceChildren){temp->initChildren();} else{return temp;} } return &temp->children[pIndex]; } } template const OctNode* OctNode::__faceNeighbor(const int& dir,const int& iOff) const { if(!parent){return NULL;} int pIndex=int(this-parent->children); pIndex^=(1<children[pIndex];} // if(!(((pIndex>>dir)^iOff)&1)){return &parent->children[pIndex];} else{ const OctNode* temp=parent->__faceNeighbor(dir,iOff); if(!temp || !temp->children){return temp;} else{return &temp->children[pIndex];} } } template OctNode* OctNode::edgeNeighbor(const int& edgeIndex,const int& forceChildren){ int idx[2],o,i[2]; Cube::FactorEdgeIndex(edgeIndex,o,i[0],i[1]); switch(o){ case 0: idx[0]=1; idx[1]=2; break; case 1: idx[0]=0; idx[1]=2; break; case 2: idx[0]=0; idx[1]=1; break; }; return __edgeNeighbor(o,i,idx,forceChildren); } template const OctNode* OctNode::edgeNeighbor(const int& edgeIndex) const { int idx[2],o,i[2]; Cube::FactorEdgeIndex(edgeIndex,o,i[0],i[1]); switch(o){ case 0: idx[0]=1; idx[1]=2; break; case 1: idx[0]=0; idx[1]=2; break; case 2: idx[0]=0; idx[1]=1; break; }; return __edgeNeighbor(o,i,idx); } template const OctNode* OctNode::__edgeNeighbor(const int& o,const int i[2],const int idx[2]) const{ if(!parent){return NULL;} int pIndex=int(this-parent->children); int aIndex,x[DIMENSION]; Cube::FactorCornerIndex(pIndex,x[0],x[1],x[2]); aIndex=(~((i[0] ^ x[idx[0]]) | ((i[1] ^ x[idx[1]])<<1))) & 3; pIndex^=(7 ^ (1<__faceNeighbor(idx[0],i[0]); if(!temp || !temp->children){return NULL;} else{return &temp->children[pIndex];} } else if(aIndex==2) { // I can get the neighbor from the parent's face adjacent neighbor const OctNode* temp=parent->__faceNeighbor(idx[1],i[1]); if(!temp || !temp->children){return NULL;} else{return &temp->children[pIndex];} } else if(aIndex==0) { // I can get the neighbor from the parent return &parent->children[pIndex]; } else if(aIndex==3) { // I can get the neighbor from the parent's edge adjacent neighbor const OctNode* temp=parent->__edgeNeighbor(o,i,idx); if(!temp || !temp->children){return temp;} else{return &temp->children[pIndex];} } else{return NULL;} } template OctNode* OctNode::__edgeNeighbor(const int& o,const int i[2],const int idx[2],const int& forceChildren){ if(!parent){return NULL;} int pIndex=int(this-parent->children); int aIndex,x[DIMENSION]; Cube::FactorCornerIndex(pIndex,x[0],x[1],x[2]); aIndex=(~((i[0] ^ x[idx[0]]) | ((i[1] ^ x[idx[1]])<<1))) & 3; pIndex^=(7 ^ (1<__faceNeighbor(idx[0],i[0],0); if(!temp || !temp->children){return NULL;} else{return &temp->children[pIndex];} } else if(aIndex==2) { // I can get the neighbor from the parent's face adjacent neighbor OctNode* temp=parent->__faceNeighbor(idx[1],i[1],0); if(!temp || !temp->children){return NULL;} else{return &temp->children[pIndex];} } else if(aIndex==0) { // I can get the neighbor from the parent return &parent->children[pIndex]; } else if(aIndex==3) { // I can get the neighbor from the parent's edge adjacent neighbor OctNode* temp=parent->__edgeNeighbor(o,i,idx,forceChildren); if(!temp){return NULL;} if(!temp->children){ if(forceChildren){temp->initChildren();} else{return temp;} } return &temp->children[pIndex]; } else{return NULL;} } template const OctNode* OctNode::cornerNeighbor(const int& cornerIndex) const { int pIndex,aIndex=0; if(!parent){return NULL;} pIndex=int(this-parent->children); aIndex=(cornerIndex ^ pIndex); // The disagreement bits pIndex=(~pIndex)&7; // The antipodal point if(aIndex==7){ // Agree on no bits return &parent->children[pIndex]; } else if(aIndex==0){ // Agree on all bits const OctNode* temp=((const OctNode*)parent)->cornerNeighbor(cornerIndex); if(!temp || !temp->children){return temp;} else{return &temp->children[pIndex];} } else if(aIndex==6){ // Agree on face 0 const OctNode* temp=((const OctNode*)parent)->__faceNeighbor(0,cornerIndex & 1); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else if(aIndex==5){ // Agree on face 1 const OctNode* temp=((const OctNode*)parent)->__faceNeighbor(1,(cornerIndex & 2)>>1); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else if(aIndex==3){ // Agree on face 2 const OctNode* temp=((const OctNode*)parent)->__faceNeighbor(2,(cornerIndex & 4)>>2); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else if(aIndex==4){ // Agree on edge 2 const OctNode* temp=((const OctNode*)parent)->edgeNeighbor(8 | (cornerIndex & 1) | (cornerIndex & 2) ); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else if(aIndex==2){ // Agree on edge 1 const OctNode* temp=((const OctNode*)parent)->edgeNeighbor(4 | (cornerIndex & 1) | ((cornerIndex & 4)>>1) ); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else if(aIndex==1){ // Agree on edge 0 const OctNode* temp=((const OctNode*)parent)->edgeNeighbor(((cornerIndex & 2) | (cornerIndex & 4))>>1 ); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else{return NULL;} } template OctNode* OctNode::cornerNeighbor(const int& cornerIndex,const int& forceChildren){ int pIndex,aIndex=0; if(!parent){return NULL;} pIndex=int(this-parent->children); aIndex=(cornerIndex ^ pIndex); // The disagreement bits pIndex=(~pIndex)&7; // The antipodal point if(aIndex==7){ // Agree on no bits return &parent->children[pIndex]; } else if(aIndex==0){ // Agree on all bits OctNode* temp=((OctNode*)parent)->cornerNeighbor(cornerIndex,forceChildren); if(!temp){return NULL;} if(!temp->children){ if(forceChildren){temp->initChildren();} else{return temp;} } return &temp->children[pIndex]; } else if(aIndex==6){ // Agree on face 0 OctNode* temp=((OctNode*)parent)->__faceNeighbor(0,cornerIndex & 1,0); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else if(aIndex==5){ // Agree on face 1 OctNode* temp=((OctNode*)parent)->__faceNeighbor(1,(cornerIndex & 2)>>1,0); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else if(aIndex==3){ // Agree on face 2 OctNode* temp=((OctNode*)parent)->__faceNeighbor(2,(cornerIndex & 4)>>2,0); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else if(aIndex==4){ // Agree on edge 2 OctNode* temp=((OctNode*)parent)->edgeNeighbor(8 | (cornerIndex & 1) | (cornerIndex & 2) ); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else if(aIndex==2){ // Agree on edge 1 OctNode* temp=((OctNode*)parent)->edgeNeighbor(4 | (cornerIndex & 1) | ((cornerIndex & 4)>>1) ); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else if(aIndex==1){ // Agree on edge 0 OctNode* temp=((OctNode*)parent)->edgeNeighbor(((cornerIndex & 2) | (cornerIndex & 4))>>1 ); if(!temp || !temp->children){return NULL;} else{return & temp->children[pIndex];} } else{return NULL;} } //////////////////////// // OctNodeNeighborKey // //////////////////////// template OctNode::Neighbors::Neighbors(void){clear();} template void OctNode::Neighbors::clear(void){ for(int i=0;i<3;i++){for(int j=0;j<3;j++){for(int k=0;k<3;k++){neighbors[i][j][k]=NULL;}}} } template OctNode::NeighborKey::NeighborKey(void){neighbors=NULL;} template OctNode::NeighborKey::~NeighborKey(void){ if(neighbors){delete[] neighbors;} neighbors=NULL; } template void OctNode::NeighborKey::set(const int& d){ if(neighbors){delete[] neighbors;} neighbors=NULL; if(d<0){return;} neighbors=new Neighbors[d+1]; } template typename OctNode::Neighbors& OctNode::NeighborKey::setNeighbors(OctNode* node){ int d=node->depth(); if(node!=neighbors[d].neighbors[1][1][1]){ neighbors[d].clear(); if(!node->parent){neighbors[d].neighbors[1][1][1]=node;} else{ int i,j,k,x1,y1,z1,x2,y2,z2; int idx=int(node-node->parent->children); Cube::FactorCornerIndex( idx ,x1,y1,z1); Cube::FactorCornerIndex((~idx)&7,x2,y2,z2); for(i=0;i<2;i++){ for(j=0;j<2;j++){ for(k=0;k<2;k++){ neighbors[d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[Cube::CornerIndex(i,j,k)]; } } } Neighbors& temp=setNeighbors(node->parent); // Set the neighbors from across the faces i=x1<<1; if(temp.neighbors[i][1][1]){ if(!temp.neighbors[i][1][1]->children){temp.neighbors[i][1][1]->initChildren();} for(j=0;j<2;j++){for(k=0;k<2;k++){neighbors[d].neighbors[i][y2+j][z2+k]=&temp.neighbors[i][1][1]->children[Cube::CornerIndex(x2,j,k)];}} } j=y1<<1; if(temp.neighbors[1][j][1]){ if(!temp.neighbors[1][j][1]->children){temp.neighbors[1][j][1]->initChildren();} for(i=0;i<2;i++){for(k=0;k<2;k++){neighbors[d].neighbors[x2+i][j][z2+k]=&temp.neighbors[1][j][1]->children[Cube::CornerIndex(i,y2,k)];}} } k=z1<<1; if(temp.neighbors[1][1][k]){ if(!temp.neighbors[1][1][k]->children){temp.neighbors[1][1][k]->initChildren();} for(i=0;i<2;i++){for(j=0;j<2;j++){neighbors[d].neighbors[x2+i][y2+j][k]=&temp.neighbors[1][1][k]->children[Cube::CornerIndex(i,j,z2)];}} } // Set the neighbors from across the edges i=x1<<1; j=y1<<1; if(temp.neighbors[i][j][1]){ if(!temp.neighbors[i][j][1]->children){temp.neighbors[i][j][1]->initChildren();} for(k=0;k<2;k++){neighbors[d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];} } i=x1<<1; k=z1<<1; if(temp.neighbors[i][1][k]){ if(!temp.neighbors[i][1][k]->children){temp.neighbors[i][1][k]->initChildren();} for(j=0;j<2;j++){neighbors[d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];} } j=y1<<1; k=z1<<1; if(temp.neighbors[1][j][k]){ if(!temp.neighbors[1][j][k]->children){temp.neighbors[1][j][k]->initChildren();} for(i=0;i<2;i++){neighbors[d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];} } // Set the neighbor from across the corner i=x1<<1; j=y1<<1; k=z1<<1; if(temp.neighbors[i][j][k]){ if(!temp.neighbors[i][j][k]->children){temp.neighbors[i][j][k]->initChildren();} neighbors[d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)]; } } } return neighbors[d]; } template typename OctNode::Neighbors& OctNode::NeighborKey::getNeighbors(OctNode* node){ int d=node->depth(); if(node!=neighbors[d].neighbors[1][1][1]){ neighbors[d].clear(); if(!node->parent){neighbors[d].neighbors[1][1][1]=node;} else{ int i,j,k,x1,y1,z1,x2,y2,z2; int idx=int(node-node->parent->children); Cube::FactorCornerIndex( idx ,x1,y1,z1); Cube::FactorCornerIndex((~idx)&7,x2,y2,z2); for(i=0;i<2;i++){ for(j=0;j<2;j++){ for(k=0;k<2;k++){ neighbors[d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[Cube::CornerIndex(i,j,k)]; } } } Neighbors& temp=getNeighbors(node->parent); // Set the neighbors from across the faces i=x1<<1; if(temp.neighbors[i][1][1] && temp.neighbors[i][1][1]->children){ for(j=0;j<2;j++){for(k=0;k<2;k++){neighbors[d].neighbors[i][y2+j][z2+k]=&temp.neighbors[i][1][1]->children[Cube::CornerIndex(x2,j,k)];}} } j=y1<<1; if(temp.neighbors[1][j][1] && temp.neighbors[1][j][1]->children){ for(i=0;i<2;i++){for(k=0;k<2;k++){neighbors[d].neighbors[x2+i][j][z2+k]=&temp.neighbors[1][j][1]->children[Cube::CornerIndex(i,y2,k)];}} } k=z1<<1; if(temp.neighbors[1][1][k] && temp.neighbors[1][1][k]->children){ for(i=0;i<2;i++){for(j=0;j<2;j++){neighbors[d].neighbors[x2+i][y2+j][k]=&temp.neighbors[1][1][k]->children[Cube::CornerIndex(i,j,z2)];}} } // Set the neighbors from across the edges i=x1<<1; j=y1<<1; if(temp.neighbors[i][j][1] && temp.neighbors[i][j][1]->children){ for(k=0;k<2;k++){neighbors[d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];} } i=x1<<1; k=z1<<1; if(temp.neighbors[i][1][k] && temp.neighbors[i][1][k]->children){ for(j=0;j<2;j++){neighbors[d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];} } j=y1<<1; k=z1<<1; if(temp.neighbors[1][j][k] && temp.neighbors[1][j][k]->children){ for(i=0;i<2;i++){neighbors[d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];} } // Set the neighbor from across the corner i=x1<<1; j=y1<<1; k=z1<<1; if(temp.neighbors[i][j][k] && temp.neighbors[i][j][k]->children){ neighbors[d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)]; } } } return neighbors[node->depth()]; } ///////////////////////// // OctNodeNeighborKey2 // ///////////////////////// template OctNode::Neighbors2::Neighbors2(void){clear();} template void OctNode::Neighbors2::clear(void){ for(int i=0;i<3;i++){for(int j=0;j<3;j++){for(int k=0;k<3;k++){neighbors[i][j][k]=NULL;}}} } template OctNode::NeighborKey2::NeighborKey2(void){neighbors=NULL;} template OctNode::NeighborKey2::~NeighborKey2(void){ if(neighbors){delete[] neighbors;} neighbors=NULL; } template void OctNode::NeighborKey2::set(const int& d){ if(neighbors){delete[] neighbors;} neighbors=NULL; if(d<0){return;} neighbors=new Neighbors2[d+1]; } template typename OctNode::Neighbors2& OctNode::NeighborKey2::getNeighbors(const OctNode* node){ int d=node->depth(); if(node!=neighbors[d].neighbors[1][1][1]){ neighbors[d].clear(); if(!node->parent){neighbors[d].neighbors[1][1][1]=node;} else{ int i,j,k,x1,y1,z1,x2,y2,z2; int idx=int(node-node->parent->children); Cube::FactorCornerIndex( idx ,x1,y1,z1); Cube::FactorCornerIndex((~idx)&7,x2,y2,z2); for(i=0;i<2;i++){ for(j=0;j<2;j++){ for(k=0;k<2;k++){ neighbors[d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[Cube::CornerIndex(i,j,k)]; } } } Neighbors2& temp=getNeighbors(node->parent); // Set the neighbors from across the faces i=x1<<1; if(temp.neighbors[i][1][1] && temp.neighbors[i][1][1]->children){ for(j=0;j<2;j++){for(k=0;k<2;k++){neighbors[d].neighbors[i][y2+j][z2+k]=&temp.neighbors[i][1][1]->children[Cube::CornerIndex(x2,j,k)];}} } j=y1<<1; if(temp.neighbors[1][j][1] && temp.neighbors[1][j][1]->children){ for(i=0;i<2;i++){for(k=0;k<2;k++){neighbors[d].neighbors[x2+i][j][z2+k]=&temp.neighbors[1][j][1]->children[Cube::CornerIndex(i,y2,k)];}} } k=z1<<1; if(temp.neighbors[1][1][k] && temp.neighbors[1][1][k]->children){ for(i=0;i<2;i++){for(j=0;j<2;j++){neighbors[d].neighbors[x2+i][y2+j][k]=&temp.neighbors[1][1][k]->children[Cube::CornerIndex(i,j,z2)];}} } // Set the neighbors from across the edges i=x1<<1; j=y1<<1; if(temp.neighbors[i][j][1] && temp.neighbors[i][j][1]->children){ for(k=0;k<2;k++){neighbors[d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];} } i=x1<<1; k=z1<<1; if(temp.neighbors[i][1][k] && temp.neighbors[i][1][k]->children){ for(j=0;j<2;j++){neighbors[d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];} } j=y1<<1; k=z1<<1; if(temp.neighbors[1][j][k] && temp.neighbors[1][j][k]->children){ for(i=0;i<2;i++){neighbors[d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];} } // Set the neighbor from across the corner i=x1<<1; j=y1<<1; k=z1<<1; if(temp.neighbors[i][j][k] && temp.neighbors[i][j][k]->children){ neighbors[d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)]; } } } return neighbors[node->depth()]; } template int OctNode::write(const char* fileName) const{ FILE* fp=fopen(fileName,"wb"); if(!fp){return 0;} int ret=write(fp); fclose(fp); return ret; } template int OctNode::write(FILE* fp) const{ fwrite(this,sizeof(OctNode),1,fp); if(children){for(int i=0;i int OctNode::read(const char* fileName){ FILE* fp=fopen(fileName,"rb"); if(!fp){return 0;} int ret=read(fp); fclose(fp); return ret; } template int OctNode::read(FILE* fp){ fread(this,sizeof(OctNode),1,fp); parent=NULL; if(children){ children=NULL; initChildren(); for(int i=0;i int OctNode::width(const int& iMaxDepth) const { int td=depth(); return 1<<(iMaxDepth-td); } template void OctNode::centerIndex(const int& iMaxDepth,int index[DIMENSION]) const { int td,o[3]; depthAndOffset(td,o); for(int i=0;i::CornerIndex(iMaxDepth,td+1,o[i]<<1,1);} } GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/SparseMatrix.inl0000644000175000017500000003272111667757442026352 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include /////////////////// // SparseMatrix // /////////////////// /////////////////////////////////////////// // Static Allocator Methods and Memebers // /////////////////////////////////////////// template int SparseMatrix::UseAlloc=0; template Allocator > SparseMatrix::MatrixAllocator; template int SparseMatrix::UseAllocator(void){return UseAlloc;} template void SparseMatrix::SetAllocator(const int& blockSize){ if(blockSize>0){ UseAlloc=1; MatrixAllocator.set(blockSize); } else{UseAlloc=0;} } /////////////////////////////////////// // SparseMatrix Methods and Memebers // /////////////////////////////////////// template SparseMatrix::SparseMatrix() { rows=0; rowSizes=NULL; m_ppElements=NULL; } template SparseMatrix::SparseMatrix( int iRows ){Resize(iRows);} template SparseMatrix::SparseMatrix( const SparseMatrix& M ) { Resize(M.rows); for (int i=0; i int SparseMatrix::Entries(void){ int e=0; for(int i=0;i SparseMatrix& SparseMatrix::operator = (const SparseMatrix& M) { Resize(M.rows); for (int i=0; i SparseMatrix::~SparseMatrix(){Resize(0);} template void SparseMatrix::Resize( int r ) { int i; if(rows>0){ if(!UseAlloc){for(i=0;i**)malloc(sizeof(MatrixEntry*)*r); } } template void SparseMatrix::SetRowSize(int row,int count){ if(row>=0 && rowMatrixAllocator.newElements(count);} else{ if(rowSizes[row]){free(m_ppElements[row]);} if(count>0){m_ppElements[row]=(MatrixEntry*)malloc(sizeof(MatrixEntry)*count);} } rowSizes[row]=count; } } template void SparseMatrix::SetZero() { Resize(this->m_N, this->m_M); } template void SparseMatrix::SetIdentity() { SetZero(); for(int ij=0; ij < Min( this->Rows(), this->Columns() ); ij++) (*this)(ij,ij) = T(1); } template SparseMatrix SparseMatrix::operator * (const T& V) const { SparseMatrix M(*this); M *= V; return M; } template SparseMatrix& SparseMatrix::operator *= (const T& V) { for (int i=0; iRows(); i++) { for(int ii=0;ii SparseMatrix SparseMatrix::Multiply( const SparseMatrix& M ) const { SparseMatrix R( this->Rows(), M.Columns() ); for(int i=0; i template Vector SparseMatrix::Multiply( const Vector& V ) const { Vector R( rows ); for (int i=0; i template void SparseMatrix::Multiply( const Vector& In,Vector& Out) const { for (int i=0; i SparseMatrix SparseMatrix::operator * (const SparseMatrix& M) const { return Multiply(M); } template template Vector SparseMatrix::operator * (const Vector& V) const { return Multiply(V); } template SparseMatrix SparseMatrix::Transpose() const { SparseMatrix M( this->Columns(), this->Rows() ); for (int i=0; iRows(); i++) { for(int ii=0;ii template int SparseMatrix::SolveSymmetric(const SparseMatrix& M,const Vector& b,const int& iters,Vector& solution,const T2 eps,const int& reset){ Vector d,r,Md; T2 alpha,beta,rDotR; Md.Resize(b.Dimensions()); if(reset){ solution.Resize(b.Dimensions()); solution.SetZero(); } d=r=b-M.Multiply(solution); rDotR=r.Dot(r); if(b.Dot(b)<=eps){ solution.SetZero(); return 0; } int i; for(i=0;i::Add(d,beta,r,d); } return i; } // Solve for x s.t. M(x)=b by solving for x s.t. M^tM(x)=M^t(b) template int SparseMatrix::Solve(const SparseMatrix& M,const Vector& b,const int& iters,Vector& solution,const T eps){ SparseMatrix mTranspose=M.Transpose(); Vector bb=mTranspose*b; Vector d,r,Md; T alpha,beta,rDotR; int i; solution.Resize(M.Columns()); solution.SetZero(); d=r=bb; rDotR=r.Dot(r); for(i=0;ieps;i++){ T temp; Md=mTranspose*(M*d); alpha=rDotR/d.Dot(Md); solution+=d*alpha; r-=Md*alpha; temp=r.Dot(r); beta=temp/rDotR; rDotR=temp; d=r+d*beta; } return i; } //////////////////// // SparseNMatrix // //////////////////// /////////////////////////////////////////// // Static Allocator Methods and Memebers // /////////////////////////////////////////// template int SparseNMatrix::UseAlloc=0; template Allocator > SparseNMatrix::NMatrixAllocator; template int SparseNMatrix::UseAllocator(void){return UseAlloc;} template void SparseNMatrix::SetAllocator(const int& blockSize){ if(blockSize>0){ UseAlloc=1; NMatrixAllocator.set(blockSize); } else{UseAlloc=0;} } //////////////////////////////////////// // SparseNMatrix Methods and Memebers // //////////////////////////////////////// template SparseNMatrix::SparseNMatrix() { rows=0; rowSizes=NULL; m_ppElements=NULL; } template SparseNMatrix::SparseNMatrix( int iRows ){Resize(iRows);} template SparseNMatrix::SparseNMatrix( const SparseNMatrix& M ) { Resize(M.rows); for (int i=0; i int SparseNMatrix::Entries(void){ int e=0; for(int i=0;i SparseNMatrix& SparseNMatrix::operator = (const SparseNMatrix& M) { Resize(M.rows); for (int i=0; i SparseNMatrix::~SparseNMatrix(){Resize(0);} template void SparseNMatrix::Resize( int r ) { int i; if(rows>0){ if(!UseAlloc){for(i=0;i**)malloc(sizeof(NMatrixEntry*)*r); } } template void SparseNMatrix::SetRowSize(int row,int count){ if(row>=0 && rowNMatrixAllocator.newElements(count);} else{ if(rowSizes[row]){free(m_ppElements[row]);} if(count>0){m_ppElements[row]=(NMatrixEntry*)malloc(sizeof(NMatrixEntry)*count);} } rowSizes[row]=count; } } template SparseNMatrix SparseNMatrix::operator * (const T& V) const { SparseNMatrix M(*this); M *= V; return M; } template SparseNMatrix& SparseNMatrix::operator *= (const T& V) { for (int i=0; iRows(); i++) { for(int ii=0;ii template NVector SparseNMatrix::operator * (const Vector& V) const { NVector R( rows ); for (int i=0; i template Vector SparseNMatrix::operator * (const NVector& V) const { Vector R( rows ); for (int i=0; i template Vector SparseSymmetricMatrix::operator * (const Vector& V) const {return Multiply(V);} template template Vector SparseSymmetricMatrix::Multiply( const Vector& V ) const { Vector R( this->rows ); for (int i=0; irows; i++){ for(int ii=0;iirowSizes[i];ii++){ int j=this->m_ppElements[i][ii].N; R(i)+=this->m_ppElements[i][ii].Value * V.m_pV[j]; R(j)+=this->m_ppElements[i][ii].Value * V.m_pV[i]; } } return R; } template template void SparseSymmetricMatrix::Multiply( const Vector& In,Vector& Out) const { Out.SetZero(); for (int i=0; irows; i++){ MatrixEntry* temp=this->m_ppElements[i]; T2& in1=In.m_pV[i]; T2& out1=Out.m_pV[i]; int rs=this->rowSizes[i]; for(int ii=0;ii& temp2=temp[ii]; int j=temp2.N; T2 v=temp2.Value; out1+=v * In.m_pV[j]; Out.m_pV[j]+=v * in1; } } } template template int SparseSymmetricMatrix::Solve(const SparseSymmetricMatrix& M,const Vector& b,const int& iters,Vector& solution,const T2 eps,const int& reset){ Vector d,r,Md; T2 alpha,beta,rDotR,bDotB; Md.Resize(b.Dimensions()); if(reset){ solution.Resize(b.Dimensions()); solution.SetZero(); } d=r=b-M.Multiply(solution); rDotR=r.Dot(r); bDotB=b.Dot(b); if(b.Dot(b)<=eps){ solution.SetZero(); return 0; } int i; for(i=0;i::Add(d,beta,r,d); } return i; } template template int SparseSymmetricMatrix::Solve(const SparseSymmetricMatrix& M,const Vector& diagonal,const Vector& b,const int& iters,Vector& solution,const T2 eps,const int& reset){ Vector d,r,Md; if(reset){ solution.Resize(b.Dimensions()); solution.SetZero(); } Md.Resize(M.rows); for(int i=0;i using stdext::hash_map; #else // !WIN32 #include using namespace __gnu_cxx; namespace __gnu_cxx { template< > struct hash< long long > { size_t operator()(long long __x) const { return __x; } }; template< > struct hash< const long long > { size_t operator()(const long long __x) const { return __x; } }; template< > struct hash< unsigned long long > { size_t operator()(unsigned long long __x) const { return __x; } }; template< > struct hash< const unsigned long long > { size_t operator()(const unsigned long long __x) const { return __x; } }; } #endif // WIN32 #endif // HASH_INCLUDED GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/vtkPoissonReconstruction.cxx0000644000175000017500000002351011667757442031065 0ustar mathieumathieu/*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Authors: David Doria at Rensselaer Polytechnic Institute and Arnaud Gelas at Harvard Medical School Copyright (c) 2010, David Doria at Rensselaer Polytechnic Institute and Arnaud Gelas at Harvard Medical School, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Rensselaer Polytechnic Institute and of Harvard Medical School nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkPoissonReconstruction.h" #include "vtkObjectFactory.h" #include "vtkStreamingDemandDrivenPipeline.h" #include "vtkInformationVector.h" #include "vtkInformation.h" #include "vtkDataObject.h" #include "vtkSmartPointer.h" #include "vtkTriangle.h" #include "vtkCellArray.h" #include "MultiGridOctest.h" #include "MultiGridOctreeData.h" vtkStandardNewMacro(vtkPoissonReconstruction); vtkPoissonReconstruction::vtkPoissonReconstruction() { this->Depth = 8; this->KernelDepth = 6; this->SolverDivide = 8; this->IsoDivide = 8; this->Refine = 3; this->SamplesPerNode = 1.0; this->Scale = 1.25; this->Verbose = 0; this->Confidence = 0; this->NoResetSamples = 0; this->NoClipTree = 0; this->Refine = 0; } int vtkPoissonReconstruction::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector) { // get the info objects vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); vtkInformation *outInfo = outputVector->GetInformationObject(0); // get the input and ouptut vtkPolyData *input = vtkPolyData::SafeDownCast( inInfo->Get( vtkDataObject::DATA_OBJECT() ) ); vtkPolyData *output = vtkPolyData::SafeDownCast( outInfo->Get( vtkDataObject::DATA_OBJECT() ) ); const int Degree = 2; Point3D< float > center; Real scale = 1.0; Real isoValue = 0; Octree< Degree > tree; PPolynomial< Degree > reconstructionFunction = PPolynomial< Degree >::GaussianApproximation(); center.coords[0] = 0; center.coords[1] = 0; center.coords[2] = 0; TreeOctNode::SetAllocator(MEMORY_ALLOCATOR_BLOCK_SIZE); this->KernelDepth = this->Depth - 2; tree.setFunctionData( reconstructionFunction, this->Depth, 0, Real(1.0) / ( 1 << this->Depth ) ); //DumpOutput("Function Data Set In: %lg\n",Time()-t); //size_t memoryusage = MemoryInfo::Usage(); //DumpOutput("Memory Usage: %.3f MB\n",float(memoryusage)/(1<<20)); if ( this->KernelDepth > this->Depth ) { fprintf(stderr, "KernelDepth can't be greater than Depth: %d <= %d\n", this->KernelDepth, this->Depth); return EXIT_FAILURE; } tree.setTree(input, this->Depth, this->KernelDepth, Real(this->SamplesPerNode), this->Scale, center, scale, !this->NoResetSamples, this->Confidence); //DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes()); //DumpOutput(" Tree Size: %.3f // MB\n",float(sizeof(TreeOctNode)*tree.tree.nodes())/(1<<20)); //DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20)); if ( !NoClipTree ) { tree.ClipTree(); //DumpOutput("Tree Clipped In: %lg\n",Time()-t); //DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes()); //DumpOutput(" Tree Size: %.3f // MB\n",float(sizeof(TreeOctNode)*tree.tree.nodes())/(1<<20)); } tree.finalize1(this->Refine); //DumpOutput("Finalized 1 In: %lg\n",Time()-t); //DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes()); //DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20)); // tree.maxMemoryUsage=0; tree.SetLaplacianWeights(); //DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20)); tree.finalize2(this->Refine); //DumpOutput("Finalized 2 In: %lg\n",Time()-t); //DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes()); //DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20)); //tree.maxMemoryUsage=0; tree.LaplacianMatrixIteration(this->SolverDivide); //DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20)); CoredVectorMeshData mesh; //tree.maxMemoryUsage=0; isoValue = tree.GetIsoValue(); //DumpOutput("Got average in: %f\n",Time()-t); //DumpOutput("Iso-Value: %e\n",isoValue); //DumpOutput("Memory Usage: %.3f MB\n",float(tree.MemoryUsage())); if ( this->IsoDivide ) { tree.GetMCIsoTriangles(isoValue, this->IsoDivide, &mesh, 0, 1, true); } else { tree.GetMCIsoTriangles(isoValue, &mesh, 0, 1, true); } //PlyWriteTriangles(Out.value,&mesh,PLY_BINARY_NATIVE,center,scale,comments,commentNum); //create output vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New(); Point3D< float > p; for ( size_t i = 0; i < mesh.inCorePoints.size(); i++ ) { p = mesh.inCorePoints[i]; points->InsertNextPoint(p.coords[0] * scale + center.coords[0], p.coords[1] * scale + center.coords[1], p.coords[2] * scale + center.coords[2]); } for ( unsigned int i = 0; i < static_cast< unsigned int >( mesh.outOfCorePointCount() ); i++ ) { mesh.nextOutOfCorePoint(p); points->InsertNextPoint(p.coords[0] * scale + center.coords[0], p.coords[1] * scale + center.coords[1], p.coords[2] * scale + center.coords[2]); } // write faces vtkSmartPointer< vtkCellArray > triangles = vtkSmartPointer< vtkCellArray >::New(); TriangleIndex tIndex; int inCoreFlag; unsigned int nr_faces = mesh.triangleCount(); for ( unsigned int i = 0; i < nr_faces; i++ ) { vtkSmartPointer< vtkTriangle > triangle = vtkSmartPointer< vtkTriangle >::New(); mesh.nextTriangle(tIndex, inCoreFlag); if ( !( inCoreFlag & CoredMeshData::IN_CORE_FLAG[0] ) ) { tIndex.idx[0] += int( mesh.inCorePoints.size() ); } if ( !( inCoreFlag & CoredMeshData::IN_CORE_FLAG[1] ) ) { tIndex.idx[1] += int( mesh.inCorePoints.size() ); } if ( !( inCoreFlag & CoredMeshData::IN_CORE_FLAG[2] ) ) { tIndex.idx[2] += int( mesh.inCorePoints.size() ); } for ( unsigned int j = 0; j < 3; j++ ) { triangle->GetPointIds()->SetId(j, tIndex.idx[j]); } triangles->InsertNextCell(triangle); } output->SetPoints(points); output->SetPolys(triangles); return 1; } //---------------------------------------------------------------------------- void vtkPoissonReconstruction::PrintSelf(ostream & os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); }GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/FunctionData.h0000644000175000017500000000671111667757442025754 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef FUNCTION_DATA_INCLUDED #define FUNCTION_DATA_INCLUDED #include "PPolynomial.h" template< int Degree, class Real > class FunctionData { int useDotRatios; int normalize; public: const static int DOT_FLAG; const static int D_DOT_FLAG; const static int D2_DOT_FLAG; const static int VALUE_FLAG; const static int D_VALUE_FLAG; int depth, res, res2; Real * dotTable, *dDotTable, *d2DotTable; Real * valueTables, *dValueTables; PPolynomial< Degree > baseFunction; PPolynomial< Degree - 1 > dBaseFunction; PPolynomial< Degree + 1 > *baseFunctions; FunctionData(void); virtual ~FunctionData(void); virtual void setDotTables(const int & flags); virtual void clearDotTables(const int & flags); virtual void setValueTables(const int & flags, const double & smooth = 0); virtual void setValueTables(const int & flags, const double & valueSmooth, const double & normalSmooth); virtual void clearValueTables(void); void set(const int & maxDepth, const PPolynomial< Degree > & F, const int & normalize, const int & useDotRatios = 1); Real dotProduct(const double & center1, const double & width1, const double & center2, const double & width2) const; Real dDotProduct(const double & center1, const double & width1, const double & center2, const double & width2) const; Real d2DotProduct(const double & center1, const double & width1, const double & center2, const double & width2) const; static inline int SymmetricIndex(const int & i1, const int & i2); static inline int SymmetricIndex(const int & i1, const int & i2, int & index); }; #include "FunctionData.inl" #endif // FUNCTION_DATA_INCLUDED GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Vector.h0000644000175000017500000001046411667757442024637 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __VECTOR_HPP #define __VECTOR_HPP #include template< class T > class Vector { public: Vector(); Vector(const Vector< T > & V); Vector(size_t N); Vector(size_t N, T *pV); ~Vector(); const T & operator()(size_t i) const; T & operator()(size_t i); const T & operator[](size_t i) const; T & operator[](size_t i); void SetZero(); size_t Dimensions() const; void Resize(size_t N); Vector operator *(const T & A) const; Vector operator/(const T & A) const; Vector operator-(const Vector & V) const; Vector operator+(const Vector & V) const; Vector & operator*=(const T & A); Vector & operator/=(const T & A); Vector & operator+=(const Vector & V); Vector & operator-=(const Vector & V); Vector & AddScaled(const Vector & V, const T & scale); Vector & SubtractScaled(const Vector & V, const T & scale); static void Add(const Vector & V1, const T & scale1, const Vector & V2, const T & scale2, Vector & Out); static void Add(const Vector & V1, const T & scale1, const Vector & V2, Vector & Out); Vector operator-() const; Vector & operator=(const Vector & V); T Dot(const Vector & V) const; T Length() const; T Norm(size_t Ln) const; void Normalize(); T *m_pV; protected: size_t m_N; }; template< class T, int Dim > class NVector { public: NVector(); NVector(const NVector & V); NVector(size_t N); NVector(size_t N, T *pV); ~NVector(); const T * operator()(size_t i) const; T * operator()(size_t i); const T * operator[](size_t i) const; T * operator[](size_t i); void SetZero(); size_t Dimensions() const; void Resize(size_t N); NVector operator *(const T & A) const; NVector operator/(const T & A) const; NVector operator-(const NVector & V) const; NVector operator+(const NVector & V) const; NVector & operator*=(const T & A); NVector & operator/=(const T & A); NVector & operator+=(const NVector & V); NVector & operator-=(const NVector & V); NVector & AddScaled(const NVector & V, const T & scale); NVector & SubtractScaled(const NVector & V, const T & scale); static void Add(const NVector & V1, const T & scale1, const NVector & V2, const T & scale2, NVector & Out); static void Add(const NVector & V1, const T & scale1, const NVector & V2, NVector & Out); NVector operator-() const; NVector & operator=(const NVector & V); T Dot(const NVector & V) const; T Length() const; T Norm(size_t Ln) const; void Normalize(); T *m_pV; protected: size_t m_N; }; #include "Vector.inl" #endif GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Octree.h0000644000175000017500000004200011667757442024605 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef OCT_NODE_INCLUDED #define OCT_NODE_INCLUDED #include "Allocator.h" #include "BinaryNode.h" #include "MarchingCubes.h" #define DIMENSION 3 template< class NodeData, class Real = float > class OctNode { private: static int UseAlloc; class AdjacencyCountFunction { public: int count; void Function(const OctNode< NodeData, Real > *node1, const OctNode< NodeData, Real > *node2); }; template< class NodeAdjacencyFunction > void __processNodeFaces(OctNode *node, NodeAdjacencyFunction *F, const int & cIndex1, const int & cIndex2, const int & cIndex3, const int & cIndex4); template< class NodeAdjacencyFunction > void __processNodeEdges(OctNode *node, NodeAdjacencyFunction *F, const int & cIndex1, const int & cIndex2); template< class NodeAdjacencyFunction > void __processNodeNodes(OctNode *node, NodeAdjacencyFunction *F); template< class NodeAdjacencyFunction > static void __ProcessNodeAdjacentNodes(const int & dx, const int & dy, const int & dz, OctNode *node1, const int & radius1, OctNode *node2, const int & radius2, const int & cWidth2, NodeAdjacencyFunction *F); template< class TerminatingNodeAdjacencyFunction > static void __ProcessTerminatingNodeAdjacentNodes(const int & dx, const int & dy, const int & dz, OctNode *node1, const int & radius1, OctNode *node2, const int & radius2, const int & cWidth2, TerminatingNodeAdjacencyFunction *F); template< class PointAdjacencyFunction > static void __ProcessPointAdjacentNodes(const int & dx, const int & dy, const int & dz, OctNode *node2, const int & radius2, const int & cWidth2, PointAdjacencyFunction *F); template< class NodeAdjacencyFunction > static void __ProcessFixedDepthNodeAdjacentNodes(const int & dx, const int & dy, const int & dz, OctNode *node1, const int & radius1, OctNode *node2, const int & radius2, const int & cWidth2, const int & depth, NodeAdjacencyFunction *F); template< class NodeAdjacencyFunction > static void __ProcessMaxDepthNodeAdjacentNodes(const int & dx, const int & dy, const int & dz, OctNode *node1, const int & radius1, OctNode *node2, const int & radius2, const int & cWidth2, const int & depth, NodeAdjacencyFunction *F); // This is made private because the division by two has been pulled out. static inline int Overlap(const int & c1, const int & c2, const int & c3, const int & dWidth); inline static int ChildOverlap(const int & dx, const int & dy, const int & dz, const int & d, const int & cRadius2); const OctNode * __faceNeighbor(const int & dir, const int & off) const; const OctNode * __edgeNeighbor(const int & o, const int i[2], const int idx[2]) const; OctNode * __faceNeighbor(const int & dir, const int & off, const int & forceChildren); OctNode * __edgeNeighbor(const int & o, const int i[2], const int idx[2], const int & forceChildren); public: static const int DepthShift, OffsetShift, OffsetShift1, OffsetShift2, OffsetShift3; static const int DepthMask, OffsetMask; static Allocator< OctNode > OctreeAllocator; static int UseAllocator(void); static void SetAllocator(int blockSize); OctNode *parent; OctNode *children; short d, off[3]; NodeData nodeData; OctNode(void); ~OctNode(void); int initChildren(void); void depthAndOffset(int &depth, int offset[3]) const; int depth(void) const; static inline void DepthAndOffset(const long long &index, int &depth, int offset[3]); static inline void CenterAndWidth(const long long & index, Point3D< Real > & center, Real & width); static inline int Depth(const long long & index); static inline void Index(const int &depth, const int offset[3], short &d, short off[3]); void centerAndWidth(Point3D< Real > & center, Real & width) const; int leaves(void) const; int maxDepthLeaves(const int & maxDepth) const; int nodes(void) const; int maxDepth(void) const; const OctNode * root(void) const; const OctNode * nextLeaf(const OctNode *currentLeaf = NULL) const; OctNode * nextLeaf(OctNode *currentLeaf = NULL); const OctNode * nextNode(const OctNode *currentNode = NULL) const; OctNode * nextNode(OctNode *currentNode = NULL); const OctNode * nextBranch(const OctNode *current) const; OctNode * nextBranch(OctNode *current); void setFullDepth(const int & maxDepth); void printLeaves(void) const; void printRange(void) const; template< class NodeAdjacencyFunction > void processNodeFaces(OctNode *node, NodeAdjacencyFunction *F, const int & fIndex, const int & processCurrent = 1); template< class NodeAdjacencyFunction > void processNodeEdges(OctNode *node, NodeAdjacencyFunction *F, const int & eIndex, const int & processCurrent = 1); template< class NodeAdjacencyFunction > void processNodeCorners(OctNode *node, NodeAdjacencyFunction *F, const int & cIndex, const int & processCurrent = 1); template< class NodeAdjacencyFunction > void processNodeNodes(OctNode *node, NodeAdjacencyFunction *F, const int & processCurrent = 1); template< class NodeAdjacencyFunction > static void ProcessNodeAdjacentNodes(const int & maxDepth, OctNode *node1, const int & width1, OctNode *node2, const int & width2, NodeAdjacencyFunction *F, const int & processCurrent = 1); template< class NodeAdjacencyFunction > static void ProcessNodeAdjacentNodes(const int & dx, const int & dy, const int & dz, OctNode *node1, const int & radius1, OctNode *node2, const int & radius2, const int & width2, NodeAdjacencyFunction *F, const int & processCurrent = 1); template< class TerminatingNodeAdjacencyFunction > static void ProcessTerminatingNodeAdjacentNodes(const int & maxDepth, OctNode *node1, const int & width1, OctNode *node2, const int & width2, TerminatingNodeAdjacencyFunction *F, const int & processCurrent = 1); template< class TerminatingNodeAdjacencyFunction > static void ProcessTerminatingNodeAdjacentNodes(const int & dx, const int & dy, const int & dz, OctNode *node1, const int & radius1, OctNode *node2, const int & radius2, const int & width2, TerminatingNodeAdjacencyFunction *F, const int & processCurrent = 1); template< class PointAdjacencyFunction > static void ProcessPointAdjacentNodes(const int & maxDepth, const int center1[3], OctNode *node2, const int & width2, PointAdjacencyFunction *F, const int & processCurrent = 1); template< class PointAdjacencyFunction > static void ProcessPointAdjacentNodes(const int & dx, const int & dy, const int & dz, OctNode *node2, const int & radius2, const int & width2, PointAdjacencyFunction *F, const int & processCurrent = 1); template< class NodeAdjacencyFunction > static void ProcessFixedDepthNodeAdjacentNodes(const int & maxDepth, OctNode *node1, const int & width1, OctNode *node2, const int & width2, const int & depth, NodeAdjacencyFunction *F, const int & processCurrent = 1); template< class NodeAdjacencyFunction > static void ProcessFixedDepthNodeAdjacentNodes(const int & dx, const int & dy, const int & dz, OctNode *node1, const int & radius1, OctNode *node2, const int & radius2, const int & width2, const int & depth, NodeAdjacencyFunction *F, const int & processCurrent = 1); template< class NodeAdjacencyFunction > static void ProcessMaxDepthNodeAdjacentNodes(const int & maxDepth, OctNode *node1, const int & width1, OctNode *node2, const int & width2, const int & depth, NodeAdjacencyFunction *F, const int & processCurrent = 1); template< class NodeAdjacencyFunction > static void ProcessMaxDepthNodeAdjacentNodes(const int & dx, const int & dy, const int & dz, OctNode *node1, const int & radius1, OctNode *node2, const int & radius2, const int & width2, const int & depth, NodeAdjacencyFunction *F, const int & processCurrent = 1); static int CornerIndex(const Point3D< Real > & center, const Point3D< Real > & p); OctNode * faceNeighbor(const int & faceIndex, const int & forceChildren = 0); const OctNode * faceNeighbor(const int & faceIndex) const; OctNode * edgeNeighbor(const int & edgeIndex, const int & forceChildren = 0); const OctNode * edgeNeighbor(const int & edgeIndex) const; OctNode * cornerNeighbor(const int & cornerIndex, const int & forceChildren = 0); const OctNode * cornerNeighbor(const int & cornerIndex) const; OctNode * getNearestLeaf(const Point3D< Real > & p); const OctNode * getNearestLeaf(const Point3D< Real > & p) const; static int CommonEdge(const OctNode *node1, const int & eIndex1, const OctNode *node2, const int & eIndex2); static int CompareForwardDepths(const void *v1, const void *v2); static int CompareForwardPointerDepths(const void *v1, const void *v2); static int CompareBackwardDepths(const void *v1, const void *v2); static int CompareBackwardPointerDepths(const void *v1, const void *v2); template< class NodeData2 > OctNode & operator=(const OctNode< NodeData2, Real > & node); static inline int Overlap2(const int & depth1, const int offSet1[DIMENSION], const Real & multiplier1, const int & depth2, const int offSet2[DIMENSION], const Real & multiplier2); int write(const char *fileName) const; int write(FILE *fp) const; int read(const char *fileName); int read(FILE *fp); class Neighbors { public: OctNode *neighbors[3][3][3]; Neighbors(void); void clear(void); }; class NeighborKey { public: Neighbors *neighbors; NeighborKey(void); ~NeighborKey(void); void set(const int & depth); Neighbors & setNeighbors(OctNode *node); Neighbors & getNeighbors(OctNode *node); }; class Neighbors2 { public: const OctNode *neighbors[3][3][3]; Neighbors2(void); void clear(void); }; class NeighborKey2 { public: Neighbors2 *neighbors; NeighborKey2(void); ~NeighborKey2(void); void set(const int & depth); Neighbors2 & getNeighbors(const OctNode *node); }; void centerIndex(const int &maxDepth, int index[DIMENSION]) const; int width(const int & maxDepth) const; }; #include "Octree.inl" #endif // OCT_NODE GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Example.cxx0000644000175000017500000001154711667757442025346 0ustar mathieumathieu/*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Authors: David Doria at Rensselaer Polytechnic Institute and Arnaud Gelas at Harvard Medical School Copyright (c) 2010, David Doria at Rensselaer Polytechnic Institute and Arnaud Gelas at Harvard Medical School, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Rensselaer Polytechnic Institute and of Harvard Medical School nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "vtkPoissonReconstruction.h" int main(int argc, char *argv[]) { if ( argc < 4 ) { cout << "PoissonReconstruction takes 3 arguments: " << endl; cout << "1-Input file (*.vtp)" << endl; cout << "2-Depth" << endl; cout << "3-Output file (*.vtp)" << endl; return EXIT_FAILURE; } vtkstd::string inputFileName = argv[1]; //"horsePoints.vtp"; vtkstd::string outputFileName = argv[3]; //"horse.vtp"; int depth = atoi(argv[2]); vtkSmartPointer< vtkXMLPolyDataReader > reader = vtkSmartPointer< vtkXMLPolyDataReader >::New(); reader->SetFileName( inputFileName.c_str() ); reader->Update(); vtkSmartPointer< vtkPoissonReconstruction > poissonFilter = vtkSmartPointer< vtkPoissonReconstruction >::New(); poissonFilter->SetDepth(depth); poissonFilter->SetInputConnection( reader->GetOutputPort() ); poissonFilter->Update(); vtkSmartPointer< vtkXMLPolyDataWriter > writer = vtkSmartPointer< vtkXMLPolyDataWriter >::New(); writer->SetInputConnection( poissonFilter->GetOutputPort() ); writer->SetFileName( outputFileName.c_str() ); writer->Update(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Factor.h0000644000175000017500000000611311667757442024607 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef FACTOR_INCLUDED #define FACTOR_INCLUDED #include "PoissonReconstructionConfigure.h" //BTX #define PI 3.1415926535897932384 #define SQRT_3 1.7320508075688772935 PoissonReconstruction_EXPORT double ArcTan2(const double & y, const double & x); PoissonReconstruction_EXPORT void Sqrt(const double in[2], double out[2]); PoissonReconstruction_EXPORT void Add(const double in1[2], const double in2[2], double out[2]); PoissonReconstruction_EXPORT void Subtract(const double in1[2], const double in2[2], double out[2]); PoissonReconstruction_EXPORT void Multiply(const double in1[2], const double in2[2], double out[2]); PoissonReconstruction_EXPORT void Divide(const double in1[2], const double in2[2], double out[2]); PoissonReconstruction_EXPORT int Factor(double a1, double a0, double roots[1][2], const double &EPS); PoissonReconstruction_EXPORT int Factor(double a2, double a1, double a0, double roots[2][2], const double &EPS); PoissonReconstruction_EXPORT int Factor(double a3, double a2, double a1, double a0, double roots[3][2], const double &EPS); PoissonReconstruction_EXPORT int Factor(double a4, double a3, double a2, double a1, double a0, double roots[4][2], const double &EPS); PoissonReconstruction_EXPORT int Solve(const double *eqns, const double *values, double *solutions, const int & dim); //ETX #endif // FACTOR_INCLUDED GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/BinaryNode.h0000644000175000017500000000610311667757442025422 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef BINARY_NODE_INCLUDED #define BINARY_NODE_INCLUDED template< class Real > class BinaryNode { public: static inline int CenterCount(int depth){ return 1 << depth; } static inline int CumulativeCenterCount(int maxDepth){ return ( 1 << ( maxDepth + 1 ) ) - 1; } static inline int Index(int depth, int offSet){ return ( 1 << depth ) + offSet - 1; } static inline int CornerIndex(int maxDepth, int depth, int offSet, int forwardCorner) { return ( offSet + forwardCorner ) << ( maxDepth - depth ); } static inline Real CornerIndexPosition(int index, int maxDepth) { return Real(index) / ( 1 << maxDepth ); } static inline Real Width(int depth) { return Real( 1.0 / ( 1 << depth ) ); } static inline void CenterAndWidth(int depth, int offset, Real & center, Real & width) { width = Real( 1.0 / ( 1 << depth ) ); center = Real( ( 0.5 + offset ) * width ); } static inline void CenterAndWidth(int idx, Real & center, Real & width) { int depth, offset; DepthAndOffset(idx, depth, offset); CenterAndWidth(depth, offset, center, width); } static inline void DepthAndOffset(int idx, int & depth, int & offset) { int i = idx + 1; depth = -1; while ( i ) { i >>= 1; depth++; } offset = ( idx + 1 ) - ( 1 << depth ); } }; #endif // BINARY_NODE_INCLUDED GoFigure2-v0.9.0/Code/ExternalCode/PoissonReconstruction/Geometry.cpp0000644000175000017500000000730111667757442025517 0ustar mathieumathieu/*========================================================================= Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "Geometry.h" /////////////////// // CoredMeshData // /////////////////// const int CoredMeshData::IN_CORE_FLAG[]={1,2,4}; TriangulationEdge::TriangulationEdge(void){pIndex[0]=pIndex[1]=tIndex[0]=tIndex[1]=-1;} TriangulationTriangle::TriangulationTriangle(void){eIndex[0]=eIndex[1]=eIndex[2]=-1;} ///////////////////////// // CoredVectorMeshData // ///////////////////////// CoredVectorMeshData::CoredVectorMeshData(void){oocPointIndex=triangleIndex=0;} void CoredVectorMeshData::resetIterator(void){oocPointIndex=triangleIndex=0;} int CoredVectorMeshData::addOutOfCorePoint(const Point3D& p){ oocPoints.push_back(p); return int(oocPoints.size())-1; } int CoredVectorMeshData::addTriangle(const TriangleIndex& t,const int& coreFlag){ TriangleIndex tt; if(coreFlag & CoredMeshData::IN_CORE_FLAG[0]) {tt.idx[0]= t.idx[0];} else {tt.idx[0]=-t.idx[0]-1;} if(coreFlag & CoredMeshData::IN_CORE_FLAG[1]) {tt.idx[1]= t.idx[1];} else {tt.idx[1]=-t.idx[1]-1;} if(coreFlag & CoredMeshData::IN_CORE_FLAG[2]) {tt.idx[2]= t.idx[2];} else {tt.idx[2]=-t.idx[2]-1;} triangles.push_back(tt); return int(triangles.size())-1; } int CoredVectorMeshData::nextOutOfCorePoint(Point3D& p){ if(oocPointIndex const int FunctionData::DOT_FLAG=1; template const int FunctionData::D_DOT_FLAG=2; template const int FunctionData::D2_DOT_FLAG=4; template const int FunctionData::VALUE_FLAG=1; template const int FunctionData::D_VALUE_FLAG=2; template inline FunctionData::FunctionData(void) { dotTable=dDotTable=d2DotTable=NULL; valueTables=dValueTables=NULL; res=0; } template inline FunctionData::~FunctionData(void) { if(res){ if( dotTable){delete[] dotTable;} if( dDotTable){delete[] dDotTable;} if(d2DotTable){delete[] d2DotTable;} if( valueTables){delete[] valueTables;} if(dValueTables){delete[] dValueTables;} if(baseFunctions){delete[] baseFunctions;} } dotTable=dDotTable=d2DotTable=NULL; valueTables=dValueTables=NULL; baseFunctions=NULL; res=0; } template inline void FunctionData::set(const int& maxDepth,const PPolynomial& F,const int& iNormalize,const int& iUseDotRatios) { this->normalize=iNormalize; this->useDotRatios=iUseDotRatios; depth=maxDepth; res=BinaryNode::CumulativeCenterCount(depth); res2=(1<<(depth+1))+1; baseFunctions=new PPolynomial[res]; // Scale the function so that it has: // 0] Value 1 at 0 // 1] Integral equal to 1 // 2] Square integral equal to 1 switch(normalize){ case 2: baseFunction=F/sqrt((F*F).integral(F.polys[0].start,F.polys[F.polyCount-1].start)); break; case 1: baseFunction=F/F.integral(F.polys[0].start,F.polys[F.polyCount-1].start); break; default: baseFunction=F/F(0); } dBaseFunction=baseFunction.derivative(); double c1,w1; for(int i=0;i::CenterAndWidth(i,c1,w1); baseFunctions[i]=baseFunction.scale(w1).shift(c1); // Scale the function so that it has L2-norm equal to one switch(normalize){ case 2: baseFunctions[i]/=sqrt(w1); break; case 1: baseFunctions[i]/=w1; break; } } } template inline void FunctionData::setDotTables(const int& flags) { clearDotTables(flags); int size; size=(res*res+res)>>1; if(flags & DOT_FLAG){ dotTable=new Real[size]; memset(dotTable,0,sizeof(Real)*size); } if(flags & D_DOT_FLAG){ dDotTable=new Real[size]; memset(dDotTable,0,sizeof(Real)*size); } if(flags & D2_DOT_FLAG){ d2DotTable=new Real[size]; memset(d2DotTable,0,sizeof(Real)*size); } double t1,t2; t1=baseFunction.polys[0].start; t2=baseFunction.polys[baseFunction.polyCount-1].start; for(int i=0;i::CenterAndWidth(i,c1,w1); double start1 =t1*w1+c1; double end1 =t2*w1+c1; for(int j=0;j<=i;j++){ BinaryNode::CenterAndWidth(j,c2,w2); int idx=SymmetricIndex(i,j); double start =t1*w2+c2; double end =t2*w2+c2; if(startend1) {end=end1;} if(start>=end){continue;} BinaryNode::CenterAndWidth(j,c2,w2); Real dot=dotProduct(c1,w1,c2,w2); if(fabs(dot)<1e-15){continue;} if(flags & DOT_FLAG){dotTable[idx]=dot;} if(useDotRatios){ if(flags & D_DOT_FLAG){ dDotTable [idx]=-dDotProduct(c1,w1,c2,w2)/dot; } if(flags & D2_DOT_FLAG){d2DotTable[idx]=d2DotProduct(c1,w1,c2,w2)/dot;} } else{ if(flags & D_DOT_FLAG){ dDotTable[idx]= dDotProduct(c1,w1,c2,w2); } if(flags & D2_DOT_FLAG){d2DotTable[idx]=d2DotProduct(c1,w1,c2,w2);} } } } } template inline void FunctionData::clearDotTables(const int& flags) { if((flags & DOT_FLAG) && dotTable){ delete[] dotTable; dotTable=NULL; } if((flags & D_DOT_FLAG) && dDotTable){ delete[] dDotTable; dDotTable=NULL; } if((flags & D2_DOT_FLAG) && d2DotTable){ delete[] d2DotTable; d2DotTable=NULL; } } template inline void FunctionData::setValueTables(const int& flags,const double& smooth) { clearValueTables(); if(flags & VALUE_FLAG){ valueTables=new Real[res*res2];} if(flags & D_VALUE_FLAG){dValueTables=new Real[res*res2];} PPolynomial function; PPolynomial dFunction; for(int i=0;i0){ function=baseFunctions[i].MovingAverage(smooth); dFunction=baseFunctions[i].derivative().MovingAverage(smooth); } else{ function=baseFunctions[i]; dFunction=baseFunctions[i].derivative(); } for(int j=0;j inline void FunctionData::setValueTables(const int& flags,const double& valueSmooth,const double& normalSmooth) { clearValueTables(); if(flags & VALUE_FLAG){ valueTables=new Real[res*res2];} if(flags & D_VALUE_FLAG){dValueTables=new Real[res*res2];} PPolynomial function; PPolynomial dFunction; for(int i=0;i0) { function=baseFunctions[i].MovingAverage(valueSmooth);} else { function=baseFunctions[i];} if(normalSmooth>0) {dFunction=baseFunctions[i].derivative().MovingAverage(normalSmooth);} else {dFunction=baseFunctions[i].derivative();} for(int j=0;j inline void FunctionData::clearValueTables(void) { if( valueTables){delete[] valueTables;} if(dValueTables){delete[] dValueTables;} valueTables=dValueTables=NULL; } template inline Real FunctionData::dotProduct(const double& center1,const double& width1,const double& center2,const double& width2) const { double r=fabs(baseFunction.polys[0].start); switch(normalize){ case 2: return Real((baseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1/sqrt(width1*width2)); case 1: return Real((baseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1/(width1*width2)); default: return Real((baseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1); } } template inline Real FunctionData::dDotProduct(const double& center1,const double& width1,const double& center2,const double& width2) const { double r=fabs(baseFunction.polys[0].start); switch(normalize){ case 2: return Real((dBaseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/sqrt(width1*width2)); case 1: return Real((dBaseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/(width1*width2)); default: return Real((dBaseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)); } } template inline Real FunctionData::d2DotProduct(const double& center1,const double& width1,const double& center2,const double& width2) const { double r=fabs(baseFunction.polys[0].start); switch(normalize){ case 2: return Real((dBaseFunction*dBaseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2/sqrt(width1*width2)); case 1: return Real((dBaseFunction*dBaseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2/(width1*width2)); default: return Real((dBaseFunction*dBaseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2); } } template inline int FunctionData::SymmetricIndex(const int& i1,const int& i2){ if(i1>i2) {return ((i1*i1+i1)>>1)+i2;} else {return ((i2*i2+i2)>>1)+i1;} } template inline int FunctionData::SymmetricIndex(const int& i1,const int& i2,int& index) { if(i1>1)+i1; return 1; } else{ index=((i1*i1+i1)>>1)+i2; return 0; } } GoFigure2-v0.9.0/Code/ExternalCode/CMakeLists.txt0000644000175000017500000000010411667757442021356 0ustar mathieumathieuSUBDIRS( itkQt MegaVTK vtkLSM PoissonReconstruction ctk ) GoFigure2-v0.9.0/Code/ExternalCode/ctk/0000755000175000017500000000000011667757442017404 5ustar mathieumathieuGoFigure2-v0.9.0/Code/ExternalCode/ctk/ctkRangeSlider.cpp0000644000175000017500000006016211667757442023016 0ustar mathieumathieu/*========================================================================= Library: CTK Copyright (c) Kitware Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.commontk.org/LICENSE Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =========================================================================*/ // Qt includes #include #include #include #include #include #include #include // CTK includes #include "ctkRangeSlider.h" class ctkRangeSliderPrivate { Q_DECLARE_PUBLIC(ctkRangeSlider); protected: ctkRangeSlider* const q_ptr; public: ctkRangeSliderPrivate(ctkRangeSlider& object); void init(); /// Copied verbatim from QSliderPrivate class (see QSlider.cpp) int pixelPosToRangeValue(int pos) const; int pixelPosFromRangeValue(int val) const; /// Draw the bottom and top sliders. void drawMinimumSlider( QStylePainter* painter ) const; void drawMaximumSlider( QStylePainter* painter ) const; /// End points of the range on the Model int m_MaximumValue; int m_MinimumValue; /// End points of the range on the GUI. This is synced with the model. int m_MaximumPosition; int m_MinimumPosition; /// Controls selected ? QStyle::SubControl m_MinimumSliderSelected; QStyle::SubControl m_MaximumSliderSelected; /// See QSliderPrivate::clickOffset. /// Overrides this ivar int m_SubclassClickOffset; /// See QSliderPrivate::position /// Overrides this ivar. int m_SubclassPosition; /// Original width between the 2 bounds before any moves int m_SubclassWidth; /// Boolean indicates the selected handle /// True for the minimum range handle, false for the maximum range handle enum Handle { NoHandle = 0x0, MinimumHandle = 0x1, MaximumHandle = 0x2 }; Q_DECLARE_FLAGS(Handles, Handle); ctkRangeSliderPrivate::Handles m_SelectedHandles; /// When symmetricMoves is true, moving a handle will move the other handle /// symmetrically, otherwise the handles are independent. bool m_SymmetricMoves; }; // -------------------------------------------------------------------------- ctkRangeSliderPrivate::ctkRangeSliderPrivate(ctkRangeSlider& object) :q_ptr(&object) { this->m_MinimumValue = 0; this->m_MaximumValue = 100; this->m_MinimumPosition = 0; this->m_MaximumPosition = 100; this->m_MinimumSliderSelected = QStyle::SC_None; this->m_MaximumSliderSelected = QStyle::SC_None; this->m_SubclassClickOffset = 0; this->m_SubclassPosition = 0; this->m_SubclassWidth = 0; this->m_SelectedHandles = 0; this->m_SymmetricMoves = false; } // -------------------------------------------------------------------------- void ctkRangeSliderPrivate::init() { Q_Q(ctkRangeSlider); this->m_MinimumValue = q->minimum(); this->m_MaximumValue = q->maximum(); this->m_MinimumPosition = q->minimum(); this->m_MaximumPosition = q->maximum(); q->connect(q, SIGNAL(rangeChanged(int, int)), q, SLOT(onRangeChanged(int, int))); } // -------------------------------------------------------------------------- // Copied verbatim from QSliderPrivate::pixelPosToRangeValue. See QSlider.cpp // int ctkRangeSliderPrivate::pixelPosToRangeValue( int pos ) const { Q_Q(const ctkRangeSlider); QStyleOptionSlider option; q->initStyleOption( &option ); QRect gr = q->style()->subControlRect( QStyle::CC_Slider, &option, QStyle::SC_SliderGroove, q ); QRect sr = q->style()->subControlRect( QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, q ); int sliderMin, sliderMax, sliderLength; if (option.orientation == Qt::Horizontal) { sliderLength = sr.width(); sliderMin = gr.x(); sliderMax = gr.right() - sliderLength + 1; } else { sliderLength = sr.height(); sliderMin = gr.y(); sliderMax = gr.bottom() - sliderLength + 1; } return QStyle::sliderValueFromPosition( q->minimum(), q->maximum(), pos - sliderMin, sliderMax - sliderMin, option.upsideDown ); } //--------------------------------------------------------------------------- int ctkRangeSliderPrivate::pixelPosFromRangeValue( int val ) const { Q_Q(const ctkRangeSlider); QStyleOptionSlider option; q->initStyleOption( &option ); QRect gr = q->style()->subControlRect( QStyle::CC_Slider, &option, QStyle::SC_SliderGroove, q ); QRect sr = q->style()->subControlRect( QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, q ); int sliderMin, sliderMax, sliderLength; if (option.orientation == Qt::Horizontal) { sliderLength = sr.width(); sliderMin = gr.x(); sliderMax = gr.right() - sliderLength + 1; } else { sliderLength = sr.height(); sliderMin = gr.y(); sliderMax = gr.bottom() - sliderLength + 1; } return QStyle::sliderPositionFromValue( q->minimum(), q->maximum(), val, sliderMax - sliderMin, option.upsideDown ) + sliderMin; } //--------------------------------------------------------------------------- // Draw slider at the bottom end of the range void ctkRangeSliderPrivate::drawMinimumSlider( QStylePainter* painter ) const { Q_Q(const ctkRangeSlider); QStyleOptionSlider option; q->initMinimumSliderStyleOption( &option ); option.subControls = QStyle::SC_SliderHandle; option.sliderValue = m_MinimumValue; option.sliderPosition = m_MinimumPosition; if (this->m_SelectedHandles & MinimumHandle) { option.activeSubControls = QStyle::SC_SliderHandle; option.state |= QStyle::State_Sunken; } painter->drawComplexControl(QStyle::CC_Slider, option); } //--------------------------------------------------------------------------- // Draw slider at the top end of the range void ctkRangeSliderPrivate::drawMaximumSlider( QStylePainter* painter ) const { Q_Q(const ctkRangeSlider); QStyleOptionSlider option; q->initMaximumSliderStyleOption( &option ); option.subControls = QStyle::SC_SliderHandle; option.sliderValue = m_MaximumValue; option.sliderPosition = m_MaximumPosition; if (this->m_SelectedHandles & MaximumHandle) { option.activeSubControls = QStyle::SC_SliderHandle; option.state |= QStyle::State_Sunken; } painter->drawComplexControl(QStyle::CC_Slider, option); } // -------------------------------------------------------------------------- ctkRangeSlider::ctkRangeSlider(QWidget* iParent) : QSlider(iParent) , d_ptr(new ctkRangeSliderPrivate(*this)) { Q_D(ctkRangeSlider); d->init(); } // -------------------------------------------------------------------------- ctkRangeSlider::ctkRangeSlider( Qt::Orientation o, QWidget* parentObject ) :QSlider(o, parentObject) , d_ptr(new ctkRangeSliderPrivate(*this)) { Q_D(ctkRangeSlider); d->init(); } // -------------------------------------------------------------------------- ctkRangeSlider::ctkRangeSlider(ctkRangeSliderPrivate* impl, QWidget* iParent) : QSlider(iParent) , d_ptr(impl) { Q_D(ctkRangeSlider); d->init(); } // -------------------------------------------------------------------------- ctkRangeSlider::ctkRangeSlider( ctkRangeSliderPrivate* impl, Qt::Orientation o, QWidget* parentObject ) :QSlider(o, parentObject) , d_ptr(impl) { Q_D(ctkRangeSlider); d->init(); } // -------------------------------------------------------------------------- ctkRangeSlider::~ctkRangeSlider() { } // -------------------------------------------------------------------------- int ctkRangeSlider::minimumValue() const { Q_D(const ctkRangeSlider); return d->m_MinimumValue; } // -------------------------------------------------------------------------- void ctkRangeSlider::setMinimumValue( int min ) { Q_D(ctkRangeSlider); this->setValues( min, qMax(d->m_MaximumValue,min) ); } // -------------------------------------------------------------------------- int ctkRangeSlider::maximumValue() const { Q_D(const ctkRangeSlider); return d->m_MaximumValue; } // -------------------------------------------------------------------------- void ctkRangeSlider::setMaximumValue( int max ) { Q_D(ctkRangeSlider); this->setValues( qMin(d->m_MinimumValue, max), max ); } // -------------------------------------------------------------------------- void ctkRangeSlider::setValues(int l, int u) { Q_D(ctkRangeSlider); const int t_minimumValue = qBound(this->minimum(), qMin(l,u), this->maximum()); const int t_maximumValue = qBound(this->minimum(), qMax(l,u), this->maximum()); bool emitMinValChanged = (t_minimumValue != d->m_MinimumValue); bool emitMaxValChanged = (t_maximumValue != d->m_MaximumValue); d->m_MinimumValue = t_minimumValue; d->m_MaximumValue = t_maximumValue; bool emitMinPosChanged = (t_minimumValue != d->m_MinimumPosition); bool emitMaxPosChanged = (t_maximumValue != d->m_MaximumPosition); d->m_MinimumPosition = t_minimumValue; d->m_MaximumPosition = t_maximumValue; if (isSliderDown()) { if (emitMinPosChanged || emitMaxPosChanged) { emit positionsChanged(t_minimumValue, t_maximumValue); } if (emitMinPosChanged) { emit minimumPositionChanged(t_minimumValue); } if (emitMaxPosChanged) { emit maximumPositionChanged(t_maximumValue); } } if (emitMinValChanged || emitMaxValChanged) { emit valuesChanged(d->m_MinimumValue, d->m_MaximumValue); } if (emitMinValChanged) { emit minimumValueChanged(t_minimumValue); } if (emitMaxValChanged) { emit maximumValueChanged(t_maximumValue); } if (emitMinPosChanged || emitMaxPosChanged || emitMinValChanged || emitMaxValChanged) { this->update(); } } // -------------------------------------------------------------------------- int ctkRangeSlider::minimumPosition() const { Q_D(const ctkRangeSlider); return d->m_MinimumPosition; } // -------------------------------------------------------------------------- int ctkRangeSlider::maximumPosition() const { Q_D(const ctkRangeSlider); return d->m_MaximumPosition; } // -------------------------------------------------------------------------- void ctkRangeSlider::setMinimumPosition(int l) { Q_D(const ctkRangeSlider); this->setPositions(l, qMax(l, d->m_MaximumPosition)); } // -------------------------------------------------------------------------- void ctkRangeSlider::setMaximumPosition(int u) { Q_D(const ctkRangeSlider); this->setPositions(qMin(d->m_MinimumPosition, u), u); } // -------------------------------------------------------------------------- void ctkRangeSlider::setPositions(int min, int max) { Q_D(ctkRangeSlider); const int minPosition = qBound(this->minimum(), qMin(min, max), this->maximum()); const int maxPosition = qBound(this->minimum(), qMax(min, max), this->maximum()); bool emitMinPosChanged = (minPosition != d->m_MinimumPosition); bool emitMaxPosChanged = (maxPosition != d->m_MaximumPosition); if (!emitMinPosChanged && !emitMaxPosChanged) { return; } d->m_MinimumPosition = minPosition; d->m_MaximumPosition = maxPosition; if (!this->hasTracking()) { this->update(); } if (isSliderDown()) { if (emitMinPosChanged) { emit minimumPositionChanged(d->m_MinimumPosition); } if (emitMaxPosChanged) { emit maximumPositionChanged(d->m_MaximumPosition); } if (emitMinPosChanged || emitMaxPosChanged) { emit positionsChanged(d->m_MinimumPosition, d->m_MaximumPosition); } } if (this->hasTracking()) { this->triggerAction(SliderMove); this->setValues(d->m_MinimumPosition, d->m_MaximumPosition); } } // -------------------------------------------------------------------------- void ctkRangeSlider::setSymmetricMoves(bool symmetry) { Q_D(ctkRangeSlider); d->m_SymmetricMoves = symmetry; } // -------------------------------------------------------------------------- bool ctkRangeSlider::symmetricMoves()const { Q_D(const ctkRangeSlider); return d->m_SymmetricMoves; } // -------------------------------------------------------------------------- void ctkRangeSlider::onRangeChanged(int t_minimum, int t_maximum) { Q_UNUSED(t_minimum); Q_UNUSED(t_maximum); Q_D(ctkRangeSlider); this->setValues(d->m_MinimumValue, d->m_MaximumValue); } // -------------------------------------------------------------------------- // Render void ctkRangeSlider::paintEvent( QPaintEvent* ) { Q_D(ctkRangeSlider); QStyleOptionSlider option; this->initStyleOption(&option); QStylePainter painter(this); option.subControls = QStyle::SC_SliderGroove; option.sliderPosition = this->minimum(); // don't highlight the SliderGroove painter.drawComplexControl(QStyle::CC_Slider, option); option.sliderPosition = d->m_MinimumPosition; const QRect lr = style()->subControlRect( QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, this); option.sliderPosition = d->m_MaximumPosition; const QRect ur = style()->subControlRect( QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, this); QRect sr = style()->subControlRect( QStyle::CC_Slider, &option, QStyle::SC_SliderGroove, this); QRect rangeBox; if (option.orientation == Qt::Horizontal) { rangeBox = QRect( QPoint(qMin( lr.center().x(), ur.center().x() ), sr.center().y() - 2), QPoint(qMax( lr.center().x(), ur.center().x() ), sr.center().y() + 1)); } else { rangeBox = QRect( QPoint(sr.center().x() - 2, qMin( lr.center().y(), ur.center().y() )), QPoint(sr.center().x() + 1, qMax( lr.center().y(), ur.center().y() ))); } // ----------------------------- // Render the range // QRect groove = this->style()->subControlRect( QStyle::CC_Slider, &option, QStyle::SC_SliderGroove, this ); groove.adjust(0, 0, -1, 0); // Create default colors based on the transfer function. // QColor highlight = this->palette().color(QPalette::Normal, QPalette::Highlight); QLinearGradient gradient; if (option.orientation == Qt::Horizontal) { gradient = QLinearGradient( groove.center().x(), groove.top(), groove.center().x(), groove.bottom()); } else { gradient = QLinearGradient( groove.left(), groove.center().y(), groove.right(), groove.center().y()); } // TODO: Set this based on the supplied transfer function // QColor l = Qt::darkGray; // QColor u = Qt::black; gradient.setColorAt(0, highlight.darker(120)); gradient.setColorAt(1, highlight.lighter(160)); painter.setPen(QPen(highlight.darker(150), 0)); painter.setBrush(gradient); painter.drawRect( rangeBox.intersected(groove) ); // ----------------------------------- // Render the sliders // if (d->m_SelectedHandles & ctkRangeSliderPrivate::MinimumHandle) { d->drawMaximumSlider( &painter ); d->drawMinimumSlider( &painter ); } else { d->drawMinimumSlider( &painter ); d->drawMaximumSlider( &painter ); } } // -------------------------------------------------------------------------- // Standard Qt UI events void ctkRangeSlider::mousePressEvent(QMouseEvent* mouseEvent) { Q_D(ctkRangeSlider); if (minimum() == maximum() || (mouseEvent->buttons() ^ mouseEvent->button())) { mouseEvent->ignore(); return; } int t_pos = this->orientation() == Qt::Horizontal ? mouseEvent->pos().x() : mouseEvent->pos().y(); QStyleOptionSlider option; this->initStyleOption( &option ); // Check if the first handle is pressed option.sliderPosition = d->m_MinimumPosition; option.sliderValue = d->m_MinimumValue; QStyle::SubControl control; control = this->style()->hitTestComplexControl( QStyle::CC_Slider, &option, mouseEvent->pos(), this); const QRect lr = this->style()->subControlRect( QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, this); if (control == QStyle::SC_SliderHandle) { d->m_SubclassPosition = d->m_MinimumPosition; // save the position of the mouse inside the handle for later d->m_SubclassClickOffset = t_pos - (this->orientation() == Qt::Horizontal ? lr.left() : lr.top()); this->setSliderDown(true); if (d->m_SelectedHandles != ctkRangeSliderPrivate::MinimumHandle) { d->m_SelectedHandles = ctkRangeSliderPrivate::MinimumHandle; this->update(lr); } // Accept the mouseEvent mouseEvent->accept(); return; } // The user didn't press on the minimum handle, // Check if the other handle is pressed option.sliderPosition = d->m_MaximumPosition; option.sliderValue = d->m_MaximumValue; control = this->style()->hitTestComplexControl( QStyle::CC_Slider, &option, mouseEvent->pos(), this); const QRect ur = this->style()->subControlRect( QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, this); if (control == QStyle::SC_SliderHandle) { d->m_SubclassPosition = d->m_MaximumPosition; // save the position of the mouse inside the handle for later d->m_SubclassClickOffset = t_pos - (this->orientation() == Qt::Horizontal ? ur.left() : ur.top()); this->setSliderDown(true); if (d->m_SelectedHandles != ctkRangeSliderPrivate::MaximumHandle) { d->m_SelectedHandles = ctkRangeSliderPrivate::MaximumHandle; this->update(ur); } // Accept the mouseEvent mouseEvent->accept(); return; } // if we are here, no handles have been pressed // Check if we pressed on the groove between the 2 handles control = this->style()->hitTestComplexControl( QStyle::CC_Slider, &option, mouseEvent->pos(), this); QRect sr = style()->subControlRect( QStyle::CC_Slider, &option, QStyle::SC_SliderGroove, this); int minCenter = (this->orientation() == Qt::Horizontal ? lr.center().x() : ur.center().y()); int maxCenter = (this->orientation() == Qt::Horizontal ? ur.center().x() : lr.center().y()); if (control == QStyle::SC_SliderGroove && t_pos > minCenter && t_pos < maxCenter) { // warning lost of precision it might be fatal d->m_SubclassPosition = (d->m_MinimumPosition + d->m_MaximumPosition) / 2.; d->m_SubclassClickOffset = t_pos - d->pixelPosFromRangeValue(d->m_SubclassPosition); d->m_SubclassWidth = (d->m_MaximumPosition - d->m_MinimumPosition) / 2; qMax(d->m_SubclassPosition - d->m_MinimumPosition, d->m_MaximumPosition - d->m_SubclassPosition); this->setSliderDown(true); if (!(d->m_SelectedHandles & QFlags( ctkRangeSliderPrivate::MinimumHandle)) || !(d->m_SelectedHandles & QFlags(ctkRangeSliderPrivate::MaximumHandle))) { d->m_SelectedHandles = QFlags(ctkRangeSliderPrivate::MinimumHandle) | QFlags(ctkRangeSliderPrivate::MaximumHandle); this->update(lr.united(ur).united(sr)); } mouseEvent->accept(); return; } mouseEvent->ignore(); } // -------------------------------------------------------------------------- // Standard Qt UI events void ctkRangeSlider::mouseMoveEvent(QMouseEvent* mouseEvent) { Q_D(ctkRangeSlider); if (!d->m_SelectedHandles) { mouseEvent->ignore(); return; } int t_pos = this->orientation() == Qt::Horizontal ? mouseEvent->pos().x() : mouseEvent->pos().y(); QStyleOptionSlider option; this->initStyleOption(&option); const int m = style()->pixelMetric( QStyle::PM_MaximumDragDistance, &option, this ); int newPosition = d->pixelPosToRangeValue(t_pos - d->m_SubclassClickOffset); if (m >= 0) { const QRect r = rect().adjusted(-m, -m, m, m); if (!r.contains(mouseEvent->pos())) { newPosition = d->m_SubclassPosition; } } // The lower/left slider is down if (d->m_SelectedHandles == ctkRangeSliderPrivate::MinimumHandle) { double newMinPos = qMin(newPosition,d->m_MaximumPosition); this->setPositions(newMinPos, d->m_MaximumPosition + (d->m_SymmetricMoves ? d->m_MinimumPosition - newMinPos : 0)); } // The upper/right slider is down else if (d->m_SelectedHandles == ctkRangeSliderPrivate::MaximumHandle) { double newMaxPos = qMax(d->m_MinimumPosition, newPosition); this->setPositions(d->m_MinimumPosition - (d->m_SymmetricMoves ? newMaxPos - d->m_MaximumPosition: 0), newMaxPos); } // Both handles are down (the user clicked in between the handles) else if (d->m_SelectedHandles & ctkRangeSliderPrivate::MinimumHandle && d->m_SelectedHandles & ctkRangeSliderPrivate::MaximumHandle) { this->setPositions(newPosition - d->m_SubclassWidth, newPosition + d->m_SubclassWidth ); } mouseEvent->accept(); } // -------------------------------------------------------------------------- // Standard Qt UI mouseEvents void ctkRangeSlider::mouseReleaseEvent(QMouseEvent* mouseEvent) { Q_D(ctkRangeSlider); this->QSlider::mouseReleaseEvent(mouseEvent); setSliderDown(false); d->m_SelectedHandles = 0; this->update(); } // -------------------------------------------------------------------------- bool ctkRangeSlider::isMinimumSliderDown()const { Q_D(const ctkRangeSlider); return d->m_SelectedHandles & ctkRangeSliderPrivate::MinimumHandle; } // -------------------------------------------------------------------------- bool ctkRangeSlider::isMaximumSliderDown()const { Q_D(const ctkRangeSlider); return d->m_SelectedHandles & ctkRangeSliderPrivate::MaximumHandle; } // -------------------------------------------------------------------------- void ctkRangeSlider::initMinimumSliderStyleOption(QStyleOptionSlider* option) const { this->initStyleOption(option); } // -------------------------------------------------------------------------- void ctkRangeSlider::initMaximumSliderStyleOption(QStyleOptionSlider* option) const { this->initStyleOption(option); } GoFigure2-v0.9.0/Code/ExternalCode/ctk/ctkDoubleSlider.cpp0000644000175000017500000002501411667757442023171 0ustar mathieumathieu/*========================================================================= Library: CTK Copyright (c) Kitware Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.commontk.org/LICENSE Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =========================================================================*/ // QT includes #include #include // CTK includes #include "ctkDoubleSlider.h" // STD includes #include //----------------------------------------------------------------------------- class ctkDoubleSliderPrivate { Q_DECLARE_PUBLIC(ctkDoubleSlider); protected: ctkDoubleSlider* const q_ptr; public: ctkDoubleSliderPrivate(ctkDoubleSlider& object); int toInt(double _value)const; double fromInt(int _value)const; void init(); void updateOffset(double value); QSlider* Slider; double Minimum; double Maximum; bool SettingRange; // we should have a Offset and SliderPositionOffset (and MinimumOffset?) double Offset; double SingleStep; double Value; }; // -------------------------------------------------------------------------- ctkDoubleSliderPrivate::ctkDoubleSliderPrivate(ctkDoubleSlider& object) :q_ptr(&object) { this->Slider = 0; this->Minimum = 0.; this->Maximum = 100.; this->SettingRange = false; this->Offset = 0.; this->SingleStep = 1.; this->Value = 0.; } // -------------------------------------------------------------------------- void ctkDoubleSliderPrivate::init() { Q_Q(ctkDoubleSlider); this->Slider = new QSlider(q); QHBoxLayout* l = new QHBoxLayout(q); l->addWidget(this->Slider); l->setContentsMargins(0,0,0,0); this->Minimum = this->Slider->minimum(); this->Maximum = this->Slider->maximum(); this->SingleStep = this->Slider->singleStep(); this->Value = this->Slider->value(); q->connect(this->Slider, SIGNAL(valueChanged(int)), q, SLOT(onValueChanged(int))); q->connect(this->Slider, SIGNAL(sliderMoved(int)), q, SLOT(onSliderMoved(int))); q->connect(this->Slider, SIGNAL(sliderPressed()), q, SIGNAL(sliderPressed())); q->connect(this->Slider, SIGNAL(sliderReleased()), q, SIGNAL(sliderReleased())); q->connect(this->Slider, SIGNAL(rangeChanged(int, int)), q, SLOT(onRangeChanged(int, int))); q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::Slider)); } // -------------------------------------------------------------------------- int ctkDoubleSliderPrivate::toInt(double doubleValue)const { double tmp = doubleValue / this->SingleStep; static const double minInt = std::numeric_limits::min(); static const double maxInt = std::numeric_limits::max(); #ifndef QT_NO_DEBUG if (tmp < minInt || tmp > maxInt) { qWarning("ctkDoubleSliderPrivate::toInt value out of bounds !"); } #endif tmp = qBound(minInt, tmp, maxInt); int intValue = qRound(tmp); //qDebug() << __FUNCTION__ << doubleValue << tmp << intValue; return intValue; } // -------------------------------------------------------------------------- double ctkDoubleSliderPrivate::fromInt(int intValue)const { double doubleValue = this->SingleStep * (this->Offset + intValue) ; //qDebug() << __FUNCTION__ << intValue << doubleValue; return doubleValue; } // -------------------------------------------------------------------------- void ctkDoubleSliderPrivate::updateOffset(double value) { this->Offset = (value / this->SingleStep) - this->toInt(value); } // -------------------------------------------------------------------------- ctkDoubleSlider::ctkDoubleSlider(QWidget* _parent) : Superclass(_parent) , d_ptr(new ctkDoubleSliderPrivate(*this)) { Q_D(ctkDoubleSlider); d->init(); } // -------------------------------------------------------------------------- ctkDoubleSlider::ctkDoubleSlider(Qt::Orientation _orientation, QWidget* _parent) : Superclass(_parent) , d_ptr(new ctkDoubleSliderPrivate(*this)) { Q_D(ctkDoubleSlider); d->init(); this->setOrientation(_orientation); } // -------------------------------------------------------------------------- ctkDoubleSlider::~ctkDoubleSlider() { } // -------------------------------------------------------------------------- void ctkDoubleSlider::setMinimum(double min) { Q_D(ctkDoubleSlider); d->Minimum = min; if (d->Minimum >= d->Value) { d->updateOffset(d->Minimum); } d->SettingRange = true; d->Slider->setMinimum(d->toInt(min)); d->SettingRange = false; emit this->rangeChanged(d->Minimum, d->Maximum); } // -------------------------------------------------------------------------- void ctkDoubleSlider::setMaximum(double max) { Q_D(ctkDoubleSlider); d->Maximum = max; if (d->Maximum <= d->Value) { d->updateOffset(d->Maximum); } d->SettingRange = true; d->Slider->setMaximum(d->toInt(max)); d->SettingRange = false; emit this->rangeChanged(d->Minimum, d->Maximum); } // -------------------------------------------------------------------------- void ctkDoubleSlider::setRange(double min, double max) { Q_D(ctkDoubleSlider); d->Minimum = min; d->Maximum = max; if (d->Minimum >= d->Value) { d->updateOffset(d->Minimum); } if (d->Maximum <= d->Value) { d->updateOffset(d->Maximum); } d->SettingRange = true; d->Slider->setRange(d->toInt(min), d->toInt(max)); d->SettingRange = false; emit this->rangeChanged(d->Minimum, d->Maximum); } // -------------------------------------------------------------------------- double ctkDoubleSlider::minimum()const { Q_D(const ctkDoubleSlider); return d->Minimum; } // -------------------------------------------------------------------------- double ctkDoubleSlider::maximum()const { Q_D(const ctkDoubleSlider); return d->Maximum; } // -------------------------------------------------------------------------- double ctkDoubleSlider::sliderPosition()const { Q_D(const ctkDoubleSlider); return d->fromInt(d->Slider->sliderPosition()); } // -------------------------------------------------------------------------- void ctkDoubleSlider::setSliderPosition(double newSliderPosition) { Q_D(ctkDoubleSlider); d->Slider->setSliderPosition(d->toInt(newSliderPosition)); } // -------------------------------------------------------------------------- double ctkDoubleSlider::value()const { Q_D(const ctkDoubleSlider); return d->Value; } // -------------------------------------------------------------------------- void ctkDoubleSlider::setValue(double newValue) { Q_D(ctkDoubleSlider); newValue = qBound(d->Minimum, newValue, d->Maximum); d->updateOffset(newValue); int newIntValue = d->toInt(newValue); if (newIntValue != d->Slider->value()) { // d->Slider will emit a valueChanged signal that is connected to // ctkDoubleSlider::onValueChanged d->Slider->setValue(newIntValue); } else { double oldValue = d->Value; d->Value = newValue; // don't emit a valuechanged signal if the new value is quite // similar to the old value. if (qAbs(newValue - oldValue) > (d->SingleStep * 0.000000001)) { emit this->valueChanged(newValue); } } } // -------------------------------------------------------------------------- double ctkDoubleSlider::singleStep()const { Q_D(const ctkDoubleSlider); return d->SingleStep; } // -------------------------------------------------------------------------- void ctkDoubleSlider::setSingleStep(double newStep) { Q_D(ctkDoubleSlider); d->SingleStep = newStep; // update the new values of the QSlider double _value = d->Value; d->updateOffset(_value); bool oldBlockSignals = this->blockSignals(true); this->setRange(d->Minimum, d->Maximum); d->Slider->setValue(d->toInt(_value)); d->Value = _value; this->blockSignals(oldBlockSignals); } // -------------------------------------------------------------------------- double ctkDoubleSlider::tickInterval()const { Q_D(const ctkDoubleSlider); return d->fromInt(d->Slider->tickInterval()); } // -------------------------------------------------------------------------- void ctkDoubleSlider::setTickInterval(double newTickInterval) { Q_D(ctkDoubleSlider); d->Slider->setTickInterval(d->toInt(newTickInterval)); } // -------------------------------------------------------------------------- bool ctkDoubleSlider::hasTracking()const { Q_D(const ctkDoubleSlider); return d->Slider->hasTracking(); } // -------------------------------------------------------------------------- void ctkDoubleSlider::setTracking(bool enable) { Q_D(ctkDoubleSlider); d->Slider->setTracking(enable); } // -------------------------------------------------------------------------- void ctkDoubleSlider::triggerAction( QAbstractSlider::SliderAction action) { Q_D(ctkDoubleSlider); d->Slider->triggerAction(action); } // -------------------------------------------------------------------------- Qt::Orientation ctkDoubleSlider::orientation()const { Q_D(const ctkDoubleSlider); return d->Slider->orientation(); } // -------------------------------------------------------------------------- void ctkDoubleSlider::setOrientation(Qt::Orientation newOrientation) { Q_D(ctkDoubleSlider); d->Slider->setOrientation(newOrientation); } // -------------------------------------------------------------------------- void ctkDoubleSlider::onValueChanged(int newValue) { Q_D(ctkDoubleSlider); double doubleNewValue = d->fromInt(newValue); /* qDebug() << "onValueChanged: " << newValue << "->"<< d->fromInt(newValue+d->Offset) << " old: " << d->Value << "->" << d->toInt(d->Value) << "offset:" << d->Offset << doubleNewValue; */ if (d->Value == doubleNewValue) { return; } d->Value = doubleNewValue; emit this->valueChanged(d->Value); } // -------------------------------------------------------------------------- void ctkDoubleSlider::onSliderMoved(int newPosition) { Q_D(const ctkDoubleSlider); emit this->sliderMoved(d->fromInt(newPosition)); } // -------------------------------------------------------------------------- void ctkDoubleSlider::onRangeChanged(int min, int max) { Q_D(const ctkDoubleSlider); if (!d->SettingRange) { this->setRange(d->fromInt(min), d->fromInt(max)); } } GoFigure2-v0.9.0/Code/ExternalCode/ctk/ctkCollapsibleGroupBox.cpp0000644000175000017500000001335011667757442024533 0ustar mathieumathieu/*========================================================================= Library: CTK Copyright (c) Kitware Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.commontk.org/LICENSE Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =========================================================================*/ // Qt includes #include #include #include #include #include #include // CTK includes #include "ctkCollapsibleGroupBox.h" //----------------------------------------------------------------------------- ctkCollapsibleGroupBox::ctkCollapsibleGroupBox(QWidget* _parent) :QGroupBox(_parent) { this->init(); } //----------------------------------------------------------------------------- ctkCollapsibleGroupBox::ctkCollapsibleGroupBox(const QString& _title, QWidget* _parent) :QGroupBox(_title, _parent) { this->init(); } //----------------------------------------------------------------------------- ctkCollapsibleGroupBox::~ctkCollapsibleGroupBox() { if(Style) { delete Style; } } //----------------------------------------------------------------------------- void ctkCollapsibleGroupBox::init() { this->setCheckable(true); connect(this, SIGNAL(toggled(bool)), this, SLOT(expand(bool))); this->MaxHeight = this->maximumHeight(); #if QT_VERSION >= 0x040600 Style = new ctkCollapsibleGroupBoxStyle; this->setStyle(Style); #else this->setStyleSheet( "ctkCollapsibleGroupBox::indicator:checked{" "image: url(:/Icons/expand-up.png);}" "ctkCollapsibleGroupBox::indicator:unchecked{" "image: url(:/Icons/expand-down.png);}"); #endif } //----------------------------------------------------------------------------- void ctkCollapsibleGroupBox::expand(bool _expand) { if (!_expand) { this->OldSize = this->size(); } /*QObjectList childList = this->children(); for (int i = 0; i < childList.size(); ++i) { QObject *o = childList.at(i); if (o && o->isWidgetType()) { QWidget *w = static_cast(o); if ( w ) { w->setVisible(_expand); } } }*/ if (_expand) { this->setMaximumHeight(this->MaxHeight); this->resize(this->OldSize); this->setFlat(false); } else { this->MaxHeight = this->maximumHeight(); this->setMaximumHeight(22); this->setFlat(true); } //this->updateGeometry(); //this->sizeHint(); } //----------------------------------------------------------------------------- void ctkCollapsibleGroupBox::childEvent(QChildEvent* c) { if(c && c->type() == QEvent::ChildAdded) { if (c->child() && c->child()->isWidgetType()) { QWidget *w = static_cast(c->child()); w->setVisible(this->isChecked()); } } QGroupBox::childEvent(c); } #if QT_VERSION < 0x040600 //----------------------------------------------------------------------------- void ctkCollapsibleGroupBox::paintEvent(QPaintEvent* e) { this->QGroupBox::paintEvent(e); QStylePainter paint(this); QStyleOptionGroupBox option; initStyleOption(&option); option.activeSubControls &= !QStyle::SC_GroupBoxCheckBox; paint.drawComplexControl(QStyle::CC_GroupBox, option); } //----------------------------------------------------------------------------- void ctkCollapsibleGroupBox::mousePressEvent(QMouseEvent *event) { if (event->button() != Qt::LeftButton) { event->ignore(); return; } // no animation } //----------------------------------------------------------------------------- void ctkCollapsibleGroupBox::mouseReleaseEvent(QMouseEvent *event) { if (event->button() != Qt::LeftButton) { event->ignore(); return; } QStyleOptionGroupBox box; initStyleOption(&box); box.activeSubControls &= !QStyle::SC_GroupBoxCheckBox; QStyle::SubControl released = style()->hitTestComplexControl(QStyle::CC_GroupBox, &box, event->pos(), this); bool toggle = this->isCheckable() && (released == QStyle::SC_GroupBoxLabel || released == QStyle::SC_GroupBoxCheckBox); if (toggle) { this->setChecked(!this->isChecked()); } } #endif //----------------------------------------------------------------------------- QSize ctkCollapsibleGroupBox::minimumSizeHint() const { //qDebug() << "ctkCollapsibleGroupBox::minimumSizeHint::" << this->QGroupBox::minimumSizeHint() ; return this->QGroupBox::minimumSizeHint(); } //----------------------------------------------------------------------------- QSize ctkCollapsibleGroupBox::sizeHint() const { //qDebug() << "ctkCollapsibleGroupBox::sizeHint::" << this->QGroupBox::sizeHint() ; return this->QGroupBox::sizeHint(); } //----------------------------------------------------------------------------- int ctkCollapsibleGroupBox::heightForWidth(int w) const { //qDebug() << "ctkCollapsibleGroupBox::heightForWidth::" << this->QGroupBox::heightForWidth(w) ; return this->QGroupBox::heightForWidth(w); } //----------------------------------------------------------------------------- void ctkCollapsibleGroupBox::resizeEvent ( QResizeEvent * _event ) { //qDebug() << "ctkCollapsibleGroupBox::resizeEvent::" << _event->oldSize() << _event->size() ; return this->QGroupBox::resizeEvent(_event); } GoFigure2-v0.9.0/Code/ExternalCode/ctk/ctkDoubleRangeSlider.cpp0000644000175000017500000004673011667757442024156 0ustar mathieumathieu/*========================================================================= Library: CTK Copyright (c) Kitware Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.commontk.org/LICENSE Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =========================================================================*/ // Qt includes #include #include // CTK includes #include "ctkRangeSlider.h" #include "ctkDoubleRangeSlider.h" //----------------------------------------------------------------------------- class ctkDoubleRangeSliderPrivate { Q_DECLARE_PUBLIC(ctkDoubleRangeSlider); protected: ctkDoubleRangeSlider* const q_ptr; public: ctkDoubleRangeSliderPrivate(ctkDoubleRangeSlider& object); int toInt(double _value)const; double minFromInt(int _value)const; double maxFromInt(int _value)const; void init(); void connectSlider(); void updateMinOffset(double value); void updateMaxOffset(double value); ctkRangeSlider* Slider; double Minimum; double Maximum; bool SettingRange; // we should have a MinValueOffset and MinPositionOffset (and MinimumOffset?) double MinOffset; // we should have a MaxValueOffset and MaxPositionOffset (and MaximumOffset?) double MaxOffset; double SingleStep; double MinValue; double MaxValue; }; // -------------------------------------------------------------------------- ctkDoubleRangeSliderPrivate::ctkDoubleRangeSliderPrivate(ctkDoubleRangeSlider& object) :q_ptr(&object) { // the initial values will be overwritten in // ctkDoubleRangeSliderPrivate::init() this->Slider = 0; this->Minimum = 0.; this->Maximum = 99.; this->SettingRange = false; this->MinOffset = 0.; this->MaxOffset = 0.; this->SingleStep = 1.; this->MinValue = 0.; this->MaxValue = 99.; } // -------------------------------------------------------------------------- void ctkDoubleRangeSliderPrivate::init() { Q_Q(ctkDoubleRangeSlider); this->Slider = new ctkRangeSlider(q); QHBoxLayout* l = new QHBoxLayout(q); l->addWidget(this->Slider); l->setContentsMargins(0,0,0,0); this->Minimum = this->Slider->minimum(); this->Maximum = this->Slider->maximum(); this->MinValue = this->Slider->minimumValue(); this->MaxValue = this->Slider->maximumValue(); this->SingleStep = this->Slider->singleStep(); q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::Slider)); this->connectSlider(); } // -------------------------------------------------------------------------- void ctkDoubleRangeSliderPrivate::connectSlider() { Q_Q(ctkDoubleRangeSlider); q->connect(this->Slider, SIGNAL(minimumValueChanged(int)), q, SLOT(onMinValueChanged(int))); q->connect(this->Slider, SIGNAL(maximumValueChanged(int)), q, SLOT(onMaxValueChanged(int))); q->connect(this->Slider, SIGNAL(valuesChanged(int,int)), q, SLOT(onValuesChanged(int,int))); q->connect(this->Slider, SIGNAL(minimumPositionChanged(int)), q, SLOT(onMinPosChanged(int))); q->connect(this->Slider, SIGNAL(maximumPositionChanged(int)), q, SLOT(onMaxPosChanged(int))); q->connect(this->Slider, SIGNAL(positionsChanged(int,int)), q, SLOT(onPositionsChanged(int,int))); q->connect(this->Slider, SIGNAL(sliderPressed()), q, SIGNAL(sliderPressed())); q->connect(this->Slider, SIGNAL(sliderReleased()), q, SIGNAL(sliderReleased())); q->connect(this->Slider, SIGNAL(rangeChanged(int, int)), q, SLOT(onRangeChanged(int, int))); } // -------------------------------------------------------------------------- int ctkDoubleRangeSliderPrivate::toInt(double doubleValue)const { double tmp = doubleValue / this->SingleStep; int intValue = qRound(tmp); return intValue; } // -------------------------------------------------------------------------- double ctkDoubleRangeSliderPrivate::minFromInt(int intValue)const { double doubleValue = this->SingleStep * (this->MinOffset + intValue) ; return doubleValue; } // -------------------------------------------------------------------------- double ctkDoubleRangeSliderPrivate::maxFromInt(int intValue)const { double doubleValue = this->SingleStep * (this->MaxOffset + intValue) ; return doubleValue; } // -------------------------------------------------------------------------- void ctkDoubleRangeSliderPrivate::updateMinOffset(double value) { this->MinOffset = (value / this->SingleStep) - this->toInt(value); } // -------------------------------------------------------------------------- void ctkDoubleRangeSliderPrivate::updateMaxOffset(double value) { this->MaxOffset = (value / this->SingleStep) - this->toInt(value); } // -------------------------------------------------------------------------- ctkDoubleRangeSlider::ctkDoubleRangeSlider(QWidget* _parent) : Superclass(_parent) , d_ptr(new ctkDoubleRangeSliderPrivate(*this)) { Q_D(ctkDoubleRangeSlider); d->init(); } // -------------------------------------------------------------------------- ctkDoubleRangeSlider::ctkDoubleRangeSlider(Qt::Orientation _orientation, QWidget* _parent) : Superclass(_parent) , d_ptr(new ctkDoubleRangeSliderPrivate(*this)) { Q_D(ctkDoubleRangeSlider); d->init(); this->setOrientation(_orientation); } // -------------------------------------------------------------------------- ctkDoubleRangeSlider::~ctkDoubleRangeSlider() { } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setMinimum(double min) { Q_D(ctkDoubleRangeSlider); d->Minimum = min; if (d->Minimum >= d->MinValue) {// TBD: use same offset d->updateMinOffset(d->Minimum); } if (d->Minimum >= d->MaxValue) {// TBD: use same offset d->updateMaxOffset(d->Minimum); } d->SettingRange = true; d->Slider->setMinimum(d->toInt(min)); d->SettingRange = false; emit this->rangeChanged(d->Minimum, d->Maximum); } // -------------------------------------------------------------------------- double ctkDoubleRangeSlider::minimum()const { Q_D(const ctkDoubleRangeSlider); return d->Minimum; } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setMaximum(double max) { Q_D(ctkDoubleRangeSlider); d->Maximum = max; if (d->Maximum <= d->MinValue) {// TBD: use same offset d->updateMinOffset(d->Maximum); } if (d->Maximum <= d->MaxValue) {// TBD: use same offset ? d->updateMaxOffset(d->Maximum); } d->SettingRange = true; d->Slider->setMaximum(d->toInt(max)); d->SettingRange = false; emit this->rangeChanged(d->Minimum, d->Maximum); } // -------------------------------------------------------------------------- double ctkDoubleRangeSlider::maximum()const { Q_D(const ctkDoubleRangeSlider); return d->Maximum; } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setRange(double min, double max) { Q_D(ctkDoubleRangeSlider); d->Minimum = min; d->Maximum = max; if (d->Minimum >= d->MinValue) {// TBD: use same offset d->updateMinOffset(d->Minimum); } if (d->Minimum >= d->MaxValue) {// TBD: use same offset d->updateMaxOffset(d->Minimum); } if (d->Maximum <= d->MinValue) {// TBD: use same offset d->updateMinOffset(d->Maximum); } if (d->Maximum <= d->MaxValue) {// TBD: use same offset ? d->updateMaxOffset(d->Maximum); } d->SettingRange = true; d->Slider->setRange(d->toInt(min), d->toInt(max)); d->SettingRange = false; emit this->rangeChanged(d->Minimum, d->Maximum); } // -------------------------------------------------------------------------- double ctkDoubleRangeSlider::minimumPosition()const { Q_D(const ctkDoubleRangeSlider); return d->minFromInt(d->Slider->minimumPosition()); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setMinimumPosition(double minPos) { Q_D(ctkDoubleRangeSlider); d->Slider->setMinimumPosition(d->toInt(minPos)); } // -------------------------------------------------------------------------- double ctkDoubleRangeSlider::maximumPosition()const { Q_D(const ctkDoubleRangeSlider); return d->maxFromInt(d->Slider->maximumPosition()); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setMaximumPosition(double maxPos) { Q_D(ctkDoubleRangeSlider); d->Slider->setMaximumPosition(d->toInt(maxPos)); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setPositions(double minPos, double maxPos) { Q_D(ctkDoubleRangeSlider); d->Slider->setPositions(d->toInt(minPos), d->toInt(maxPos)); } // -------------------------------------------------------------------------- double ctkDoubleRangeSlider::minimumValue()const { Q_D(const ctkDoubleRangeSlider); return d->MinValue; } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setMinimumValue(double newMinValue) { Q_D(ctkDoubleRangeSlider); newMinValue = qBound(d->Minimum, newMinValue, d->Maximum); d->updateMinOffset(newMinValue); if (newMinValue >= d->MaxValue) { d->updateMaxOffset(newMinValue); } int newIntValue = d->toInt(newMinValue); if (newIntValue != d->Slider->minimumValue()) { // d->Slider will emit a minimumValueChanged signal that is connected to // ctkDoubleSlider::onValueChanged d->Slider->setMinimumValue(newIntValue); } else { double oldValue = d->MinValue; d->MinValue = newMinValue; // don't emit a valuechanged signal if the new value is quite // similar to the old value. if (qAbs(newMinValue - oldValue) > (d->SingleStep * 0.000000001)) { emit this->valuesChanged(newMinValue, this->maximumValue()); emit this->minimumValueChanged(newMinValue); } } } // -------------------------------------------------------------------------- double ctkDoubleRangeSlider::maximumValue()const { Q_D(const ctkDoubleRangeSlider); return d->MaxValue; } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setMaximumValue(double newMaxValue) { Q_D(ctkDoubleRangeSlider); newMaxValue = qBound(d->Minimum, newMaxValue, d->Maximum); d->updateMaxOffset(newMaxValue); if (newMaxValue <= d->MinValue) { d->updateMinOffset(newMaxValue); } int newIntValue = d->toInt(newMaxValue); if (newIntValue != d->Slider->maximumValue()) { // d->Slider will emit a maximumValueChanged signal that is connected to // ctkDoubleSlider::onValueChanged d->Slider->setMaximumValue(newIntValue); } else { double oldValue = d->MaxValue; d->MaxValue = newMaxValue; // don't emit a valuechanged signal if the new value is quite // similar to the old value. if (qAbs(newMaxValue - oldValue) > (d->SingleStep * 0.000000001)) { emit this->valuesChanged(this->minimumValue(), newMaxValue); emit this->maximumValueChanged(newMaxValue); } } } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setValues(double newMinVal, double newMaxVal) { Q_D(ctkDoubleRangeSlider); // We can't call setMinimumValue() and setMaximumValue() as they would // generate an inconsistent state. when minimumValueChanged() is fired the // new max value wouldn't be updated yet. double newMinValue = qBound(d->Minimum, qMin(newMinVal, newMaxVal), d->Maximum); double newMaxValue = qBound(d->Minimum, qMax(newMinVal, newMaxVal), d->Maximum); d->updateMinOffset(newMinValue); d->updateMaxOffset(newMaxValue); int newMinIntValue = d->toInt(newMinValue); int newMaxIntValue = d->toInt(newMaxValue); if (newMinIntValue != d->Slider->minimumValue() || newMaxIntValue != d->Slider->maximumValue()) { // d->Slider will emit a maximumValueChanged signal that is connected to // ctkDoubleSlider::onValueChanged d->Slider->setValues(newMinIntValue, newMaxIntValue); } else { double oldMinValue = d->MinValue; double oldMaxValue = d->MaxValue; d->MinValue = newMinValue; d->MaxValue = newMaxValue; // don't emit a valuechanged signal if the new value is quite // similar to the old value. bool minChanged = qAbs(newMinValue - oldMinValue) > (d->SingleStep * 0.000000001); bool maxChanged = qAbs(newMaxValue - oldMaxValue) > (d->SingleStep * 0.000000001); if (minChanged || maxChanged) { emit this->valuesChanged(newMinValue, newMaxValue); if (minChanged) { emit this->minimumValueChanged(newMinValue); } if (maxChanged) { emit this->maximumValueChanged(newMaxValue); } } } } // -------------------------------------------------------------------------- double ctkDoubleRangeSlider::singleStep()const { Q_D(const ctkDoubleRangeSlider); return d->SingleStep; } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setSingleStep(double newStep) { Q_D(ctkDoubleRangeSlider); d->SingleStep = newStep; // The following can fire A LOT of signals that shouldn't be // fired. bool oldBlockSignals = this->blockSignals(true); d->updateMinOffset(d->MinValue); d->updateMaxOffset(d->MaxValue); // update the new values of the ctkRangeSlider double _minvalue = d->MinValue; double _maxvalue = d->MaxValue; // calling setMinimum or setMaximum can change the values MinimumValue // and MaximumValue, this is why we re-set them later. this->setMinimum(d->Minimum); this->setMaximum(d->Maximum); this->setMinimumValue(_minvalue); this->setMinimumPosition(_minvalue); this->setMaximumValue(_maxvalue); this->setMaximumPosition(_maxvalue); this->blockSignals(oldBlockSignals); } // -------------------------------------------------------------------------- double ctkDoubleRangeSlider::tickInterval()const { Q_D(const ctkDoubleRangeSlider); return d->minFromInt(d->Slider->tickInterval()); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setTickInterval(double newTickInterval) { Q_D(ctkDoubleRangeSlider); d->Slider->setTickInterval(d->toInt(newTickInterval)); } // -------------------------------------------------------------------------- bool ctkDoubleRangeSlider::hasTracking()const { Q_D(const ctkDoubleRangeSlider); return d->Slider->hasTracking(); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setTracking(bool enable) { Q_D(ctkDoubleRangeSlider); d->Slider->setTracking(enable); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::triggerAction( QAbstractSlider::SliderAction action) { Q_D(ctkDoubleRangeSlider); d->Slider->triggerAction(action); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setOrientation(Qt::Orientation newOrientation) { Q_D(ctkDoubleRangeSlider); d->Slider->setOrientation(newOrientation); } // -------------------------------------------------------------------------- Qt::Orientation ctkDoubleRangeSlider::orientation()const { Q_D(const ctkDoubleRangeSlider); return d->Slider->orientation(); } // -------------------------------------------------------------------------- bool ctkDoubleRangeSlider::symmetricMoves()const { Q_D(const ctkDoubleRangeSlider); return d->Slider->symmetricMoves(); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setSymmetricMoves(bool symmetry) { Q_D(ctkDoubleRangeSlider); d->Slider->setSymmetricMoves(symmetry); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::onMinValueChanged(int newValue) { Q_D(ctkDoubleRangeSlider); double doubleNewValue = d->minFromInt(newValue); if (d->MinValue == doubleNewValue) { return; } d->MinValue = doubleNewValue; emit this->valuesChanged(d->MinValue, d->MaxValue); emit this->minimumValueChanged(d->MinValue); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::onMaxValueChanged(int newValue) { Q_D(ctkDoubleRangeSlider); double doubleNewValue = d->maxFromInt(newValue); if (d->MaxValue == doubleNewValue) { return; } d->MaxValue = doubleNewValue; emit this->valuesChanged(d->MinValue, d->MaxValue); emit this->maximumValueChanged(d->MaxValue); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::onValuesChanged(int newMinValue, int newMaxValue) { Q_D(ctkDoubleRangeSlider); double doubleNewMinValue = d->minFromInt(newMinValue); double doubleNewMaxValue = d->maxFromInt(newMaxValue); bool emitMinValueChanged = (d->MinValue != doubleNewMinValue); bool emitMaxValueChanged = (d->MaxValue != doubleNewMaxValue); if (!emitMinValueChanged && !emitMaxValueChanged) { return; } d->MinValue = doubleNewMinValue; d->MaxValue = doubleNewMaxValue; emit this->valuesChanged(d->MinValue, d->MaxValue); if (emitMinValueChanged) { emit this->minimumValueChanged(d->MinValue); } if (emitMaxValueChanged) { emit this->maximumValueChanged(d->MaxValue); } } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::onMinPosChanged(int newPosition) { Q_D(const ctkDoubleRangeSlider); emit this->minimumPositionChanged(d->minFromInt(newPosition)); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::onMaxPosChanged(int newPosition) { Q_D(const ctkDoubleRangeSlider); emit this->maximumPositionChanged(d->maxFromInt(newPosition)); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::onPositionsChanged(int min, int max) { Q_D(const ctkDoubleRangeSlider); emit this->positionsChanged(d->minFromInt(min), d->maxFromInt(max)); } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::onRangeChanged(int min, int max) { Q_D(const ctkDoubleRangeSlider); if (!d->SettingRange) { this->setRange(d->minFromInt(min), d->maxFromInt(max)); } } // -------------------------------------------------------------------------- ctkRangeSlider* ctkDoubleRangeSlider::slider()const { Q_D(const ctkDoubleRangeSlider); return d->Slider; } // -------------------------------------------------------------------------- void ctkDoubleRangeSlider::setSlider(ctkRangeSlider* t_slider) { Q_D(ctkDoubleRangeSlider); t_slider->setOrientation(d->Slider->orientation()); t_slider->setMinimum(d->Slider->minimum()); t_slider->setMaximum(d->Slider->maximum()); t_slider->setValues(d->Slider->minimumValue(), d->Slider->maximumValue()); t_slider->setSingleStep(d->Slider->singleStep()); t_slider->setTracking(d->Slider->hasTracking()); t_slider->setTickInterval(d->Slider->tickInterval()); delete d->Slider; qobject_cast(this->layout())->addWidget(t_slider); d->Slider = t_slider; d->connectSlider(); } GoFigure2-v0.9.0/Code/ExternalCode/ctk/CMakeLists.txt0000644000175000017500000000341711667757442022151 0ustar mathieumathieuIF( WIN32 ) IF( NOT CYGWIN ) IF( NOT MINGW ) IF( BUILD_SHARED_LIBS ) ADD_DEFINITIONS( -Dctk_EXPORTS ) ENDIF( BUILD_SHARED_LIBS ) ENDIF( NOT MINGW ) ENDIF( NOT CYGWIN ) ENDIF( WIN32 ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/ctkConfigure.h.in ${CMAKE_CURRENT_BINARY_DIR}/ctkConfigure.h @ONLY IMMEDIATE ) #Define sources SET( ctk_SRCS ctkRangeSlider.cpp ctkDoubleSlider.cpp ctkDoubleRangeSlider.cpp ctkCollapsibleGroupBox.cpp ctkRangeSlider.h ctkDoubleSlider.h ctkDoubleRangeSlider.h ctkCollapsibleGroupBox.h ) #Headers that should run through moc SET(ctk_MOC_SRCS ctkRangeSlider.h ctkDoubleSlider.h ctkDoubleRangeSlider.h ctkCollapsibleGroupBox.h ) # Wrap QT4_WRAP_CPP(MY_MOC_CPP ${ctk_MOC_SRCS}) ADD_LIBRARY(ctk ${ctk_SRCS} ${MY_MOC_CPP} ) TARGET_LINK_LIBRARIES( ctk ${QT_LIBRARIES} ) SET_TARGET_PROPERTIES( ctk PROPERTIES VERSION ${GOFIGURE2_LIB_VERSION} SOVERSION ${GOFIGURE2_LIB_VERSION} ) # Runtime INSTALL( TARGETS ctk EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} NAMELINK_SKIP COMPONENT Libraries ) # Development INSTALL( TARGETS ctk EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries NAMELINK_ONLY ) FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE( GLOB __binary_file_h "${CMAKE_CURRENT_BINARY_DIR}/*.h" ) INSTALL( FILES ${__source_file_h} ${__binary_file_h} DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Code/ExternalCode/ctk/ctkRangeSlider.h0000644000175000017500000001620711667757442022464 0ustar mathieumathieu/*========================================================================= Library: CTK Copyright (c) Kitware Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.commontk.org/LICENSE Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =========================================================================*/ #ifndef __ctkRangeSlider_h #define __ctkRangeSlider_h // Qt includes #include // CTK includes #include #include "ctkConfigure.h" class QStylePainter; class ctkRangeSliderPrivate; /// /// A ctkRangeSlider is a slider that lets you input 2 values instead of one /// (see QSlider). These values are typically a lower and upper bound. /// Values are comprised between the range of the slider. See setRange(), /// minimum() and maximum(). The upper bound can't be smaller than the /// lower bound and vice-versa. /// When setting new values (setMinimumValue(), setMaximumValue() or /// setValues()), make sure they lie between the range (minimum(), maximum()) /// of the slider, they would be forced otherwised. If it is not the behavior /// you desire, you can set the range first (setRange(), setMinimum(), /// setMaximum()) /// TODO: support triggerAction(QAbstractSlider::SliderSingleStepSub) that /// moves both values at a time. /// \sa ctkDoubleRangeSlider, ctkDoubleSlider, ctkRangeWidget class ctk_EXPORT ctkRangeSlider : public QSlider { Q_OBJECT Q_PROPERTY(int minimumValue READ minimumValue WRITE setMinimumValue) Q_PROPERTY(int maximumValue READ maximumValue WRITE setMaximumValue) Q_PROPERTY(int minimumPosition READ minimumPosition WRITE setMinimumPosition) Q_PROPERTY(int maximumPosition READ maximumPosition WRITE setMaximumPosition) Q_PROPERTY(bool symmetricMoves READ symmetricMoves WRITE setSymmetricMoves) public: // Superclass typedef typedef QSlider Superclass; /// Constructor, builds a ctkRangeSlider that ranges from 0 to 100 and has /// a lower and upper values of 0 and 100 respectively, other properties /// are set the QSlider default properties. explicit ctkRangeSlider( Qt::Orientation o, QWidget* par= 0 ); explicit ctkRangeSlider( QWidget* par = 0 ); virtual ~ctkRangeSlider(); /// /// This property holds the slider's current minimum value. /// The slider silently forces minimumValue to be within the legal range: /// minimum() <= minimumValue() <= maximumValue() <= maximum(). /// Changing the minimumValue also changes the minimumPosition. int minimumValue() const; /// /// This property holds the slider's current maximum value. /// The slider forces the maximum value to be within the legal range: /// The slider silently forces maximumValue to be within the legal range: /// Changing the maximumValue also changes the maximumPosition. int maximumValue() const; /// /// This property holds the current slider minimum position. /// If tracking is enabled (the default), this is identical to minimumValue. int minimumPosition() const; void setMinimumPosition(int min); /// /// This property holds the current slider maximum position. /// If tracking is enabled (the default), this is identical to maximumValue. int maximumPosition() const; void setMaximumPosition(int max); /// /// Utility function that set the minimum position and /// maximum position at once. void setPositions(int min, int max); /// /// When symmetricMoves is true, moving a handle will move the other handle /// symmetrically, otherwise the handles are independent. False by default bool symmetricMoves()const; void setSymmetricMoves(bool symmetry); signals: /// /// This signal is emitted when the slider minimum value has changed, /// with the new slider value as argument. void minimumValueChanged(int min); /// /// This signal is emitted when the slider maximum value has changed, /// with the new slider value as argument. void maximumValueChanged(int max); /// /// Utility signal that is fired when minimum or maximum values have changed. void valuesChanged(int min, int max); /// /// This signal is emitted when sliderDown is true and the slider moves. /// This usually happens when the user is dragging the minimum slider. /// The value is the new slider minimum position. /// This signal is emitted even when tracking is turned off. void minimumPositionChanged(int min); /// /// This signal is emitted when sliderDown is true and the slider moves. /// This usually happens when the user is dragging the maximum slider. /// The value is the new slider maximum position. /// This signal is emitted even when tracking is turned off. void maximumPositionChanged(int max); /// /// Utility signal that is fired when minimum or maximum positions /// have changed. void positionsChanged(int min, int max); public slots: /// /// This property holds the slider's current minimum value. /// The slider silently forces min to be within the legal range: /// minimum() <= min <= maximumValue() <= maximum(). /// Note: Changing the minimumValue also changes the minimumPosition. /// \sa stMaximumValue, setValues, setMinimum, setMaximum, setRange void setMinimumValue(int min); /// /// This property holds the slider's current maximum value. /// The slider silently forces max to be within the legal range: /// minimum() <= minimumValue() <= max <= maximum(). /// Note: Changing the maximumValue also changes the maximumPosition. /// \sa stMinimumValue, setValues, setMinimum, setMaximum, setRange void setMaximumValue(int max); /// /// Utility function that set the minimum value and maximum value at once. /// The slider silently forces min and max to be within the legal range: /// minimum() <= min <= max <= maximum(). /// Note: Changing the minimumValue and maximumValue also changes the /// minimumPosition and maximumPosition. /// \sa setMinimumValue, setMaximumValue, setMinimum, setMaximum, setRange void setValues(int min, int max); protected slots: void onRangeChanged(int minimum, int maximum); protected: ctkRangeSlider( ctkRangeSliderPrivate* impl, Qt::Orientation o, QWidget* par= 0 ); ctkRangeSlider( ctkRangeSliderPrivate* impl, QWidget* par = 0 ); // Description: // Standard Qt UI events virtual void mousePressEvent(QMouseEvent* ev); virtual void mouseMoveEvent(QMouseEvent* ev); virtual void mouseReleaseEvent(QMouseEvent* ev); bool isMinimumSliderDown()const; bool isMaximumSliderDown()const; // Description: // Rendering is done here. virtual void paintEvent(QPaintEvent* ev); virtual void initMinimumSliderStyleOption(QStyleOptionSlider* option) const; virtual void initMaximumSliderStyleOption(QStyleOptionSlider* option) const; protected: QScopedPointer d_ptr; private: Q_DECLARE_PRIVATE(ctkRangeSlider); Q_DISABLE_COPY(ctkRangeSlider); }; #endif GoFigure2-v0.9.0/Code/ExternalCode/ctk/ctkConfigure.h.in0000644000175000017500000000051311667757442022604 0ustar mathieumathieu#ifndef __ctkConfigure_h #define __ctkConfigure_h /* Whether we are building shared libraries. */ #if defined ( WIN32 ) && defined ( GOFIGURE2_BUILD_SHARED_LIBS ) #if defined ( ctk_EXPORTS ) #define ctk_EXPORT __declspec(dllexport) #else #define ctk_EXPORT __declspec(dllimport) #endif #else #define ctk_EXPORT #endif #endifGoFigure2-v0.9.0/Code/ExternalCode/ctk/ctkDoubleRangeSlider.h0000644000175000017500000002257711667757442023626 0ustar mathieumathieu/*========================================================================= Library: CTK Copyright (c) Kitware Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.commontk.org/LICENSE Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =========================================================================*/ #ifndef __ctkDoubleRangeSlider_h #define __ctkDoubleRangeSlider_h // Qt includes #include #include // CTK includes #include #include "ctkConfigure.h" class ctkRangeSlider; class ctkDoubleRangeSliderPrivate; /// ctkDoubleRangeSlider is a slider that controls 2 numbers as double. /// ctkDoubleRangeSlider internally aggregates a ctkRangeSlider (not in the /// API to prevent misuse). Only subclasses can have access to it. /// \sa ctkRangeSlider, ctkDoubleSlider, ctkRangeWidget class ctk_EXPORT ctkDoubleRangeSlider : public QWidget { Q_OBJECT Q_PROPERTY(double minimum READ minimum WRITE setMinimum) Q_PROPERTY(double maximum READ maximum WRITE setMaximum) Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep) Q_PROPERTY(double minimumValue READ minimumValue WRITE setMinimumValue) Q_PROPERTY(double maximumValue READ maximumValue WRITE setMaximumValue) Q_PROPERTY(double minimumPosition READ minimumPosition WRITE setMinimumPosition) Q_PROPERTY(double maximumPosition READ maximumPosition WRITE setMaximumPosition) Q_PROPERTY(bool tracking READ hasTracking WRITE setTracking) Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation) Q_PROPERTY(double tickInterval READ tickInterval WRITE setTickInterval) Q_PROPERTY(bool symmetricMoves READ symmetricMoves WRITE setSymmetricMoves) public: // Superclass typedef typedef QWidget Superclass; /// Constructor, builds a ctkDoubleRangeSlider whose default values are the same /// as ctkRangeSlider. ctkDoubleRangeSlider( Qt::Orientation o, QWidget* par= 0 ); /// Constructor, builds a ctkDoubleRangeSlider whose default values are the same /// as ctkRangeSlider. ctkDoubleRangeSlider( QWidget* par = 0 ); /// Destructor virtual ~ctkDoubleRangeSlider(); /// /// This property holds the single step. /// The smaller of two natural steps that an abstract sliders provides and /// typically corresponds to the user pressing an arrow key void setSingleStep(double ss); double singleStep()const; /// /// This property holds the interval between tickmarks. /// This is a value interval, not a pixel interval. If it is 0, the slider /// will choose between lineStep() and pageStep(). /// The default value is 0. void setTickInterval(double ti); double tickInterval()const; /// /// This property holds the sliders's minimum value. /// When setting this property, the maximum is adjusted if necessary to /// ensure that the range remains valid. Also the slider's current values /// are adjusted to be within the new range. double minimum()const; void setMinimum(double min); /// /// This property holds the slider's maximum value. /// When setting this property, the minimum is adjusted if necessary to /// ensure that the range remains valid. Also the slider's current values /// are adjusted to be within the new range. double maximum()const; void setMaximum(double max); /// /// Sets the slider's minimum to min and its maximum to max. /// If max is smaller than min, min becomes the only legal value. void setRange(double min, double max); /// /// This property holds the slider's current minimum value. /// The slider forces the minimum value to be within the legal range: /// minimum <= minvalue <= maxvalue <= maximum. /// Changing the minimumValue also changes the minimumPosition. double minimumValue() const; /// /// This property holds the slider's current maximum value. /// The slider forces the maximum value to be within the legal range: /// minimum <= minvalue <= maxvalue <= maximum. /// Changing the maximumValue also changes the maximumPosition. double maximumValue() const; /// /// This property holds the current slider minimum position. /// If tracking is enabled (the default), this is identical to minimumValue. double minimumPosition() const; void setMinimumPosition(double minPos); /// /// This property holds the current slider maximum position. /// If tracking is enabled (the default), this is identical to maximumValue. double maximumPosition() const; void setMaximumPosition(double maxPos); /// /// Utility function that set the minimum position and /// maximum position at once. void setPositions(double minPos, double maxPos); /// /// This property holds whether slider tracking is enabled. /// If tracking is enabled (the default), the slider emits the minimumValueChanged() /// signal while the left/bottom handler is being dragged and the slider emits /// the maximumValueChanged() signal while the right/top handler is being dragged. /// If tracking is disabled, the slider emits the minimumValueChanged() /// and maximumValueChanged() signals only when the user releases the slider. void setTracking(bool enable); bool hasTracking()const; /// /// Triggers a slider action on the current slider. Possible actions are /// SliderSingleStepAdd, SliderSingleStepSub, SliderPageStepAdd, /// SliderPageStepSub, SliderToMinimum, SliderToMaximum, and SliderMove. void triggerAction(QAbstractSlider::SliderAction action); /// /// This property holds the orientation of the slider. /// The orientation must be Qt::Vertical (the default) or Qt::Horizontal. Qt::Orientation orientation()const; void setOrientation(Qt::Orientation orientation); /// /// When symmetricMoves is true, moving a handle will move the other handle /// symmetrically, otherwise the handles are independent. False by default bool symmetricMoves()const; void setSymmetricMoves(bool symmetry); signals: /// /// This signal is emitted when the slider minimum value has changed, /// with the new slider value as argument. void minimumValueChanged(double minVal); /// /// This signal is emitted when the slider maximum value has changed, /// with the new slider value as argument. void maximumValueChanged(double maxVal); /// /// Utility signal that is fired when minimum or maximum values have changed. void valuesChanged(double minVal, double maxVal); /// /// This signal is emitted when sliderDown is true and the slider moves. /// This usually happens when the user is dragging the minimum slider. /// The value is the new slider minimum position. /// This signal is emitted even when tracking is turned off. void minimumPositionChanged(double minPos); /// /// This signal is emitted when sliderDown is true and the slider moves. /// This usually happens when the user is dragging the maximum slider. /// The value is the new slider maximum position. /// This signal is emitted even when tracking is turned off. void maximumPositionChanged(double maxPos); /// /// Utility signal that is fired when minimum or maximum positions /// have changed. void positionsChanged(double minPos, double maxPos); /// /// This signal is emitted when the user presses one slider with the mouse, /// or programmatically when setSliderDown(true) is called. void sliderPressed(); /// /// This signal is emitted when the user releases one slider with the mouse, /// or programmatically when setSliderDown(false) is called. void sliderReleased(); /// /// This signal is emitted when the slider range has changed, with min being /// the new minimum, and max being the new maximum. /// Warning: don't confound with valuesChanged(double, double); /// \sa QAbstractSlider::rangeChanged() void rangeChanged(double min, double max); public slots: /// /// This property holds the slider's current minimum value. /// The slider forces the minimum value to be within the legal range: /// minimum <= minvalue <= maxvalue <= maximum. /// Changing the minimumValue also changes the minimumPosition. void setMinimumValue(double minVal); /// /// This property holds the slider's current maximum value. /// The slider forces the maximum value to be within the legal range: /// minimum <= minvalue <= maxvalue <= maximum. /// Changing the maximumValue also changes the maximumPosition. void setMaximumValue(double maxVal); /// /// Utility function that set the minimum value and maximum value at once. void setValues(double minVal, double maxVal); protected slots: void onMinValueChanged(int value); void onMaxValueChanged(int value); void onValuesChanged(int min, int max); void onMinPosChanged(int value); void onMaxPosChanged(int value); void onPositionsChanged(int min, int max); void onRangeChanged(int min, int max); protected: ctkRangeSlider* slider()const; /// Subclasses can change the internal slider void setSlider(ctkRangeSlider* slider); protected: QScopedPointer d_ptr; private: Q_DECLARE_PRIVATE(ctkDoubleRangeSlider); Q_DISABLE_COPY(ctkDoubleRangeSlider); }; #endif GoFigure2-v0.9.0/Code/ExternalCode/ctk/ctkCollapsibleGroupBox.h0000644000175000017500000000727211667757442024206 0ustar mathieumathieu/*========================================================================= Library: CTK Copyright (c) Kitware Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.commontk.org/LICENSE Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =========================================================================*/ #ifndef __ctkCollapsibleGroupBox_h #define __ctkCollapsibleGroupBox_h // Qt includes #include // CTK includes #include "ctkConfigure.h" #if QT_VERSION >= 0x040600 #include //----------------------------------------------------------------------------- class ctkCollapsibleGroupBoxStyle:public QProxyStyle { public: virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption * opt, QPainter * p, const QWidget * widget = 0) const { if (pe == QStyle::PE_IndicatorCheckBox) { const QGroupBox* groupBox= qobject_cast(widget); if (groupBox) { this->QProxyStyle::drawPrimitive(groupBox->isChecked() ? QStyle::PE_IndicatorArrowUp : QStyle::PE_IndicatorArrowDown, opt, p, widget); return; } } this->QProxyStyle::drawPrimitive(pe, opt, p, widget); } }; #else #endif /// A QGroupBox with an arrow indicator that shows/hides the groupbox contents /// when clicked. It responds to the slot QGroupBox::setChecked(bool) or /// ctkCollapsibleGroupBox::setCollapsed(bool) /// When checked is true, the groupbox is expanded /// When checked is false, the groupbox is collapsed class ctk_EXPORT ctkCollapsibleGroupBox : public QGroupBox { Q_OBJECT public: ctkCollapsibleGroupBox(QWidget* parent = 0); ctkCollapsibleGroupBox(const QString& title, QWidget* parent = 0); virtual ~ctkCollapsibleGroupBox(); /// Utility function to collapse the groupbox /// Collapse(close) the group box if collapse is true, expand(open) /// it otherwise. /// \sa QGroupBox::setChecked(bool) inline void setCollapsed(bool collapse); /// Return the collapse state of the groupbox /// true if the groupbox is collapsed (closed), false if it is expanded(open) inline bool collapsed()const; /// Reimplemtented for internal reasons virtual int heightForWidth(int w) const; /// Reimplemtented for internal reasons virtual QSize minimumSizeHint()const; /// Reimplemtented for internal reasons virtual QSize sizeHint()const; protected slots: /// called when the arrow indicator is clicked /// users can call it programatically by calling setChecked(bool) virtual void expand(bool expand); protected: /// reimplemented for internal reasons virtual void childEvent(QChildEvent*); #if QT_VERSION < 0x040600 virtual void paintEvent(QPaintEvent*); virtual void mousePressEvent(QMouseEvent*); virtual void mouseReleaseEvent(QMouseEvent*); #endif virtual void resizeEvent(QResizeEvent*); private: void init(); /// Size of the widget for collapsing QSize OldSize; /// Maximum allowed height int MaxHeight; ctkCollapsibleGroupBoxStyle* Style; }; //---------------------------------------------------------------------------- bool ctkCollapsibleGroupBox::collapsed()const { return !this->isChecked(); } //---------------------------------------------------------------------------- void ctkCollapsibleGroupBox::setCollapsed(bool collapse) { this->setChecked(!collapse); } #endif GoFigure2-v0.9.0/Code/ExternalCode/ctk/ctkPimpl.h0000644000175000017500000001035511667757442021344 0ustar mathieumathieu/** \class ctkPimpl \brief Utility macros for handling private implementations. It is in addition to QtGlobal: Q_DECLARE_PRIVATE, Q_DECLARE_PUBLIC, Q_D and Q_Q. Application code generally doesn't have to be concerned about hiding its implementation details, but when writing library code it is important to maintain a constant interface, both source and binary. Maintaining a constant source interface is easy enough, but keeping the binary interface constant means moving implementation details into a private class. The PIMPL, or d-pointer, idiom is a common method of implementing this separation. ctkPimpl offers a convenient way to connect the public and private sides of your class. \section start Getting Started Before you declare the public class, you need to make a forward declaration of the private class. The private class must have the same name as the public class, followed by the word Private. \subsection pub The Public Class Generally, you shouldn't keep any data members in the public class without a good reason. Functions that are part of the public interface should be declared in the public class, and functions that need to be available to subclasses (for calling or overriding) should be in the protected section of the public class. To connect the private class to the public class, include the Q_DECLARE_PRIVATE macro in the private section of the public class. Additionally, you must construct the d_ptr pointer in the constructor of the public class. \subsection priv The Private Class As mentioned above, data members should usually be kept in the private class. This allows the memory layout of the private class to change without breaking binary compatibility for the public class. Functions that exist only as implementation details, or functions that need access to private data members, should be implemented here. To define the private class, nothing special needs to be done, except if you want the private class to have access to the public class. Then use Q_DECLARE_PUBLIC and create a public class pointer member. The constructor of the private class should take a public class reference as a parameter. \section cross Accessing Private Members Use the Q_D() macros from functions in the public class to access the private class. Similarly, functions in the private class can invoke functions in the public class by using the Q_Q() macro. */ #ifndef __ctkPimpl_h #define __ctkPimpl_h // Qt includes #include /*! \relates ctkPimpl * Define a public class constructor with no argument * * Also make sure the Pimpl is initalized */ #define CTK_CONSTRUCTOR_NO_ARG_CPP(PUB) \ PUB::PUB(): d_ptr(new PUB##Private) \ { \ } /*! \relates ctkPimpl * Define a public class constructor with one argument * * Also make sure the Pimpl is initalized */ #define CTK_CONSTRUCTOR_1_ARG_CPP(PUB, _ARG1) \ PUB::PUB(_ARG1 _parent) \ : Superclass( _parent ) \ , d_ptr(new PUB##Private) \ { \ } /*! \relates ctkPimpl * Define the setter in the public class. * * This should be put in the .cxx file of the public class. The parameter are * the name of the public class (PUB), the type of the argument to return (_TYPE), * the name of the getter(_NAME) and the name of the variable in the Private class(_VARNAME). */ #define CTK_SET_CPP(PUB, _TYPE, _NAME, _VARNAME) \ void PUB::_NAME(_TYPE var) \ { \ Q_D(PUB); \ d->_VARNAME = var; \ } /*! \relates ctkPimpl * Define the setter in the public class. * * This should be put in the .cxx file of the public class. The parameter are * the name of the public class (PUB), the type of the argument to return (_TYPE), * the name of the setter(_NAME) and the name of the variable in the Private class(_VARNAME). */ #define CTK_GET_CPP(PUB, _TYPE, _NAME, _VARNAME) \ _TYPE PUB::_NAME()const \ { \ Q_D(const PUB); \ return d->_VARNAME; \ } #endif GoFigure2-v0.9.0/Code/ExternalCode/ctk/ctkDoubleSlider.h0000644000175000017500000001544511667757442022645 0ustar mathieumathieu/*========================================================================= Library: CTK Copyright (c) Kitware Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.commontk.org/LICENSE Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =========================================================================*/ #ifndef __ctkDoubleSlider_h #define __ctkDoubleSlider_h // Qt includes #include #include // CTK includes #include #include "ctkConfigure.h" class ctkDoubleSliderPrivate; /// ctkDoubleSlider is a QSlider that controls doubles instead of integers. /// ctkDoubleSlider internally aggregates a QSlider /// TODO: ctkDoubleSlider tries to represent a double value with integers. It's /// of course non-optimal and can lead to errors, it would be better if /// ctkDoubleSlider works like QDoubleSpinBox, where the value is a QVariant /// and the conversion between double and integer is only done to convert /// to/from screen coordinates. /// \sa ctkRangeSlider, ctkDoubleRangeSlider, ctkRangeWidget class ctk_EXPORT ctkDoubleSlider : public QWidget { Q_OBJECT Q_PROPERTY(double value READ value WRITE setValue) Q_PROPERTY(double sliderPosition READ sliderPosition WRITE setSliderPosition) Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep) Q_PROPERTY(double minimum READ minimum WRITE setMinimum) Q_PROPERTY(double maximum READ maximum WRITE setMaximum) Q_PROPERTY(double tickInterval READ tickInterval WRITE setTickInterval) Q_PROPERTY(bool tracking READ hasTracking WRITE setTracking) Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation) public: /// Superclass typedef typedef QWidget Superclass; /// Constructors, builds a slider whose default values are the same as /// QSlider (vertical by default). explicit ctkDoubleSlider(QWidget* parent = 0); /// Constructors, builds a slider whose default values are the same as /// QSlider (vertical by default). explicit ctkDoubleSlider(Qt::Orientation orient, QWidget* parent = 0); /// Destructor virtual ~ctkDoubleSlider(); /// /// This property holds the sliders's minimum value. /// When setting this property, the maximum is adjusted if necessary to /// ensure that the range remains valid. Also the slider's current value /// is adjusted to be within the new range. void setMinimum(double min); double minimum()const; /// /// This property holds the slider's maximum value. /// When setting this property, the minimum is adjusted if necessary to /// ensure that the range remains valid. Also the slider's current value /// is adjusted to be within the new range. void setMaximum(double max); double maximum()const; /// /// Sets the slider's minimum to min and its maximum to max. /// If max is smaller than min, min becomes the only legal value. void setRange(double min, double max); /// /// This property holds the slider's current value. /// The slider forces the value to be within the legal range: /// minimum <= value <= maximum. /// Changing the value also changes the sliderPosition. double value()const; /// /// This property holds the single step. /// The smaller of two natural steps that an abstract sliders provides and /// typically corresponds to the user pressing an arrow key void setSingleStep(double step); double singleStep()const; /// /// This property holds the interval between tickmarks. /// This is a value interval, not a pixel interval. If it is 0, the slider /// will choose between lineStep() and pageStep(). /// The default value is 0. void setTickInterval(double ti); double tickInterval()const; /// /// This property holds the current slider position. /// If tracking is enabled (the default), this is identical to value. double sliderPosition()const; void setSliderPosition(double); /// /// This property holds whether slider tracking is enabled. /// If tracking is enabled (the default), the slider emits the valueChanged() /// signal while the slider is being dragged. If tracking is disabled, the /// slider emits the valueChanged() signal only when the user releases the /// slider. void setTracking(bool enable); bool hasTracking()const; /// /// Triggers a slider action. Possible actions are SliderSingleStepAdd, /// SliderSingleStepSub, SliderPageStepAdd, SliderPageStepSub, /// SliderToMinimum, SliderToMaximum, and SliderMove. void triggerAction(QAbstractSlider::SliderAction action); /// /// This property holds the orientation of the slider. /// The orientation must be Qt::Vertical (the default) or Qt::Horizontal. Qt::Orientation orientation()const; public slots: /// /// This property holds the slider's current value. /// The slider forces the value to be within the legal range: /// minimum <= value <= maximum. /// Changing the value also changes the sliderPosition. void setValue(double value); /// /// This property holds the orientation of the slider. /// The orientation must be Qt::Vertical (the default) or Qt::Horizontal. void setOrientation(Qt::Orientation orientation); signals: /// /// This signal is emitted when the slider value has changed, with the new /// slider value as argument. void valueChanged(double value); /// /// This signal is emitted when sliderDown is true and the slider moves. /// This usually happens when the user is dragging the slider. The value /// is the new slider position. /// This signal is emitted even when tracking is turned off. void sliderMoved(double position); /// /// This signal is emitted when the user presses the slider with the mouse, /// or programmatically when setSliderDown(true) is called. void sliderPressed(); /// /// This signal is emitted when the user releases the slider with the mouse, /// or programmatically when setSliderDown(false) is called. void sliderReleased(); /// /// This signal is emitted when the slider range has changed, with min being /// the new minimum, and max being the new maximum. /// Warning: don't confound with valuesChanged(double, double); /// \sa QAbstractSlider::rangeChanged() void rangeChanged(double min, double max); protected slots: void onValueChanged(int value); void onSliderMoved(int position); void onRangeChanged(int min, int max); protected: QScopedPointer d_ptr; private: Q_DECLARE_PRIVATE(ctkDoubleSlider); Q_DISABLE_COPY(ctkDoubleSlider); }; #endif GoFigure2-v0.9.0/Code/ExternalCode/vtkLSM/0000755000175000017500000000000011667757442020003 5ustar mathieumathieuGoFigure2-v0.9.0/Code/ExternalCode/vtkLSM/CMakeLists.txt0000644000175000017500000000261011667757442022542 0ustar mathieumathieuIF( WIN32 ) IF( NOT CYGWIN ) IF( NOT MINGW ) IF( BUILD_SHARED_LIBS ) ADD_DEFINITIONS( -DvtkLSM_EXPORT ) ENDIF( BUILD_SHARED_LIBS ) ENDIF( NOT MINGW ) ENDIF( NOT CYGWIN ) ENDIF( WIN32 ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/vtkLSMConfigure.h.in ${CMAKE_CURRENT_BINARY_DIR}/vtkLSMConfigure.h @ONLY IMMEDIATE ) ADD_LIBRARY( vtkLSMReader vtkLSMReader.cxx ) TARGET_LINK_LIBRARIES( vtkLSMReader vtkIO vtkFiltering ) SET_TARGET_PROPERTIES( vtkLSMReader PROPERTIES VERSION ${GOFIGURE2_LIB_VERSION} SOVERSION ${GOFIGURE2_LIB_VERSION} ) # Runtime INSTALL( TARGETS vtkLSMReader EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} NAMELINK_SKIP COMPONENT Libraries ) # Development INSTALL( TARGETS vtkLSMReader EXPORT GoFigure2Targets RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries NAMELINK_ONLY ) FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) INSTALL( FILES ${__source_file_h} ${GOFIGURE2_BINARY_DIR}/Code/ExternalCode/vtkLSM/vtkLSMConfigure.h DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Code/ExternalCode/vtkLSM/vtkLSMReader.h0000644000175000017500000003562011667757442022465 0ustar mathieumathieu/*========================================================================= Program: BioImageXD Module: $RCSfile: vtkLSMReader.h,v $ Language: C++ Date: $Date: 2003/08/22 14:46:02 $ Version: $Revision: 1.39 $ This is an open-source copyright as follows: Copyright (c) 2004-2008 BioImageXD Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #define TIF_NEWSUBFILETYPE 254 #define TIF_IMAGEWIDTH 256 #define TIF_IMAGELENGTH 257 #define TIF_BITSPERSAMPLE 258 #define TIF_COMPRESSION 259 #define TIF_PHOTOMETRICINTERPRETATION 262 #define TIF_STRIPOFFSETS 273 #define TIF_SAMPLESPERPIXEL 277 #define TIF_STRIPBYTECOUNTS 279 #define TIF_PLANARCONFIGURATION 284 #define TIF_PREDICTOR 317 #define TIF_COLORMAP 320 #define TIF_CZ_LSMINFO 34412 #define SUBBLOCK_END 0x0FFFFFFFF #define SUBBLOCK_RECORDING 0x010000000 #define SUBBLOCK_LASERS 0x030000000 #define SUBBLOCK_LASER 0x050000000 #define SUBBLOCK_TRACKS 0x020000000 #define SUBBLOCK_TRACK 0x040000000 #define SUBBLOCK_DETECTION_CHANNELS 0x060000000 #define SUBBLOCK_DETECTION_CHANNEL 0x070000000 #define SUBBLOCK_ILLUMINATION_CHANNELS 0x080000000 #define SUBBLOCK_ILLUMINATION_CHANNEL 0x090000000 #define SUBBLOCK_BEAM_SPLITTERS 0x0A0000000 #define SUBBLOCK_BEAM_SPLITTER 0x0B0000000 #define SUBBLOCK_DATA_CHANNELS 0x0C0000000 #define SUBBLOCK_DATA_CHANNEL 0x0D0000000 #define SUBBLOCK_TIMERS 0x011000000 #define SUBBLOCK_TIMER 0x012000000 #define SUBBLOCK_MARKERS 0x013000000 #define SUBBLOCK_MARKER 0x014000000 #define SUBBLOCK_END 0x0FFFFFFFF #define RECORDING_ENTRY_NAME 0x010000001 #define RECORDING_ENTRY_DESCRIPTION 0x010000002 #define RECORDING_ENTRY_NOTES 0x010000003 #define RECORDING_ENTRY_OBJETIVE 0x010000004 #define RECORDING_ENTRY_PROCESSING_SUMMARY 0x010000005 #define RECORDING_ENTRY_SPECIAL_SCAN_MODE 0x010000006 #define RECORDING_ENTRY_SCAN_TYPE 0x010000007 #define OLEDB_RECORDING_ENTRY_SCAN_MODE 0x010000008 #define RECORDING_ENTRY_NUMBER_OF_STACKS 0x010000009 #define RECORDING_ENTRY_LINES_PER_PLANE 0x01000000A #define RECORDING_ENTRY_SAMPLES_PER_LINE 0x01000000B #define RECORDING_ENTRY_PLANES_PER_VOLUME 0x01000000C #define RECORDING_ENTRY_IMAGES_WIDTH 0x01000000D #define RECORDING_ENTRY_IMAGES_HEIGHT 0x01000000E #define RECORDING_ENTRY_IMAGES_NUMBER_PLANES 0x01000000F #define RECORDING_ENTRY_IMAGES_NUMBER_STACKS 0x010000010 #define RECORDING_ENTRY_IMAGES_NUMBER_CHANNELS 0x010000011 #define RECORDING_ENTRY_LINSCAN_XY_SIZE 0x010000012 #define RECORDING_ENTRY_SCAN_DIRECTION 0x010000013 #define RECORDING_ENTRY_TIME_SERIES 0x010000014 #define RECORDING_ENTRY_ORIGINAL_SCAN_DATA 0x010000015 #define RECORDING_ENTRY_ZOOM_X 0x010000016 #define RECORDING_ENTRY_ZOOM_Y 0x010000017 #define RECORDING_ENTRY_ZOOM_Z 0x010000018 #define RECORDING_ENTRY_SAMPLE_0X 0x010000019 #define RECORDING_ENTRY_SAMPLE_0Y 0x01000001A #define RECORDING_ENTRY_SAMPLE_0Z 0x01000001B #define RECORDING_ENTRY_SAMPLE_SPACING 0x01000001C #define RECORDING_ENTRY_LINE_SPACING 0x01000001D #define RECORDING_ENTRY_PLANE_SPACING 0x01000001E #define RECORDING_ENTRY_PLANE_WIDTH 0x01000001F #define RECORDING_ENTRY_PLANE_HEIGHT 0x010000020 #define RECORDING_ENTRY_VOLUME_DEPTH 0x010000021 #define RECORDING_ENTRY_ROTATION 0x010000034 #define RECORDING_ENTRY_NUTATION 0x010000023 #define RECORDING_ENTRY_PRECESSION 0x010000035 #define RECORDING_ENTRY_SAMPLE_0TIME 0x010000036 #define LASER_ENTRY_NAME 0x050000001 #define LASER_ENTRY_ACQUIRE 0x050000002 #define LASER_ENTRY_POWER 0x050000003 #define DETCHANNEL_ENTRY_DETECTOR_GAIN_FIRST 0x070000003 #define DETCHANNEL_ENTRY_DETECTOR_GAIN_LAST 0x070000004 #define DETCHANNEL_ENTRY_INTEGRATION_MODE 0x070000001 #define DETCHANNEL_ENTRY_ACQUIRE 0x07000000B #define DETCHANNEL_DETECTION_CHANNEL_NAME 0x070000014 #define RECORDING_ENTRY_DESCRIPTION 0x010000002 #define ILLUMCHANNEL_ENTRY_WAVELENGTH 0x090000003 #define ILLUMCHANNEL_ENTRY_AQUIRE 0x090000004 #define ILLUMCHANNEL_DETCHANNEL_NAME 0x090000005 #define TRACK_ENTRY_ACQUIRE 0x040000006 #define TRACK_ENTRY_NAME 0x04000000C #define TYPE_SUBBLOCK 0 #define TYPE_LONG 4 #define TYPE_RATIONAL 5 #define TYPE_ASCII 2 // .NAME vtkLSMReader - read LSM files // .SECTION Description // vtkLSMReader is a source object that reads LSM files. // It should be able to read most any LSM file // // .SECTION Thanks // This class was developed as a part of the BioImageXD Project. // The BioImageXD project includes the following people: // // Dan White // Kalle Pahajoki // Pasi Kankaanp�� // #ifndef __vtkLSMReader_h #define __vtkLSMReader_h #include "vtkImageSource.h" #include "vtkImageAlgorithm.h" #include "vtkIntArray.h" #include "vtkUnsignedIntArray.h" #include "vtkUnsignedLongArray.h" #include "vtkDoubleArray.h" #include "vtkUnsignedShortArray.h" #include "vtkUnsignedCharArray.h" #include "vtkStringArray.h" #define TIFF_BYTE 1 #define TIFF_ASCII 2 #define TIFF_SHORT 3 #define TIFF_LONG 4 #define TIFF_RATIONAL 5 #define LSM_MAGIC_NUMBER 42 #define LSM_COMPRESSED 5 #define VTK_FILE_BYTE_ORDER_BIG_ENDIAN 0 #define VTK_FILE_BYTE_ORDER_LITTLE_ENDIAN 1 #include "vtkLSMConfigure.h" class VTKLSM_EXPORT vtkLSMReader:public vtkImageAlgorithm { public: static vtkLSMReader * New(); vtkTypeMacro(vtkLSMReader, vtkImageAlgorithm); virtual void PrintSelf(ostream & os, vtkIndent indent); // Description: // Get the file extensions for this format. // Returns a string with a space separated list of extensions in // the format .extension const char * GetFileExtensions() { return ".lsm .LSM"; } int GetHeaderIdentifier(); bool IsValidLSMFile(); bool IsCompressed(); int GetNumberOfTimePoints(); int GetNumberOfChannels(); int OpenFile(); int GetChannelColorComponent(int, int); char * GetChannelName(int); void SetFileName(const char *); //void ExecuteInformation(); int RequestInformation ( vtkInformation * vtkNotUsed(request), vtkInformationVector * *vtkNotUsed(inputVector), vtkInformationVector * outputVector); void SetUpdateTimePoint(int); void SetUpdateChannel(int); void SetDataByteOrderToBigEndian(); void SetDataByteOrderToLittleEndian(); void SetDataByteOrder(int); int GetDataByteOrder(); const char * GetDataByteOrderAsString(); // Description: // Set/Get the byte swapping to explicitly swap the bytes of a file. vtkSetMacro(SwapBytes, int); virtual int GetSwapBytes() { return this->SwapBytes; } vtkBooleanMacro(SwapBytes, int); int GetDataTypeForChannel(unsigned int channel); vtkGetStringMacro(Objective); vtkGetStringMacro(Description); vtkGetStringMacro(FileName); vtkGetVector3Macro(VoxelSizes, double); vtkGetVectorMacro(Dimensions, int, 5); vtkGetVectorMacro(NumberOfIntensityValues, int, 4); vtkGetVectorMacro(DataSpacing, double, 3); vtkGetMacro(Identifier, unsigned short); vtkGetMacro(NewSubFileType, unsigned int); vtkGetMacro(Compression, unsigned int); vtkGetMacro(SamplesPerPixel, unsigned int); vtkGetMacro(ScanType, unsigned short); vtkGetMacro(DataType, int); vtkGetMacro(TimeInterval, double); vtkGetObjectMacro(TimeStampInformation, vtkDoubleArray); vtkGetObjectMacro(ChannelColors, vtkIntArray); vtkGetObjectMacro(TrackWavelengths, vtkDoubleArray); unsigned int GetUpdateChannel(); vtkImageData * GetTimePointOutput(int, int); protected: vtkLSMReader(); ~vtkLSMReader(); int TIFF_BYTES(unsigned short); int BYTES_BY_DATA_TYPE(int); void ClearFileName(); void Clean(); unsigned long ReadImageDirectory(ifstream *, unsigned long); int AllocateChannelNames(int); int SetChannelName(const char *, int); int ClearChannelNames(); int FindChannelNameStart(const char *, int); int ReadChannelName(const char *, int, char *); int ReadChannelDataTypes(ifstream *, unsigned long); int ReadChannelColorsAndNames(ifstream *, unsigned long); int ReadTimeStampInformation(ifstream *, unsigned long); int ReadLSMSpecificInfo(ifstream *, unsigned long); int AnalyzeTag(ifstream *, unsigned long); int ReadScanInformation(ifstream *, unsigned long); int NeedToReadHeaderInformation(); void NeedToReadHeaderInformationOn(); void NeedToReadHeaderInformationOff(); unsigned long SeekFile(unsigned long); unsigned long GetOffsetToImage(int, int); ifstream * GetFile(); int RequestUpdateExtent( vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector); int RequestData( vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *outputVector); //void ExecuteData(vtkDataObject *out); void CalculateExtentAndSpacing(int extent[6], double spacing[3]); void DecodeHorizontalDifferencing(unsigned char *, int); void DecodeHorizontalDifferencingUnsignedShort(unsigned short *, int); void DecodeLZWCompression(unsigned char *, int); void ConstructSliceOffsets(); unsigned long GetStripByteCount(unsigned int timepoint, unsigned int slice); unsigned long GetSliceOffset(unsigned int timepoint, unsigned int slice); vtkStringArray *LaserNames; vtkDoubleArray *TrackWavelengths; vtkDoubleArray *DetectorOffsetFirstImage; vtkDoubleArray *DetectorOffsetLastImage; vtkUnsignedLongArray *ImageOffsets; vtkUnsignedLongArray *ReadSizes; vtkUnsignedIntArray *StripOffset; vtkUnsignedIntArray *ChannelDataTypes; vtkUnsignedIntArray *StripByteCount; vtkUnsignedShortArray *BitsPerSample; double VoxelSizes[3]; unsigned long OffsetToLastAccessedImage; unsigned long ColorMapOffset; unsigned long ChannelInfoOffset; unsigned long ChannelDataTypesOffset; unsigned long NumberOfLastAccessedImage; unsigned int SamplesPerPixel; unsigned int LSMSpecificInfoOffset; unsigned int NewSubFileType; unsigned int Compression; int Dimensions[5]; // x,y,z,time,channels int NumberOfIntensityValues[4]; int DataScalarType; int IntUpdateExtent[6]; int FileNameChanged; int SwapBytes; unsigned short PhotometricInterpretation; unsigned short Identifier; unsigned short PlanarConfiguration; unsigned short Predictor; unsigned short ScanType; ifstream *File; char *FileName; double DataSpacing[3]; int DataExtent[6]; int NumberOfScalarComponents; int DataType; vtkIntArray *ChannelColors; char **ChannelNames; vtkDoubleArray *TimeStampInformation; char *Objective; char *Description; double TimeInterval; unsigned char CharPointerToUnsignedChar(char *); int CharPointerToInt(char *); unsigned int CharPointerToUnsignedInt(char *); short CharPointerToShort(char *); unsigned short CharPointerToUnsignedShort(char *); double CharPointerToDouble(char *); int ReadInt(ifstream *, unsigned long &); unsigned int ReadUnsignedInt(ifstream *, unsigned long &); short ReadShort(ifstream *, unsigned long &); unsigned short ReadUnsignedShort(ifstream *, unsigned long &); double ReadDouble(ifstream *, unsigned long &); std::streamsize ReadFile(ifstream *, unsigned long &, unsigned int, char *, bool swap = false); std::streamsize ReadData(ifstream *, unsigned long &, unsigned int, char *); private: vtkLSMReader(const vtkLSMReader &); // Not implemented. void operator=(const vtkLSMReader &); // Not implemented. }; #endif GoFigure2-v0.9.0/Code/ExternalCode/vtkLSM/vtkLSMReader.cxx0000644000175000017500000014532511667757442023044 0ustar mathieumathieu/*========================================================================= Program: BioImageXD Module: $RCSfile: vtkLSMReader.cxx,v $ Language: C++ Date: $Date: 2003/08/22 14:46:02 $ Version: $Revision: 1.39 $ This is an open-source copyright as follows: Copyright (c) 2004-2008 BioImageXD Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /*========================================================================= Modifications were made by the GoFigure Dev. Team. while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkLSMReader.h" #include "vtkObjectFactory.h" #include "vtkImageData.h" #include "vtkSource.h" #include "vtkPointData.h" #include "vtkByteSwap.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkStreamingDemandDrivenPipeline.h" #include #include #define PRT_EXT(ext) ext[0], ext[1], ext[2], ext[3], ext[4], ext[5] #define PRT_EXT2(ext) ext[0] << "," << ext[1] << "," << ext[2] << "," << ext[3] << "," << ext[4] << "," << ext[5] #define CLEAR_CODE 256 #define EOI_CODE 257 //#include "lzw.h" vtkStandardNewMacro(vtkLSMReader); vtkLSMReader::vtkLSMReader() { this->SetNumberOfInputPorts(0); this->SetNumberOfOutputPorts(1); this->ChannelDataTypes = 0; this->TrackWavelengths = 0; this->ImageOffsets = 0; this->ReadSizes = NULL; this->Description = NULL; #ifdef VTK_WORDS_BIGENDIAN this->SwapBytes = true; #else this->SwapBytes = false; #endif this->Clean(); } vtkLSMReader::~vtkLSMReader() { this->ClearFileName(); this->ClearChannelNames(); this->ChannelColors->Delete(); this->BitsPerSample->Delete(); this->StripOffset->Delete(); this->StripByteCount->Delete(); this->LaserNames->Delete(); if ( this->TrackWavelengths ) { this->TrackWavelengths->Delete(); } if ( this->ChannelDataTypes ) { this->ChannelDataTypes->Delete(); } if ( this->ImageOffsets ) { this->ImageOffsets->Delete(); this->ImageOffsets = 0; this->ReadSizes->Delete(); this->ReadSizes = 0; } if ( this->TimeStampInformation ) { this->TimeStampInformation->Delete(); } if(Description) { delete[] Description; Description = NULL; } if(Objective) { delete[] Objective; Objective = NULL; } } void vtkLSMReader::ClearFileName() { if ( this->File ) { this->File->close(); delete this->File; this->File = NULL; } if ( this->FileName ) { delete[] this->FileName; this->FileName = NULL; } } //---------------------------------------------------------------------------- // This function sets the name of the file. void vtkLSMReader::SetFileName(const char *name) { if ( this->FileName && name && ( !strcmp(this->FileName, name) ) ) { return; } if ( !name && !this->FileName ) { return; } if ( this->FileName ) { delete[] this->FileName; } if ( name ) { this->FileName = new char[strlen(name) + 1]; strcpy(this->FileName, name); } else { this->FileName = NULL; } this->NeedToReadHeaderInformationOn(); this->Modified(); } void vtkLSMReader::Clean() { this->IntUpdateExtent[0] = this->IntUpdateExtent[1] = this->IntUpdateExtent[2] = this->IntUpdateExtent[4] = 0; this->IntUpdateExtent[3] = this->IntUpdateExtent[5] = 0; this->DataExtent[0] = this->DataExtent[1] = this->DataExtent[2] = this->DataExtent[4] = 0; this->DataExtent[3] = this->DataExtent[5] = 0; this->OffsetToLastAccessedImage = 0; this->NumberOfLastAccessedImage = 0; this->FileNameChanged = 0; this->FileName = NULL; this->File = NULL; this->VoxelSizes[0] = this->VoxelSizes[1] = this->VoxelSizes[2] = 0.0; this->Identifier = 0; this->LaserNames = vtkStringArray::New(); this->TrackWavelengths = vtkDoubleArray::New(); this->DataSpacing[0] = this->DataSpacing[1] = this->DataSpacing[2] = 1.0f; this->Dimensions[0] = this->Dimensions[1] = this->Dimensions[2] = this->Dimensions[3] = this->Dimensions[4] = 0; this->NewSubFileType = 0; this->BitsPerSample = vtkUnsignedShortArray::New(); this->BitsPerSample->SetNumberOfTuples(4); this->BitsPerSample->SetNumberOfComponents(1); this->Compression = 0; this->StripOffset = vtkUnsignedIntArray::New(); this->StripOffset->SetNumberOfTuples(4); this->StripOffset->SetNumberOfComponents(1); this->SamplesPerPixel = 0; this->StripByteCount = vtkUnsignedIntArray::New(); this->StripByteCount->SetNumberOfTuples(4); this->StripByteCount->SetNumberOfComponents(1); this->Predictor = 0; this->PhotometricInterpretation = 0; this->PlanarConfiguration = 0; this->ColorMapOffset = 0; this->LSMSpecificInfoOffset = 0; this->NumberOfIntensityValues[0] = this->NumberOfIntensityValues[1] = this->NumberOfIntensityValues[2] = this->NumberOfIntensityValues[3] = 0; this->ScanType = 0; this->DataType = 0; this->ChannelColors = vtkIntArray::New(); this->ChannelNames = NULL; this->TimeStampInformation = vtkDoubleArray::New(); } int vtkLSMReader::OpenFile() { if ( !this->FileName ) { vtkErrorMacro(<< "FileName must be specified."); return 0; } // Close file from any previous image if ( this->File ) { this->File->close(); delete this->File; this->File = NULL; } // Open the new file #ifdef _WIN32 this->File = new ifstream(this->FileName, ios::in | ios::binary); #else this->File = new ifstream(this->FileName, ios::in); #endif if ( !this->File || this->File->fail() ) { vtkErrorMacro(<< "OpenFile: Could not open file " << this->FileName); return 0; } return 1; } void vtkLSMReader::SetDataByteOrderToBigEndian() { #ifndef VTK_WORDS_BIGENDIAN this->SwapBytesOn(); #else this->SwapBytesOff(); #endif } void vtkLSMReader::SetDataByteOrderToLittleEndian() { #ifdef VTK_WORDS_BIGENDIAN this->SwapBytesOn(); #else this->SwapBytesOff(); #endif } void vtkLSMReader::SetDataByteOrder(int byteOrder) { if ( byteOrder == VTK_FILE_BYTE_ORDER_BIG_ENDIAN ) { this->SetDataByteOrderToBigEndian(); } else { this->SetDataByteOrderToLittleEndian(); } } int vtkLSMReader::GetDataByteOrder() { #ifdef VTK_WORDS_BIGENDIAN if ( this->SwapBytes ) { return VTK_FILE_BYTE_ORDER_LITTLE_ENDIAN; } else { return VTK_FILE_BYTE_ORDER_BIG_ENDIAN; } #else if ( this->SwapBytes ) { return VTK_FILE_BYTE_ORDER_BIG_ENDIAN; } else { return VTK_FILE_BYTE_ORDER_LITTLE_ENDIAN; } #endif } const char * vtkLSMReader::GetDataByteOrderAsString() { #ifdef VTK_WORDS_BIGENDIAN if ( this->SwapBytes ) { return "LittleEndian"; } else { return "BigEndian"; } #else if ( this->SwapBytes ) { return "BigEndian"; } else { return "LittleEndian"; } #endif } char * vtkLSMReader::GetChannelName(int chNum) { if ( !this->ChannelNames || chNum < 0 || chNum > this->GetNumberOfChannels() - 1 ) { vtkDebugMacro(<< "GetChannelName: Illegal channel index!"); //NOTE: would be much easier to return a const char* return const_cast< char * >( std::string("").c_str() ); } return this->ChannelNames[chNum]; } int vtkLSMReader::ClearChannelNames() { vtkDebugMacro(<< "clearing " << this->GetNumberOfChannels() << "channel names"); if ( !this->ChannelNames || this->GetNumberOfChannels() < 1 ) { return 0; } for ( int i = 0; i < this->GetNumberOfChannels(); i++ ) { delete[] this->ChannelNames[i]; } vtkDebugMacro(<< "almost done\n"); delete[] this->ChannelNames; vtkDebugMacro(<< "done"); return 0; } int vtkLSMReader::AllocateChannelNames(int chNum) { this->ClearChannelNames(); vtkDebugMacro(<< "allocating space for " << chNum << "channel names"); this->ChannelNames = new char *[chNum]; if ( !this->ChannelNames ) { vtkErrorMacro(<< "Could not allocate memory for channel name table!"); return 1; } for ( int i = 0; i < chNum; i++ ) { this->ChannelNames[i] = NULL; } return 0; } int vtkLSMReader::SetChannelName(const char *chName, int chNum) { char *name; if ( !chName || chNum > this->GetNumberOfChannels() ) { return 0; } if ( !this->ChannelNames ) { this->AllocateChannelNames( this->GetNumberOfChannels() ); } size_t length = strlen(chName); vtkDebugMacro(<< "length=" << length); name = new char[length + 1]; if ( !name ) { vtkErrorMacro(<< "Could not allocate memory for channel name"); return 1; } strncpy(name, chName, length); name[length] = 0; this->ChannelNames[chNum] = name; return 0; } int vtkLSMReader::FindChannelNameStart(const char *nameBuff, int length) { int i; char ch; for ( i = 0; i < length; i++ ) { ch = *( nameBuff + i ); if ( ch > 32 ) { break; } } if ( i >= length ) { vtkWarningMacro(<< "Start of the channel name may not be found!"); } return i; } int vtkLSMReader::ReadChannelName(const char *nameBuff, int length, char *buffer) { int i; char component; for ( i = 0; i < length; i++ ) { component = *( nameBuff + i ); *( buffer + i ) = component; if ( component == 0 ) { break; } } return i; } int vtkLSMReader::ReadChannelDataTypes(ifstream *f, unsigned long start) { unsigned long pos; unsigned int dataType; pos = start; unsigned int numOfChls = this->GetNumberOfChannels(); this->ChannelDataTypes = vtkUnsignedIntArray::New(); this->ChannelDataTypes->SetNumberOfTuples(numOfChls); this->ChannelDataTypes->SetNumberOfComponents(1); for ( unsigned int i = 0; i < numOfChls; i++ ) { dataType = this->ReadUnsignedInt(f, pos); this->ChannelDataTypes->SetValue(i, dataType); vtkDebugMacro(<< "Channel " << i << " has datatype " << dataType << "\n"); } return 0; } int vtkLSMReader::ReadChannelColorsAndNames(ifstream *f, unsigned long start) { int colNum, nameNum, sizeOfStructure, sizeOfNames, nameLength, nameSkip; unsigned long colorOffset, nameOffset, pos; char * nameBuff, *colorBuff, *name, *tempBuff; unsigned char component; colorBuff = new char[5]; pos = start; // Read size of structure sizeOfStructure = this->ReadInt(f, pos); //vtkDebugMacro(<<"size of structure = "<ReadInt(f, pos); // Read number of names nameNum = this->ReadInt(f, pos); //vtkDebugMacro(<<"nameNum="<GetNumberOfChannels() ) { vtkDebugMacro(<< "Number of channel colors is not same as number of channels!"); vtkDebugMacro(<< "numColors=" << colNum << ", numChls=" << this->GetNumberOfChannels() << ", numNames=" << nameNum); } if ( nameNum != this->GetNumberOfChannels() ) { vtkDebugMacro(<< "Number of channel names is not same as number of channels!"); vtkDebugMacro(<< "numColors=" << colNum << ", numChls=" << this->GetNumberOfChannels() << ", numNames=" << nameNum); } // Read offset to color info colorOffset = this->ReadInt(f, pos) + start; // Read offset to name info nameOffset = this->ReadInt(f, pos) + start; vtkDebugMacro(<< "colorOffset=" << colorOffset); vtkDebugMacro(<< "nameOffset=" << nameOffset); vtkDebugMacro(<< "number of colors" << colNum); this->ChannelColors->Reset(); this->ChannelColors->SetNumberOfValues( 3 * ( colNum + 1 ) ); this->ChannelColors->SetNumberOfComponents(3); // Read the colors for ( int j = 0; j < this->GetNumberOfChannels(); j++ ) { this->ReadFile(f, colorOffset, 4, colorBuff, 1); for ( int i = 0; i < 3; i++ ) { component = this->CharPointerToUnsignedChar(colorBuff + i); this->ChannelColors->SetValue(i + ( 3 * j ), component); } } this->ReadFile(f, nameOffset, sizeOfNames, nameBuff, 1); nameLength = nameSkip = 0; tempBuff = nameBuff; for ( int i = 0; i < this->GetNumberOfChannels(); i++ ) { nameSkip = this->FindChannelNameStart(tempBuff, sizeOfNames - nameSkip); nameLength = this->ReadChannelName(tempBuff + nameSkip, sizeOfNames - nameSkip, name); tempBuff += nameSkip + nameLength; vtkDebugMacro(<< "Setting channel " << i << "name"); this->SetChannelName(name, i); } delete[] nameBuff; delete[] name; delete[] colorBuff; return 0; } int vtkLSMReader::ReadTimeStampInformation(ifstream *f, unsigned long offset) { int numOffStamps = 0; if ( offset == 0 ) // position is 0 for non-timeseries files! { vtkDebugMacro(<< "No timestamp information available"); return 0; } offset += 4; numOffStamps = this->ReadInt(f, offset); vtkDebugMacro(<< "There are " << numOffStamps << " stamps available"); if ( numOffStamps != this->GetNumberOfTimePoints() ) { // vtkWarningMacro(<<"Number of time stamps does not correspond to the number // off time points!"); } this->TimeStampInformation->Reset(); this->TimeStampInformation->SetNumberOfTuples(numOffStamps); this->TimeStampInformation->SetNumberOfComponents(1); for ( int i = 0; i < numOffStamps; i++ ) { this->TimeStampInformation->SetValue( i, this->ReadDouble(f, offset) ); } return 0; } /* Read the TIF_CZ_LSMINFO entry described in Table 17 of the LSM file format specification * * */ int vtkLSMReader::ReadLSMSpecificInfo(ifstream *f, unsigned long pos) { unsigned long offset; vtkDebugMacro("ReadLSMSpecificInfo(stream," << pos << ")\n"); pos += 2 * 4; // skip over the start of the LSMInfo // first 4 byte entry if magic number // second is number of bytes in this structure // Then we read X this->NumberOfIntensityValues[0] = this->ReadInt(f, pos); // vtkByteSwap::Swap4LE((int*)&this->NumberOfIntensityValues[0]); this->Dimensions[0] = this->NumberOfIntensityValues[0]; // Y this->NumberOfIntensityValues[1] = this->ReadInt(f, pos); this->Dimensions[1] = this->NumberOfIntensityValues[1]; // and Z dimension this->NumberOfIntensityValues[2] = this->ReadInt(f, pos); this->Dimensions[2] = this->NumberOfIntensityValues[2]; vtkDebugMacro(<< "Dimensions =" << Dimensions[0] << "," << Dimensions[1] << "," << Dimensions[2] << "\n"); // Read number of channels this->Dimensions[4] = this->ReadInt(f, pos); vtkDebugMacro(<< "Number of Channels" << this->Dimensions[4] << "\n"); // Read number of timepoints this->NumberOfIntensityValues[3] = this->ReadInt(f, pos); this->Dimensions[3] = this->NumberOfIntensityValues[3]; // Read datatype, 1 for 8-bit unsigned int // 2 for 12-bit unsigned int // 5 for 32-bit float (timeseries mean of ROIs) // 0 if the channels have different types // In that case, u32OffsetChannelDataTypes // has further info this->DataType = this->ReadInt(f, pos); vtkDebugMacro(<< "Data type=" << this->DataType << "\n"); // Skip the width and height of thumbnails pos += 2 * 4; // Read voxel sizes this->VoxelSizes[0] = this->ReadDouble(f, pos); this->VoxelSizes[1] = this->ReadDouble(f, pos); this->VoxelSizes[2] = this->ReadDouble(f, pos); vtkDebugMacro("Voxel size=" << VoxelSizes[0] << "," << VoxelSizes[1] << "," << VoxelSizes[2] << "\n"); // Skip over OriginX,OriginY,OriginZ which are not used pos += 3 * 8; // Read scan type which is // 0 for normal x-y-z scan // 1 for z-scan (x-z plane) // 2 for line scan // 3 for time series x-y // 4 for time series x-z // 5 time series mean of ROIs // 6 time series x y z // 7 spline scan // 8 spline plane x-z // 9 time series spline plane // 10 point mode this->ScanType = this->ReadShort(f, pos); vtkDebugMacro("ScanType" << this->ScanType << "\n"); // skip over SpectralScan flag // if 0, no spectral scan // if 1, image has been acquired with spectral scan mode with a "meta" // detector // skip over DataType, Offset to vector overlay, Offset to input LUT pos += 1 * 2 + 4 * 4; // + 1*8 + 3*4; // Read OffsetChannelColors, which is an offset to channel colors and names this->ChannelInfoOffset = this->ReadUnsignedInt(f, pos); vtkDebugMacro(<< "Channel info offset (from addr" << pos << ")=" << this->ChannelInfoOffset << "\n"); this->ReadChannelColorsAndNames(f, this->ChannelInfoOffset); // Skip time interval in seconds (8 bytes) //pos += 1*8; this->TimeInterval = this->ReadDouble(f, pos); printf("Time interval = %f\n", this->TimeInterval); // If each channel has different datatype (meaning DataType == 0), then // read the offset to more information and read the info this->ChannelDataTypesOffset = this->ReadInt(f, pos); unsigned long scanInformationOffset = this->ReadUnsignedInt(f, pos); if ( this->DataType == 0 ) { this->ReadChannelDataTypes(f, this->ChannelDataTypesOffset); } // Read scan information printf("Scan information offset = %ld\n", scanInformationOffset); this->ReadScanInformation(f, scanInformationOffset); // SKip Zeiss Vision KS-3D speific data pos += 4; // Read timestamp information offset = this->ReadUnsignedInt(f, pos); this->ReadTimeStampInformation(f, offset); return 1; } int vtkLSMReader::ReadScanInformation(ifstream *f, unsigned long pos) { unsigned int entry, type, size; unsigned int subblocksOpen = 0; char * name; double wavelength = 0.; char * chName; int chIsOn = 0, trackIsOn = 0, isOn = 0; while ( 1 ) { entry = this->ReadUnsignedInt(f, pos); type = this->ReadUnsignedInt(f, pos); size = this->ReadUnsignedInt(f, pos); //printf("entry=%d\n", entry); if ( type == TYPE_SUBBLOCK && entry == SUBBLOCK_END ) { subblocksOpen--; } else if ( type == TYPE_SUBBLOCK ) { subblocksOpen++; } switch ( entry ) { case DETCHANNEL_ENTRY_DETECTOR_GAIN_FIRST: this->ReadDouble(f, pos); // double gain continue; break; case DETCHANNEL_ENTRY_DETECTOR_GAIN_LAST: this->ReadDouble(f, pos); // double gain continue; break; case DETCHANNEL_ENTRY_INTEGRATION_MODE: this->ReadInt(f, pos); // int mode continue; break; case LASER_ENTRY_NAME: name = new char[size + 1]; this->ReadData(f, pos, size, name); //printf("Laser name: %s\n", name); this->LaserNames->InsertNextValue(name); delete[] name; continue; break; case ILLUMCHANNEL_ENTRY_WAVELENGTH: wavelength = this->ReadDouble(f, pos); continue; break; case ILLUMCHANNEL_DETCHANNEL_NAME: chName = new char[size + 1]; this->ReadData(f, pos, size, chName); // printf("chName = %s\n", chName); delete[] chName; continue; break; case TRACK_ENTRY_ACQUIRE: trackIsOn = this->ReadInt(f, pos); continue; break; case TRACK_ENTRY_NAME: chName = new char[size + 1]; this->ReadData(f, pos, size, chName); if ( trackIsOn ) { // printf("Track name = %s is on\n", chName); } delete[] chName; continue; break; case DETCHANNEL_DETECTION_CHANNEL_NAME: chName = new char[size + 1]; this->ReadData(f, pos, size, chName); if ( chIsOn ) { //printf("Detection channel name = %s is on\n", chName); } delete[] chName; continue; break; case DETCHANNEL_ENTRY_ACQUIRE: chIsOn = this->ReadInt(f, pos); continue; break; case ILLUMCHANNEL_ENTRY_AQUIRE: isOn = this->ReadInt(f, pos); if ( isOn ) { if ( trackIsOn ) { this->TrackWavelengths->InsertNextValue(wavelength); //printf("Acquired using wavelength: %f\n", wavelength); } } continue; break; case RECORDING_ENTRY_DESCRIPTION: Description = new char[size + 1]; this->ReadData(f, pos, size, Description); // printf("Description: %s\n", Description); continue; break; case RECORDING_ENTRY_OBJETIVE: Objective = new char[size + 1]; this->ReadData(f, pos, size, Objective); continue; case SUBBLOCK_RECORDING: break; case SUBBLOCK_LASERS: break; case SUBBLOCK_LASER: break; case SUBBLOCK_TRACKS: break; case SUBBLOCK_TRACK: break; case SUBBLOCK_DETECTION_CHANNELS: break; case SUBBLOCK_DETECTION_CHANNEL: break; case SUBBLOCK_ILLUMINATION_CHANNELS: break; case SUBBLOCK_ILLUMINATION_CHANNEL: break; case SUBBLOCK_BEAM_SPLITTERS: break; case SUBBLOCK_BEAM_SPLITTER: break; case SUBBLOCK_DATA_CHANNELS: break; case SUBBLOCK_DATA_CHANNEL: break; case SUBBLOCK_TIMERS: break; case SUBBLOCK_TIMER: break; case SUBBLOCK_MARKERS: break; case SUBBLOCK_MARKER: break; } if ( subblocksOpen == 0 ) { break; } // By default, skip the entry pos += size; } return 0; } int vtkLSMReader::AnalyzeTag(ifstream *f, unsigned long startPos) { char tempValue[4], tempValue2[4]; char *actualValue = NULL; //vtkDebugMacro(<<"Analyze tag start pos="<ReadUnsignedShort(f, startPos); unsigned short type = this->ReadUnsignedShort(f, startPos); unsigned int length = this->ReadUnsignedInt(f, startPos); this->ReadFile(f, startPos, 4, tempValue); unsigned int i; for ( i = 0; i < 4; i++ ) { tempValue2[i] = tempValue[i]; } #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap4LE( (unsigned int *)tempValue2 ); #endif unsigned int value = this->CharPointerToUnsignedInt(tempValue2); // if there is more than 4 bytes in value, // value is an offset to the actual data int dataSize = this->TIFF_BYTES(type); unsigned int readSize = dataSize * length; if ( readSize > 4 && tag != TIF_CZ_LSMINFO ) { actualValue = new char[readSize]; startPos = value; if ( tag == TIF_STRIPOFFSETS || tag == TIF_STRIPBYTECOUNTS ) { // vtkDebugMacro(<<"Reading actual value from "<ReadFile(f, startPos, readSize, actualValue) == 0 ) { vtkErrorMacro(<< "Failed to get strip offsets\n"); return 0; } } } else { actualValue = new char[4]; for ( int o = 0; o < 4; o++ ) { actualValue[o] = tempValue[o]; } } switch ( tag ) { case TIF_NEWSUBFILETYPE: // vtkDebugMacro(<<"New subfile type="<NewSubFileType = value; break; case TIF_IMAGEWIDTH: #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap4LE( (unsigned int *)actualValue ); vtkDebugMacro(<< "Image width=" << value); #endif //this->Dimensions[0] = this->CharPointerToUnsignedInt(actualValue); //this->Dimensions[0] = value; break; case TIF_IMAGELENGTH: #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap4LE( (unsigned int *)actualValue ); //this->Dimensions[1] = this->CharPointerToUnsignedInt(actualValue); vtkDebugMacro(<< "Image length=" << value); #endif //this->Dimensions[1] = value; break; case TIF_BITSPERSAMPLE: #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap2LE( (unsigned short *)actualValue ); #endif this->BitsPerSample->SetNumberOfValues(length); unsigned short bitsPerSample; for ( i = 0; i < length; i++ ) { bitsPerSample = this->CharPointerToUnsignedShort( actualValue + ( this->TIFF_BYTES(TIFF_SHORT) * i ) ); this->BitsPerSample->SetValue(i, bitsPerSample); } break; case TIF_COMPRESSION: #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap2LE( (unsigned short *)actualValue ); #endif this->Compression = this->CharPointerToUnsignedShort(actualValue); break; case TIF_PHOTOMETRICINTERPRETATION: #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap2LE( (unsigned short *)actualValue ); #endif this->PhotometricInterpretation = this->CharPointerToUnsignedShort(actualValue); break; case TIF_STRIPOFFSETS: // vtkDebugMacro(<<"Number of values="<StripOffset->SetNumberOfValues(length); #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap4LERange( (unsigned int *)actualValue, length ); #endif if ( length > 1 ) { unsigned int *offsets = static_cast< unsigned int * >( static_cast< void * >( actualValue ) ); for ( i = 0; i < length; i++ ) { /// \bug here for large files stripOffset is screwed unsigned int stripOffset = offsets[i]; // vtkDebugMacro(<<"Strip offset to "<StripOffset->SetValue(i, stripOffset); } } else { // vtkDebugMacro(<<"Strip offset to only channel="<StripOffset->SetValue(0, value); } break; case TIF_SAMPLESPERPIXEL: #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap4LE( (unsigned int *)actualValue ); #endif this->SamplesPerPixel = this->CharPointerToUnsignedInt(actualValue); // vtkDebugMacro(<<"Samples per pixel="<StripByteCount->SetNumberOfValues(length); if ( length > 1 ) { for ( i = 0; i < length; i++ ) { // unsigned int* counts = (unsigned int*)actualValue; unsigned int bytecount = this->CharPointerToUnsignedInt( actualValue + ( this->TIFF_BYTES(TIFF_LONG) * i ) ); this->StripByteCount->SetValue(i, bytecount); // vtkDebugMacro(<<"Strip byte count of " << i <<"="<ReadSizes->GetValue(timepoint * this->Dimensions[2] + slice); } unsigned long vtkLSMReader::GetSliceOffset(unsigned int timepoint, unsigned int slice) { if ( !this->ImageOffsets ) { vtkErrorMacro(<< "Request slice offset but table not constructed\n"); return 0; } return this->ImageOffsets->GetValue(timepoint * this->Dimensions[2] + slice); } void vtkLSMReader::ConstructSliceOffsets() { // unsigned long int startPos = 2; if ( !this->ImageOffsets ) { this->ImageOffsets = vtkUnsignedLongArray::New(); this->ReadSizes = vtkUnsignedLongArray::New(); int length = this->Dimensions[2] * this->Dimensions[3]; this->ImageOffsets->SetNumberOfTuples(length); this->ReadSizes->SetNumberOfTuples(length); for ( int j = 0; j < length; j++ ) { this->ImageOffsets->SetValue(j, 0); this->ReadSizes->SetValue(j, 0); } } int channel = this->GetUpdateChannel(); unsigned long temp, offset, readSize; for ( int tp = 0; tp < this->Dimensions[3]; tp++ ) { for ( int slice = 0; slice < this->Dimensions[2]; slice++ ) { temp = tp * this->Dimensions[2] + slice; this->GetOffsetToImage(slice, tp); offset = this->StripOffset->GetValue(channel); readSize = this->StripByteCount->GetValue(channel); this->ImageOffsets->SetValue(temp, offset); this->ReadSizes->SetValue(temp, readSize); } } } unsigned long vtkLSMReader::GetOffsetToImage(int slice, int timepoint) { unsigned long temp = slice + ( timepoint * this->Dimensions[2] ); return this->SeekFile(temp); } unsigned long vtkLSMReader::SeekFile(unsigned long image) { unsigned long offset = 4, finalOffset; // int readSize = 4; unsigned long i = 0; //unsigned short numberOfTags = 0; unsigned long imageCount = image + 1; if ( this->OffsetToLastAccessedImage && ( this->NumberOfLastAccessedImage < image ) ) { offset = this->OffsetToLastAccessedImage; imageCount = image - this->NumberOfLastAccessedImage; // vtkDebugMacro(<<"offset of last image: // "<ReadInt(this->GetFile(), offset); vtkDebugMacro(<< "offset (from file): " << offset << "\n"); } offset = this->ReadImageDirectory(this->GetFile(), offset); // vtkDebugMacro(<<"Offset: "<NewSubFileType == 0 ) { i++; } finalOffset = offset; offset = this->ReadImageDirectory(this->GetFile(), offset); //vtkDebugMacro(<<"i="<OffsetToLastAccessedImage = finalOffset; this->NumberOfLastAccessedImage = image; return finalOffset; } unsigned long vtkLSMReader::ReadImageDirectory(ifstream *f, unsigned long offset) { unsigned short numberOfTags = 0; unsigned long nextOffset = offset; //vtkDebugMacro(<<"Reading unsigned short from "<ReadUnsignedShort(f, offset); for ( int i = 0; i < numberOfTags; i++ ) { this->AnalyzeTag(f, offset); //vtkDebugMacro(<<"Tag analyed...\n"); if ( this->NewSubFileType == 1 ) { //vtkDebugMacro(<<"Found thumbnail, get next"); break; //thumbnail image } offset = offset + 12; //vtkDebugMacro(<<"New offset="<ReadUnsignedInt(f, nextOffset); } void vtkLSMReader::DecodeHorizontalDifferencing(unsigned char *buffer, int size) { // std::cout <<"DecodeHorizontalDifferencing " <Dimensions[0]; int channel = this->GetUpdateChannel(); int bytes = this->BYTES_BY_DATA_TYPE(this->GetDataTypeForChannel(channel)); int lines = size / (width*bytes); lzw_decode_init(s, 8, bufp, size); vtkDebugMacro(<<"Size: "<Predictor == 2) { if(bytes == 1) { this->DecodeHorizontalDifferencing(outbufp,width*bytes); } else { this->DecodeHorizontalDifferencingUnsignedShort( static_cast(static_cast(outbufp)), width ); } } outbufp += width*bytes; } for(int i=0;i < size;i++) { buffer[i] = outbuf[i]; } vtkDebugMacro(<<"Decoding done"<<"\n"); delete s; delete []outbuf; */ } int vtkLSMReader::GetDataTypeForChannel(unsigned int channel) { if ( this->DataType != 0 ) { return this->DataType; } if ( !this->ChannelDataTypes ) { return 1; } return this->ChannelDataTypes->GetValue(channel); } //---------------------------------------------------------------------------- // Convert to Imaging API int vtkLSMReader::RequestData( vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *outputVector) { unsigned long offset; //, imageOffset;; int outExtent[6]; if ( !this->ImageOffsets ) { vtkDebugMacro(<< "Constructing slice offset table\n"); this->ConstructSliceOffsets(); } // get the info object vtkInformation *outInfo = outputVector->GetInformationObject(0); vtkImageData * data = this->AllocateOutputData( outInfo->Get( vtkDataObject::DATA_OBJECT() ) ); data->GetPointData()->GetScalars()->SetName("LSM Scalars"); data->GetExtent(outExtent); if ( !this->Identifier ) { vtkDebugMacro(<< "Can not execute data since information has not been executed!"); return 0; } vtkDebugMacro( << "Update extent: " << outExtent[0] << ", " << outExtent[1] << ", " << outExtent[2] << ", " << outExtent[3] << ", " << outExtent[4] << "," << outExtent[5] << "\n"); // if given time point or channel index is bigger than maximum, // we use maximum int timepoint = ( this->IntUpdateExtent[3] > ( this->GetNumberOfTimePoints() - 1 ) ? this->GetNumberOfTimePoints() - 1 : this->IntUpdateExtent[3] ); int channel = this->GetUpdateChannel(); // int nSlices = (outExtent[5]-outExtent[4])+1; // std::cout <<"Timepoint="<Dimensions[0] * this->Dimensions[1] * ( outExtent[5] - outExtent[4] + 1 ); int dataType = this->GetDataTypeForChannel(channel); unsigned int size = numberOfPixels * this->BYTES_BY_DATA_TYPE(dataType); vtkDebugMacro( << "numberOfPixels=" << numberOfPixels << ", buffer size=" << size << ", datatype=" << dataType << ", bytes by datatype=" << this->BYTES_BY_DATA_TYPE(dataType) << "\n"); // this buffer will be deleted by the vtkXXXArray when the array is destroyed. unsigned char *buf = new unsigned char[size]; unsigned char *tempBuf = buf; unsigned int readSize; time_t start = time (NULL); for ( int i = outExtent[4]; i <= outExtent[5]; ++i ) { offset = this->GetSliceOffset(timepoint, i); readSize = static_cast< unsigned int >( this->GetStripByteCount(timepoint, i) ); vtkDebugMacro( << "Offset to tp " << timepoint << ", slice " << i << " = " << offset << ", strip byte count: " << readSize << "\n"); for ( unsigned long ii = 0; ii < readSize; ii++ ) { tempBuf[ii] = 0; } std::streamsize bytes = this->ReadFile(this->GetFile(), offset, readSize, static_cast< char * >( static_cast< void * >( tempBuf ) ), 1); if ( static_cast< unsigned int >( bytes ) != readSize ) { vtkDebugMacro(<< "Asked for " << readSize << " bytes, got " << bytes << "\n"); vtkDebugMacro(<< "File status: fail: " << this->GetFile()->fail() << ", eof: " << this->GetFile()->eof() << "\n"); this->GetFile()->clear(); } if ( this->IsCompressed() ) { this->DecodeLZWCompression(tempBuf, readSize); } tempBuf += readSize; } time_t end = time (NULL); (void) start; (void) end; vtkDebugMacro(<< "Dataset generation time: " << end - start); vtkUnsignedCharArray * uscarray; vtkUnsignedShortArray *ussarray; if ( this->BYTES_BY_DATA_TYPE(dataType) > 1 ) { ussarray = vtkUnsignedShortArray::New(); ussarray->SetNumberOfComponents(1); ussarray->SetNumberOfValues(numberOfPixels); ussarray->SetArray(static_cast< unsigned short * >( static_cast< void * >( buf ) ), numberOfPixels, 0); data->GetPointData()->SetScalars(ussarray); ussarray->Delete(); } else { uscarray = vtkUnsignedCharArray::New(); uscarray->SetNumberOfComponents(1); uscarray->SetNumberOfValues(numberOfPixels); uscarray->SetArray(buf, numberOfPixels, 0); data->GetPointData()->SetScalars(uscarray); uscarray->Delete(); } return 1; } int vtkLSMReader::RequestUpdateExtent( vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) { (void)request; (void)inputVector; int uext[6], ext[6]; vtkInformation *outInfo = outputVector->GetInformationObject(0); //vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), ext); // Get the requested update extent from the output. outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), uext); // If they request an update extent that doesn't cover the whole slice // then modify the uextent if ( uext[1] < ext[1] ) { uext[1] = ext[1]; } if ( uext[3] < ext[3] ) { uext[3] = ext[3]; } outInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), uext, 6); //request->Set(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT(), // uext,6); return 1; } int vtkLSMReader::RequestInformation( vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *outputVector) { unsigned long startPos; unsigned int imageDirOffset; int dataType; // char buf[12]; vtkInformation *outInfo = outputVector->GetInformationObject(0); this->SetDataByteOrderToLittleEndian(); if ( !this->NeedToReadHeaderInformation() ) { vtkDebugMacro(<< "Don't need to read header information"); return 1; } vtkDebugMacro(<< "Executing information."); if ( !this->OpenFile() ) { this->Identifier = 0; return 0; } startPos = 2; // header identifier this->Identifier = this->ReadUnsignedShort(this->GetFile(), startPos); if ( !this->IsValidLSMFile() ) { vtkErrorMacro("Given file is not a valid LSM-file."); return 0; } imageDirOffset = this->ReadUnsignedInt(this->GetFile(), startPos); this->ReadImageDirectory(this->GetFile(), imageDirOffset); if ( this->LSMSpecificInfoOffset ) { ReadLSMSpecificInfo( this->GetFile(), static_cast< unsigned long >( this->LSMSpecificInfoOffset ) ); } else { vtkErrorMacro("Did not found LSM specific info!"); return 0; } if ( !( this->ScanType == 6 || this->ScanType == 0 || this->ScanType == 3 ) ) { vtkErrorMacro( "Sorry! Your LSM-file must be of type 6 LSM-file (time series x-y-z) or type 0 (normal x-y-z) or type 3 (2D + time). Type of this File is " << this->ScanType); return 0; } vtkDebugMacro(<< "Executing information: first directory has been read."); this->CalculateExtentAndSpacing(this->DataExtent, this->DataSpacing); outInfo->Set(vtkDataObject::SPACING(), this->DataSpacing, 3); outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), this->DataExtent, 6); this->NumberOfScalarComponents = 1; int channel = this->GetUpdateChannel(); dataType = this->GetDataTypeForChannel(channel); if ( dataType > 1 ) { this->DataScalarType = VTK_UNSIGNED_SHORT; } else { this->DataScalarType = VTK_UNSIGNED_CHAR; } vtkDataObject::SetPointDataActiveScalarInfo(outInfo, this->DataScalarType, this->NumberOfScalarComponents); this->NeedToReadHeaderInformationOff(); vtkDebugMacro(<< "Executing information: executed."); return 1; } void vtkLSMReader::CalculateExtentAndSpacing(int extent[6], double spacing[3]) { extent[0] = extent[2] = extent[4] = 0; extent[1] = this->Dimensions[0] - 1; extent[3] = this->Dimensions[1] - 1; extent[5] = this->Dimensions[2] - 1; spacing[0] = this->VoxelSizes[0] * 1000000; spacing[1] = this->VoxelSizes[1] * 1000000; spacing[2] = this->VoxelSizes[2] * 1000000; } //------------------------------------------------------------------------- int vtkLSMReader::GetChannelColorComponent(int ch, int component) { if ( ch < 0 || ch > this->GetNumberOfChannels() - 1 || component < 0 || component > 2 ) { return 0; } return *( this->ChannelColors->GetPointer( ( ch * 3 ) + component ) ); } vtkImageData * vtkLSMReader::GetTimePointOutput(int timepoint, int channel) { this->SetUpdateTimePoint(timepoint); this->SetUpdateChannel(channel); return this->GetOutput(); } void vtkLSMReader::SetUpdateTimePoint(int timepoint) { if ( timepoint < 0 || timepoint == this->IntUpdateExtent[3] ) { return; } this->IntUpdateExtent[3] = timepoint; this->Modified(); } void vtkLSMReader::SetUpdateChannel(int ch) { if ( ch < 0 || ch == this->IntUpdateExtent[4] ) { return; } this->IntUpdateExtent[4] = ch; // std::cout << "Update channel is now " << ch << std::endl; this->Modified(); } void vtkLSMReader::NeedToReadHeaderInformationOn() { this->FileNameChanged = 1; } void vtkLSMReader::NeedToReadHeaderInformationOff() { this->FileNameChanged = 0; } int vtkLSMReader::NeedToReadHeaderInformation() { return this->FileNameChanged; } ifstream * vtkLSMReader::GetFile() { return this->File; } int vtkLSMReader::BYTES_BY_DATA_TYPE(int type) { int bytes = 1; switch ( type ) { case ( 1 ): return 1; case ( 2 ): return 2; case ( 5 ): return 4; } return bytes; } int vtkLSMReader::TIFF_BYTES(unsigned short type) { switch ( type ) { default: case ( TIFF_BYTE ): return 1; case ( TIFF_ASCII ): case ( TIFF_SHORT ): return 2; case ( TIFF_LONG ): case ( TIFF_RATIONAL ): return 4; } } unsigned char vtkLSMReader::CharPointerToUnsignedChar(char *buf) { return *static_cast< unsigned char * >( static_cast< void * >( buf ) ); } int vtkLSMReader::CharPointerToInt(char *buf) { return *static_cast< int * >( static_cast< void * >( buf ) ); } unsigned int vtkLSMReader::CharPointerToUnsignedInt(char *buf) { return *static_cast< unsigned int * >( static_cast< void * >( buf ) ); } short vtkLSMReader::CharPointerToShort(char *buf) { return *static_cast< short * >( static_cast< void * >( buf ) ); } unsigned short vtkLSMReader::CharPointerToUnsignedShort(char *buf) { return *static_cast< unsigned short * >( static_cast< void * >( buf ) ); } double vtkLSMReader::CharPointerToDouble(char *buf) { return *static_cast< double * >( static_cast< void * >( buf ) ); } int vtkLSMReader::ReadInt(ifstream *f, unsigned long & pos) { char buff[4]; this->ReadFile(f, pos, 4, buff); #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap4LE( (int *)buff ); #endif return CharPointerToInt(buff); } unsigned int vtkLSMReader::ReadUnsignedInt(ifstream *f, unsigned long & pos) { char buff[4]; this->ReadFile(f, pos, 4, buff); #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap4LE( (unsigned int *)buff ); #endif return this->CharPointerToUnsignedInt(buff); } short vtkLSMReader::ReadShort(ifstream *f, unsigned long & pos) { char buff[2]; this->ReadFile(f, pos, 2, buff); #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap2LE( (short *)buff ); #endif return this->CharPointerToShort(buff); } unsigned short vtkLSMReader::ReadUnsignedShort(ifstream *f, unsigned long & pos) { char buff[2]; this->ReadFile(f, pos, 2, buff); #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap2LE( (unsigned short *)buff ); #endif return this->CharPointerToUnsignedShort(buff); } double vtkLSMReader::ReadDouble(ifstream *f, unsigned long & pos) { char buff[8]; this->ReadFile(f, pos, 8, buff); #ifdef VTK_WORDS_BIGENDIAN vtkByteSwap::Swap8LE( (double *)buff ); #endif return this->CharPointerToDouble(buff); } std::streamsize vtkLSMReader::ReadData(ifstream *f, unsigned long & pos, unsigned int size, char *buf) { return this->ReadFile(f, pos, size, buf, 1); } std::streamsize vtkLSMReader::ReadFile(ifstream *f, unsigned long & pos, unsigned int size, char *buf, bool swap) { std::streamsize ret = 1; f->seekg(pos, ios::beg); f->read(buf, size); #ifdef VTK_WORDS_BIGENDIAN if ( swap ) { vtkByteSwap::SwapLERange(buf, size); } #else (void)swap; #endif //if(f->fail() || f->eof()) ret=0; ret = f->gcount(); if ( !f ) { return 0; } pos = pos + size; return ret; } unsigned int vtkLSMReader::GetUpdateChannel() { return ( this->IntUpdateExtent[4] > this->GetNumberOfChannels() - 1 ? this->GetNumberOfChannels() - 1 : this->IntUpdateExtent[4] ); } void vtkLSMReader::PrintSelf(ostream & os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "Identifier: " << this->Identifier << "\n"; os << indent << "Dimensions: " << this->Dimensions[0] << "," << this->Dimensions[1] << "," << this->Dimensions[2] << "\n"; os << indent << "Time points: " << this->Dimensions[3] << "\n"; os << "Number of channels: " << this->Dimensions[4] << "\n"; os << "\n"; os << indent << "Number of intensity values X: " << this->NumberOfIntensityValues[0] << "\n"; os << indent << "Number of intensity values Y: " << this->NumberOfIntensityValues[1] << "\n"; os << indent << "Number of intensity values Z: " << this->NumberOfIntensityValues[2] << "\n"; os << indent << "Number of intensity values Time: " << this->NumberOfIntensityValues[3] << "\n"; os << indent << "Voxel size X: " << this->VoxelSizes[0] << "\n"; os << indent << "Voxel size Y: " << this->VoxelSizes[1] << "\n"; os << indent << "Voxel size Z: " << this->VoxelSizes[2] << "\n"; os << "\n"; os << indent << "Scan type: " << this->ScanType << "\n"; os << indent << "Data type: " << this->DataType << "\n"; if ( this->DataType == 0 ) { for ( int i = 0; i < this->GetNumberOfChannels(); i++ ) { os << indent << indent << "Data type of channel " << i << ": " << this->ChannelDataTypes->GetValue(i) << "\n"; } } os << indent << "Compression: " << this->Compression << "\n"; os << "\n"; os << indent << "Planar configuration: " << this->PlanarConfiguration << "\n"; os << indent << "Photometric interpretation: " << this->PhotometricInterpretation << "\n"; os << indent << "Predictor: " << this->Predictor << "\n"; os << indent << "Channel info:\n"; for ( int i = 0; i < this->Dimensions[4]; i++ ) { os << indent << indent << this->GetChannelName(i) << ",(" << this->GetChannelColorComponent(i, 0) << "," << this->GetChannelColorComponent(i, 1) << "," << this->GetChannelColorComponent(i, 2) << ")\n"; } os << indent << "Strip byte counts:\n"; for ( int i = 0; i < this->Dimensions[4]; i++ ) { os << indent << indent << this->StripByteCount->GetValue(i) << "\n"; } } GoFigure2-v0.9.0/Code/ExternalCode/vtkLSM/vtkLSMConfigure.h.in0000644000175000017500000000056711667757442023613 0ustar mathieumathieu#ifndef __vtkLSMConfigure_h #define __vtkLSMConfigure_h #include "vtkConfigure.h" /* Whether we are building shared libraries. */ #if defined ( WIN32 ) && defined ( GOFIGURE2_BUILD_SHARED_LIBS ) #if defined ( vtkLSM_EXPORT ) #define VTKLSM_EXPORT __declspec(dllexport) #else #define VTKLSM_EXPORT __declspec(dllimport) #endif #else #define VTKLSM_EXPORT #endif #endifGoFigure2-v0.9.0/Code/GoFigureGlobalDefinition.h0000644000175000017500000000447611667757442021273 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-10 Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __GoFigureGlobalDefinition_h #define __GoFigureGlobalDefinition_h namespace GoFigure { enum FileType { BMP = 0, JPEG, PNG, TIFF, MHA, LSM, EPS }; enum TabDimensionType { TWO_D_WITH_T = 1, TWO_D, THREE_D, THREE_D_WITH_T, FOUR_D }; } #endif GoFigure2-v0.9.0/Interfaces/0000755000175000017500000000000011667757442015457 5ustar mathieumathieuGoFigure2-v0.9.0/Interfaces/QGoPluginHelper.cxx0000644000175000017500000000522311667757442021212 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoPluginHelper.h" #include #include #include //-------------------------------------------------------------------------- QDir FindPluginDirectory(const QString & iSubdir) { QDir dir = QDir( QApplication::applicationDirPath() ); #if defined( Q_OS_WIN ) if ( ( dir.dirName().toLower() == "debug" ) || ( dir.dirName().toLower() == "release" ) ) { dir.cdUp(); } #elif defined( Q_OS_MAC ) if ( dir.dirName() == "MacOS" ) { dir.cdUp(); dir.cdUp(); dir.cdUp(); } #endif if ( dir.cd(iSubdir) ) { return dir; } else { QString temp = iSubdir; temp.toUpper(); if ( dir.cd(temp) ) { return dir; } else { temp.toLower(); dir.cd(temp); return dir; } } } //-------------------------------------------------------------------------- GoFigure2-v0.9.0/Interfaces/QGoPlugin.h0000644000175000017500000001016711667757442017502 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoPlugin_h #define __QGoPlugin_h #include #include #include #include #include #include #include #include #include "PluginInformationBase.h" #include "GoFigureGlobalDefinition.h" /** \class QGoPlugin \brief Abstract class for any kind of plugins used by GoFigure2. */ class QGoPlugin:public QObject { Q_OBJECT public: /** \brief Default Constructor.*/ explicit QGoPlugin(QObject *iParent = 0x0); /** \brief Destructor.*/ virtual ~QGoPlugin(){} /** \brief return Plugin Name of the plugin.*/ QString Name() const; /** \brief return Plugin Version of the plugin.*/ QString Version() const; /** \brief return GoFigure version for compatibility with the plugin.*/ QString GoFigureCompatibilityVersion() const; /** \brief return Distributor of the plugin.*/ QString Distributor() const; /** \brief return Copyright of the plugin.*/ QString Copyright() const; /** \brief return License of the plugin.*/ QString License() const; /** \brief return Short description of the plugin.*/ QString Description() const; /** \brief Write Settings for the plugin.*/ virtual void WriteSettings() = 0; /** \brief Read Settings for the plugin.*/ virtual void ReadSettings() = 0; virtual std::list< GoFigure::TabDimensionType > TabElementCompatibility() const = 0; /** \brief */ virtual std::vector< QAction * > Actions() = 0; /** \brief */ virtual QMenu * Menu() = 0; /** \brief */ virtual QToolBar * ToolBar() = 0; /** \brief */ virtual QDockWidget * DockWidget() = 0; /** \brief */ virtual QWidget * AdditionalWidget() = 0; /** \brief */ virtual void OnTabActivated(const int &) = 0; /** \brief */ virtual void OnTabMoved(const int &, const int &) = 0; /** \brief */ virtual void OnTabClosed(const int &) = 0; protected: /** \brief contains all information related to the plugin. \todo it would not be a bad idea to use a xml file instead. */ PluginInformationBase m_Information; /** \brief Set all required information (name, version, license...). \note This method MUST be called in the constructor of any plugin which inherits from QGoPlugin. */ virtual void SetAllRequiredInformation() = 0; private: Q_DISABLE_COPY(QGoPlugin); }; Q_DECLARE_INTERFACE(QGoPlugin, "GoFigure2.QGoPlugin/1.0") #endif GoFigure2-v0.9.0/Interfaces/QGoImageSegmentationPluginBase.h0000644000175000017500000000577711667757442023631 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoImageSegmentationPluginBase_h #define __QGoImageSegmentationPluginBase_h #include #include class vtkImageData; class vtkPolyData; class QAction; class QToolBar; class QDockWidget; class QWidget; #include "QGoPlugin.h" /** * \class QGoImageSegmentationPluginBase * \brief */ class QGoImageSegmentationPluginBase:public QGoPlugin { public: typedef vtkPolyData SubCellularType; typedef std::vector< SubCellularType * > SubCellularVectorType; typedef SubCellularVectorType::iterator SubCellularVectorIterator; typedef SubCellularType CellType; typedef std::vector< CellType > CellVectorType; typedef CellVectorType::iterator CellVectorIterator; QGoImageSegmentationPluginBase(); virtual ~QGoImageSegmentationPluginBase(); virtual void SetInput(vtkImageData *iInput); virtual void Update(); virtual CellVectorType GetOutput(); protected: vtkImageData *m_VTKInput; CellVectorType m_Output; virtual void Process() = 0; private: QGoImageSegmentationPluginBase(const QGoImageSegmentationPluginBase &); void operator=(const QGoImageSegmentationPluginBase &); }; Q_DECLARE_INTERFACE(QGoImageSegmentationPluginBase, "GoFigure2.QGoImageSegmentationPluginBase/1.0") #endif GoFigure2-v0.9.0/Interfaces/QGoPlugin.cxx0000644000175000017500000000462111667757442020053 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoPlugin.h" QGoPlugin::QGoPlugin(QObject *iParent):QObject(iParent) {} QString QGoPlugin::Name() const { return m_Information.Name; } QString QGoPlugin::Version() const { return m_Information.Version; } QString QGoPlugin::GoFigureCompatibilityVersion() const { return m_Information.GoFigureCompatibilityVersion; } QString QGoPlugin::Distributor() const { return m_Information.Distributor; } QString QGoPlugin::Copyright() const { return m_Information.Copyright; } QString QGoPlugin::License() const { return m_Information.License; } QString QGoPlugin::Description() const { return m_Information.Description; } GoFigure2-v0.9.0/Interfaces/QGoPluginHelper.h0000644000175000017500000000367611667757442020651 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoPluginHelper_h #define __QGoPluginHelper_h #include #include #include QDir FindPluginDirectory(const QString & iSubdir); #endif GoFigure2-v0.9.0/Interfaces/QGoImageSegmentationPluginBase.cxx0000644000175000017500000000467311667757442024176 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoImageSegmentationPluginBase.h" #include "vtkImageData.h" #include /** * \class QGoImageSegmentationPluginBase * \brief */ QGoImageSegmentationPluginBase::QGoImageSegmentationPluginBase():m_VTKInput(0), m_Output(0) {} QGoImageSegmentationPluginBase::~QGoImageSegmentationPluginBase() {} void QGoImageSegmentationPluginBase::SetInput(vtkImageData *iInput) { QMessageBox::information(0, "Title", "QGoImageSegmentationPluginBase::setInput"); m_VTKInput = iInput; } void QGoImageSegmentationPluginBase::Update() { if ( m_VTKInput ) { this->Process(); } } CellVectorType QGoImageSegmentationPluginBase::GetOutput() { return m_Output; } GoFigure2-v0.9.0/Interfaces/QGoImageFilterPluginBase.cxx0000644000175000017500000000510311667757442022753 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoImageFilterPluginBase.h" #include "vtkImageData.h" #include /** * \class QGoImageFilterPluginBase * \brief */ QGoImageFilterPluginBase::QGoImageFilterPluginBase(QObject *iParent):QGoPlugin(iParent), m_VTKInput(0), m_VTKOutput(0) {} void QGoImageFilterPluginBase::SetInput(vtkImageData *iInput) { m_VTKInput.resize(1, 0); m_VTKInput[0] = iInput; } void QGoImageFilterPluginBase::SetInput(std::vector< vtkImageData * > & iInput) { QMessageBox::information(0, "Title", "QGoImageFilterPluginBase::setInput"); m_VTKInput = iInput; } void QGoImageFilterPluginBase::Update() { if ( !m_VTKInput.empty() ) { if ( m_VTKInput.front() ) { this->Process(); } } } std::vector< vtkImageData * > QGoImageFilterPluginBase::GetOutput() { return m_VTKOutput; } GoFigure2-v0.9.0/Interfaces/PluginInformationBase.h0000644000175000017500000000414011667757442022066 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __PluginInformationBase_h #define __PluginInformationBase_h class QString; /** \class PluginInformationBase \brief */ struct PluginInformationBase { public: QString Name; QString Version; QString GoFigureCompatibilityVersion; QString Distributor; QString Copyright; QString License; QString Description; }; #endif GoFigure2-v0.9.0/Interfaces/QGoImageFilterPluginBase.h0000644000175000017500000000537111667757442022407 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoImageFilterPluginBase_h #define __QGoImageFilterPluginBase_h #include #include class vtkImageData; class QAction; class QToolBar; class QDockWidget; class QWidget; #include "QGoPlugin.h" /** * \class QGoImageFilterPluginBase * \brief */ class QGoImageFilterPluginBase:public QGoPlugin { Q_OBJECT public: explicit QGoImageFilterPluginBase(QObject *iParent = 0x0); virtual ~QGoImageFilterPluginBase() {} virtual void SetInput(vtkImageData *iInput); virtual void SetInput(std::vector< vtkImageData * > & iInput); virtual void Update(); virtual std::vector< vtkImageData * > GetOutput(); signals: void Done(std::vector< vtkImageData * > ); protected: std::vector< vtkImageData * > m_VTKInput; std::vector< vtkImageData * > m_VTKOutput; virtual void Process() = 0; private: Q_DISABLE_COPY(QGoImageFilterPluginBase); }; Q_DECLARE_INTERFACE(QGoImageFilterPluginBase, "GoFigure2.QGoImageFilterPluginBase/1.0") #endif GoFigure2-v0.9.0/Plugins/0000755000175000017500000000000011667757442015015 5ustar mathieumathieuGoFigure2-v0.9.0/Plugins/ImageMedianPlugin/0000755000175000017500000000000011667757442020334 5ustar mathieumathieuGoFigure2-v0.9.0/Plugins/ImageMedianPlugin/QCellPreprocess.h0000644000175000017500000000777611667757442023574 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QCellPreprocess_h #define __QCellPreprocess_h #include "vtkSmartPointer.h" #include "vtkImageData.h" #include "vtkImageImport.h" #include "vtkImageExport.h" #include "itkCellPreprocess.h" #include "itkVTKImageExport.h" #include "itkVTKImageImport.h" #include "ui_CellPreprocess.h" #include #include #include #include class QCellPreprocess:public QWidget, private Ui::CellPreprocessWidget { Q_OBJECT public: typedef itk::Image< unsigned char, 3 > InputImageType; typedef InputImageType::Pointer InputImagePointer; typedef itk::CellPreprocess< InputImageType, InputImageType > PreprocessFilterType; typedef PreprocessFilterType::Pointer PreprocessFilterPointer; typedef itk::VTKImageExport< InputImageType > ImageExportType; typedef ImageExportType::Pointer ImageExportPointer; typedef itk::VTKImageImport< InputImageType > ImageImportType; typedef ImageImportType::Pointer ImageImportPointer; explicit QCellPreprocess(QWidget *iParent = 0); virtual ~QCellPreprocess(){} void SetMembraneDataType(bool x); void SetInput(std::vector< vtkImageData * > & iImg); std::vector< vtkImageData * > GetOutput(); signals: void Done(std::vector< vtkImageData * > ); protected slots : void on_RadiusSpinBox_valueChanged(); void on_RadiusSlider_sliderReleased(); void on_GlobalResetButton_clicked(); void on_GlobalApplyButton_clicked(); void on_singleChRadioButton_clicked(); void on_allChRadioButton_clicked(); protected: void GetParameters(); void Preprocess(unsigned int i); double m_CellRadius; bool m_MembraneData; std::vector< vtkImageData * > m_VTKInput; std::vector< vtkImageData * > m_VTKOutput; private: QCellPreprocess(const QCellPreprocess &); QCellPreprocess operator=(const QCellPreprocess &); }; #endif GoFigure2-v0.9.0/Plugins/ImageMedianPlugin/medianpluginMain.cxx0000644000175000017500000000553411667757442024350 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "medianplugin.h" //#include #include #include int main(int argc, char **argv) { (void)argc; (void)argv; // QDir PluginDir( "plugins/" ); // // // Here open one image // // foreach( QString fileName, PluginDir.entryList( QDir::Files ) ) // { // QPluginLoader loader( PluginDir.absoluteFilePath( fileName ) ); // // QObject* plugin = loader.instance(); // // if( plugin ) // { // medianplugin* temp = dynamic_cast< medianplugin* >( plugin ); // // if( temp ) // { // std::cout <<"median plugin correctly loaded" < //-------------------------------------------------------------------------- QCellPreprocess::QCellPreprocess(QWidget *iParent):QWidget(iParent) { this->setupUi(this); m_CellRadius = 4.0; m_MembraneData = true; this->buttonGroup->setId(allChRadioButton, 0); this->buttonGroup->setId(singleChRadioButton, 1); this->ChannelComboBox->setEnabled(false); } void QCellPreprocess::SetMembraneDataType(bool x) { m_MembraneData = x; } void QCellPreprocess::SetInput(std::vector< vtkImageData * > & iImg) { m_VTKInput = iImg; m_VTKOutput.resize(m_VTKInput.size(), 0); } std::vector< vtkImageData * > QCellPreprocess::GetOutput() { return m_VTKOutput; } //-------------------------------------------------------------------------- void QCellPreprocess::GetParameters() { // Get the current snapshot of parameters m_CellRadius = static_cast< double >( this->RadiusSpinBox->value() ); } //-------------------------------------------------------------------------- void QCellPreprocess::on_RadiusSpinBox_valueChanged() { double t = this->RadiusSpinBox->value(); double max_spin = this->RadiusSpinBox->maximum(); double min_spin = this->RadiusSpinBox->minimum(); int max_slider = this->RadiusSlider->maximum(); int min_slider = this->RadiusSlider->minimum(); int out = static_cast< int >( min_slider + ( max_slider - min_slider ) * ( t - min_spin ) / ( max_spin - min_spin ) ); this->RadiusSlider->setValue(out); } //-------------------------------------------------------------------------- void QCellPreprocess::on_RadiusSlider_sliderReleased() { int t = this->RadiusSlider->value(); double max_spin = this->RadiusSpinBox->maximum(); double min_spin = this->RadiusSpinBox->minimum(); int max_slider = this->RadiusSlider->maximum(); int min_slider = this->RadiusSlider->minimum(); double out = static_cast< double >( min_spin + ( max_spin - min_spin ) * ( t - min_slider ) / ( max_slider - min_slider ) ); this->RadiusSpinBox->setValue(out); } //-------------------------------------------------------------------------- void QCellPreprocess::on_allChRadioButton_clicked() { this->ChannelComboBox->setEnabled(false); } //-------------------------------------------------------------------------- void QCellPreprocess::on_singleChRadioButton_clicked() { this->ChannelComboBox->setEnabled(true); } //-------------------------------------------------------------------------- void QCellPreprocess::on_GlobalResetButton_clicked() { this->m_CellRadius = 4.0; this->RadiusSpinBox->setValue(this->m_CellRadius); } //-------------------------------------------------------------------------- void QCellPreprocess::on_GlobalApplyButton_clicked() { unsigned int option = static_cast< unsigned int >( this->buttonGroup->checkedId() ); if ( !option ) { Preprocess(0); // Preprocess( 1 ); // Preprocess( 2 ); } else { unsigned int channel = static_cast< unsigned int >( this->ChannelComboBox->currentIndex() ); Preprocess(channel); } emit Done(m_VTKOutput); } void QCellPreprocess::Preprocess(unsigned int i) { if ( m_VTKInput[i] ) { // convert VTK image to ITK image vtkImageExport *vtkExporter = vtkImageExport::New(); vtkExporter->SetInput(m_VTKInput[i]); ImageImportPointer itkImporter = ImageImportType::New(); ConnectPipelines(vtkExporter, itkImporter); InputImagePointer m_ITKImage = itkImporter->GetOutput(); PreprocessFilterPointer filter = PreprocessFilterType::New(); filter->SetInput (m_ITKImage); filter->SetLargestCellRadius (m_CellRadius); // in real coordinates filter->SetMembraneData(m_MembraneData); filter->Update(); InputImagePointer m_ITKOutputImage = filter->GetOutput(); ImageExportType::Pointer itkExporter = ImageExportType::New(); itkExporter->SetInput(m_ITKOutputImage); vtkImageImport *vtkImporter = vtkImageImport::New(); ConnectPipelines(itkExporter, vtkImporter); m_VTKOutput[i] = vtkImporter->GetOutput(); vtkExporter->Delete(); vtkImporter->Delete(); } } GoFigure2-v0.9.0/Plugins/ImageMedianPlugin/medianplugin.h0000644000175000017500000000574311667757442023172 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __medianplugin_h #define __medianplugin_h #include "QGoImageFilterPluginBase.h" #include "QCellPreprocess.h" class medianplugin:public QGoImageFilterPluginBase { Q_OBJECT Q_INTERFACES(QGoImageFilterPluginBase) public: explicit medianplugin(QObject *iParent = 0x0); virtual ~medianplugin(); virtual std::vector< QAction * > Actions(); virtual QToolBar * ToolBar(); virtual QMenu * Menu(); virtual QDockWidget * DockWidget(); virtual QWidget * AdditionalWidget(); virtual void WriteSettings() {} virtual void ReadSettings() {} virtual void OnTabActivated(const int &) {} virtual void OnTabMoved(const int &, const int &) {} virtual void OnTabClosed(const int &) {} virtual std::list< GoFigure::TabDimensionType > TabElementCompatibility() const; protected: virtual void Process(); virtual void SetAllRequiredInformation(); QCellPreprocess *preprocess; private: Q_DISABLE_COPY(medianplugin); }; #endif GoFigure2-v0.9.0/Plugins/ImageMedianPlugin/itkCellPreprocess.h0000644000175000017500000001216411667757442024146 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkCellPreprocess_h #define __itkCellPreprocess_h #if defined( _MSC_VER ) #pragma warning ( disable : 4786 ) #endif #ifdef __BORLANDC__ #define ITK_LEAN_AND_MEAN #endif #include "itkImageToImageFilter.h" #include "itkCastImageFilter.h" #include "itkMedianImageFilter.h" #include "itkGrayscaleFillholeImageFilter.h" #include "itkGradientAnisotropicDiffusionImageFilter.h" namespace itk { template< class TInputImage, class TOutputImage = TInputImage > class ITK_EXPORT CellPreprocess: public ImageToImageFilter< TInputImage, TOutputImage > { public: typedef CellPreprocess Self; typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkStaticConstMacro (ImageDimension, unsigned int, TInputImage::ImageDimension); /** Method for creation through object factory */ itkNewMacro (Self); /** Run-time type information */ itkTypeMacro (CellPreprocess, ImageToImageFilter); /** Display */ void PrintSelf(std::ostream & os, Indent indent) const; typedef Image< float, ImageDimension > ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::PixelType ImagePixelType; typedef typename ImageType::RegionType ImageRegionType; typedef typename ImageType::SizeType ImageSizeType; typedef typename ImageSizeType::SizeValueType ImageSizeValueType; typedef typename ImageType::SpacingType ImageSpacingType; typedef typename ImageType::IndexType ImageIndexType; typedef typename ImageType::PointType ImagePointType; typedef CastImageFilter< TInputImage, ImageType > InputCastType; typedef typename InputCastType::Pointer InputCastPointer; typedef MedianImageFilter< ImageType, ImageType > MedianFilterType; typedef typename MedianFilterType::Pointer MedianFilterPointer; typedef GradientAnisotropicDiffusionImageFilter< ImageType, ImageType > SmoothingFilterType; typedef typename SmoothingFilterType::Pointer SmoothingFilterPointer; typedef GrayscaleFillholeImageFilter< ImageType, ImageType > GrayscaleFillholeFilterType; typedef typename GrayscaleFillholeFilterType::Pointer GrayscaleFillholePointer; typedef CastImageFilter< ImageType, TOutputImage > OutputCastType; typedef typename OutputCastType::Pointer OutputCastPointer; itkGetConstMacro (LargestCellRadius, double); itkSetMacro (LargestCellRadius, double); itkGetConstMacro (MembraneData, bool); itkSetMacro (MembraneData, bool); protected: CellPreprocess(); ~CellPreprocess() {} void GenerateData(); double m_LargestCellRadius; bool m_MembraneData; private: CellPreprocess (Self &); // intentionally not implemented void operator=(const Self &); // intentionally not implemented }; } /* namespace itk */ #include "itkCellPreprocess.txx" #endif GoFigure2-v0.9.0/Plugins/ImageMedianPlugin/CellPreprocess.ui0000644000175000017500000001341311667757442023622 0ustar mathieumathieu CellPreprocessWidget 0 0 326 248 Form 10 10 311 54 Specify the largest radius of a nuclei in terms of pixel spacing. Typically, a nucleus is in the range of 3-7 microns in radius. Specify the largest radius of a nuclei in terms of pixel spacing. Typically, a nucleus is in the range of 3-7 microns in radius. 199 40 Qt::Horizontal QSlider::TicksAbove 5 Specify the largest radius of a nuclei in terms of pixel spacing. Typically, a nucleus is in the range of 3-7 microns in radius. Specify the largest radius of a nuclei in terms of pixel spacing. Typically, a nucleus is in the range of 3-7 microns in radius. 20.000000000000000 0.100000000000000 4.000000000000000 Specify the largest radius of a nuclei in terms of pixel spacing. Typically, a nucleus is in the range of 3-7 microns in radius. Specify the largest radius of a nuclei in terms of pixel spacing. Typically, a nucleus is in the range of 3-7 microns in radius. CellRadius 28 90 250 32 Reset the parameters for all stages to default values. Reset the parameters for all stages to default values. Reset Executes the pipeline stages in sequence Apply 10 153 311 77 All Channels true buttonGroup SingleChannels buttonGroup false 0 true 0 Channel 1 Channel 2 Channel 3 RadiusSpinBox RadiusSlider GlobalResetButton GlobalApplyButton GoFigure2-v0.9.0/Plugins/ImageMedianPlugin/medianplugin.cxx0000644000175000017500000000760511667757442023544 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "medianplugin.h" #include #include Q_EXPORT_PLUGIN2(QGoIdentityImageFilterPlugin, medianplugin) medianplugin::medianplugin(QObject *iParent):QGoImageFilterPluginBase(iParent) { this->SetAllRequiredInformation(); preprocess = new QCellPreprocess(); QObject::connect( preprocess, SIGNAL( Done(std::vector< vtkImageData * > ) ), this, SIGNAL( Done(std::vector< vtkImageData * > ) ) ); } medianplugin::~medianplugin() {} std::vector< QAction * > medianplugin::Actions() { QAction *action = new QAction(tr("&Median"), this); QObject::connect( action, SIGNAL(triggered), this, SLOT( Process() ) ); std::vector< QAction * > oActionList; oActionList.push_back(action); return oActionList; } QToolBar * medianplugin::ToolBar() { return 0; } QMenu * medianplugin::Menu() { return 0; } QDockWidget * medianplugin::DockWidget() { return 0; } QWidget * medianplugin::AdditionalWidget() { return 0; } std::list< GoFigure::TabDimensionType > medianplugin::TabElementCompatibility() const { std::list< GoFigure::TabDimensionType > oCompatibility; oCompatibility.push_back(GoFigure::TWO_D); oCompatibility.push_back(GoFigure::THREE_D); return oCompatibility; } void medianplugin::Process() { preprocess->SetInput(m_VTKInput); preprocess->setVisible(true); // m_VTKOutput = preprocess->GetOutput(); std::cout << "medianplugin::Process" << std::endl; } void medianplugin::SetAllRequiredInformation() { this->m_Information.Name = "MedianFiltering"; this->m_Information.Version = "1.0"; this->m_Information.GoFigureCompatibilityVersion = "1.0"; this->m_Information.Distributor = "Megason Lab"; this->m_Information.Copyright = "Harvard Medical School"; this->m_Information.License = "BSD"; this->m_Information.Description = "Test: plugin which median filters the input"; } GoFigure2-v0.9.0/Plugins/ImageMedianPlugin/itkCellPreprocess.txx0000644000175000017500000001100111667757442024527 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __itkCellPreprocess_txx #define __itkCellPreprocess_txx #include "itkCellPreprocess.h" namespace itk { template< class TInputImage, class TOutputImage > CellPreprocess< TInputImage, TOutputImage > ::CellPreprocess():m_LargestCellRadius (4.0) { m_MembraneData = false; this->Superclass::SetNumberOfRequiredInputs (1); this->Superclass::SetNumberOfRequiredOutputs (1); this->Superclass::SetNthOutput ( 0, TOutputImage::New() ); } template< class TInputImage, class TOutputImage > void CellPreprocess< TInputImage, TOutputImage >::GenerateData() { InputCastPointer m_CastInput = InputCastType::New(); m_CastInput->SetInput ( this->GetInput() ); m_CastInput->Update(); ImageSpacingType spacing = this->GetInput()->GetSpacing(); ImageSizeType radius; for ( unsigned int j = 0; j < ImageDimension; j++ ) { radius[j] = static_cast< ImageSizeValueType >( 0.3 * m_LargestCellRadius / spacing[j]); } ImagePointer cellImg; { MedianFilterPointer m_Median = MedianFilterType::New(); m_Median = MedianFilterType::New(); m_Median->SetRadius (radius); m_Median->SetInput ( m_CastInput->GetOutput() ); m_Median->Update(); SmoothingFilterPointer m_smooth = SmoothingFilterType::New(); m_smooth->SetInput ( m_Median->GetOutput() ); m_smooth->SetNumberOfIterations(5); m_smooth->SetTimeStep(0.0125); m_smooth->SetConductanceParameter(3); m_smooth->UseImageSpacingOn(); m_smooth->Update(); if ( m_MembraneData ) { cellImg = m_smooth->GetOutput(); cellImg->DisconnectPipeline(); } else { GrayscaleFillholePointer m_fillHole = GrayscaleFillholeFilterType::New(); m_fillHole->SetInput ( m_smooth->GetOutput() ); m_fillHole->SetFullyConnected (0); m_fillHole->Update(); cellImg = m_fillHole->GetOutput(); cellImg->DisconnectPipeline(); } } OutputCastPointer m_CastOutput = OutputCastType::New(); m_CastOutput->SetInput (cellImg); m_CastOutput->GraftOutput ( this->GetOutput() ); m_CastOutput->Update(); this->GraftOutput ( m_CastOutput->GetOutput() ); } template< class TInputImage, class TOutputImage > void CellPreprocess< TInputImage, TOutputImage >::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf (os, indent); os << indent << "Class Name: " << GetNameOfClass() << std::endl; os << indent << "Largest cell radius: " << GetLargestCellRadius() << std::endl; } } /* end namespace itk */ #endif GoFigure2-v0.9.0/Plugins/CMakeLists.txt0000644000175000017500000000004611667757442017555 0ustar mathieumathieuADD_SUBDIRECTORY( ImageMedianPlugin ) GoFigure2-v0.9.0/CTestConfig.cmake0000644000175000017500000000102711667757442016546 0ustar mathieumathieu## This file should be placed in the root directory of your project. ## Then modify the CMakeLists.txt file in the root directory of your ## project to incorporate the testing dashboard. ## # The following are required to uses Dart and the Cdash dashboard ## ENABLE_TESTING() ## INCLUDE(CTest) set(CTEST_PROJECT_NAME "GoFigure2") set(CTEST_NIGHTLY_START_TIME "22:00:00 EST") set(CTEST_DROP_METHOD "http") set(CTEST_DROP_SITE "my.cdash.org") set(CTEST_DROP_LOCATION "/submit.php?project=GoFigure2") set(CTEST_DROP_SITE_CDASH TRUE) GoFigure2-v0.9.0/GOFIGURE2Uninstall.cmake.in0000644000175000017500000000173011667757442020167 0ustar mathieumathieuIF( NOT EXISTS "@GOFIGURE2_BINARY_DIR@/install_manifest.txt" ) MESSAGE( FATAL_ERROR "Cannot find install manifest: \"@GOFIGURE2_BINARY_DIR@/install_manifest.txt\"" ) ENDIF( NOT EXISTS "@GOFIGURE2_BINARY_DIR@/install_manifest.txt" ) FILE( READ "@GOFIGURE2_BINARY_DIR@/install_manifest.txt" files ) STRING( REGEX REPLACE "\n" ";" files "${files}" ) FOREACH( file ${files} ) MESSAGE( STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"" ) IF( EXISTS "$ENV{DESTDIR}${file}" ) EXEC_PROGRAM( "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) IF( "${rm_retval}" STREQUAL 0 ) ELSE( "${rm_retval}" STREQUAL 0 ) MESSAGE( FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"" ) ENDIF( "${rm_retval}" STREQUAL 0 ) ELSE( EXISTS "$ENV{DESTDIR}${file}" ) MESSAGE( STATUS "File \"$ENV{DESTDIR}${file}\" does not exist." ) ENDIF( EXISTS "$ENV{DESTDIR}${file}" ) ENDFOREACH( file ) GoFigure2-v0.9.0/CMakeLists.txt0000644000175000017500000003505111667757442016140 0ustar mathieumathieuIF( COMMAND CMAKE_POLICY ) CMAKE_POLICY( VERSION 2.6 ) CMAKE_POLICY( SET CMP0005 OLD ) CMAKE_POLICY( SET CMP0003 NEW ) ENDIF(COMMAND CMAKE_POLICY) # On Visual Studio 8 MS deprecated C. This removes all 1.276E1265 security # warnings. Copied from ITK CMakeLists. IF( WIN32 ) IF( NOT BORLAND ) IF( NOT CYGWIN ) IF( NOT MINGW ) ADD_DEFINITIONS( -D_CRT_FAR_MAPPINGS_NO_DEPRECATE -D_CRT_IS_WCTYPE_NO_DEPRECATE -D_CRT_MANAGED_FP_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_DEPRECATE_GLOBALS -D_CRT_SETERRORMODE_BEEP_SLEEP_NO_DEPRECATE -D_CRT_TIME_FUNCTIONS_NO_DEPRECATE -D_CRT_VCCLRIT_NO_DEPRECATE -D_SCL_SECURE_NO_DEPRECATE ) ENDIF( NOT MINGW ) ENDIF( NOT CYGWIN ) ENDIF( NOT BORLAND ) ENDIF( WIN32 ) #------------------------------------------------------------------------- # When making one release: update GOFIGURE2_*_VERSION, # GOFIGURE2_WC_REVISION and the date of the release SET( GOFIGURE2_MAJOR_VERSION "0" ) SET( GOFIGURE2_MINOR_VERSION "9" ) SET( GOFIGURE2_WC_REVISION "0" ) SET( DATE "12/07/2011" ) SET( GOFIGURE2_VERSION "${GOFIGURE2_MAJOR_VERSION}.${GOFIGURE2_MINOR_VERSION}.${GOFIGURE2_WC_REVISION}" ) SET( GOFIGURE2_LIB_VERSION "${GOFIGURE2_MAJOR_VERSION}.${GOFIGURE2_MINOR_VERSION}" ) MESSAGE( STATUS "GoFigure2 version ${GOFIGURE2_VERSION}" ) #--------------------------------------------------------------------------- # CONFIGURE CMAKE #--------------------------------------------------------------------------- SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMake/" "${CMAKE_CURRENT_SOURCE_DIR}/CMake/SuperBuild/" ) IF( UNIX ) SET (CACHE CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") ENDIF( UNIX ) #--------------------------------------------------------------------------- # SUPERBUILD - DISABLED BY DEFAULT #--------------------------------------------------------------------------- OPTION( SUPERBUILD "Use SuperBuild" OFF ) IF( SUPERBUILD ) CMAKE_MINIMUM_REQUIRED( VERSION 2.8.3 ) PROJECT( MYSUPERPROJECT ) INCLUDE( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/SuperBuild/SuperBuild.cmake" ) RETURN() ELSE( SUPERBUILD ) # CMake >= 2.8.2 MUST be installed (which is required by ITK) CMAKE_MINIMUM_REQUIRED( VERSION 2.8.2 ) PROJECT( GOFIGURE2 ) #------------------------------------------------------------------------- OPTION( OPENMP_SUPPORT "Enable OpenMP support if possible" ON ) IF( OPENMP_SUPPORT ) FIND_PACKAGE( OpenMP ) IF( OPENMP_FOUND ) MESSAGE( STATUS "OpenMP found" ) ADD_DEFINITIONS( -DHAS_OPENMP ) SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" ) SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" ) ELSE() MESSAGE( STATUS "OpenMP not found" ) REMOVE_DEFINITIONS( -DHAS_OPENMP ) ENDIF() ELSE() REMOVE_DEFINITIONS( -DHAS_OPENMP ) ENDIF() #----------------------------------------------------------------------- # Export and Install configuration # # GOFIGURE2_INSTALL_BUNDLE_DIR - bundle dir # GOFIGURE2_INSTALL_HEADER_DIR - include dir (headers) # GOFIGURE2_INSTALL_BIN_DIR - binary dir (executables) # GOFIGURE2_INSTALL_LIB_DIR - library dir (libs) # GOFIGURE2_INSTALL_DOC_DIR - documentation dir # GOFIGURE2_INSTALL_LICENSE_DIR - licenses dir # GOFIGURE2_INSTALL_RESOURCE_DIR - resources dir #----------------------------------------------------------------------- IF( NOT GOFIGURE2_INSTALL_BUNDLE_DIR ) SET( GOFIGURE2_INSTALL_BUNDLE_DIR "." ) ENDIF( NOT GOFIGURE2_INSTALL_BUNDLE_DIR ) IF( NOT GOFIGURE2_INSTALL_BIN_DIR ) SET( GOFIGURE2_INSTALL_BIN_DIR "bin" ) ENDIF( NOT GOFIGURE2_INSTALL_BIN_DIR ) IF( NOT GOFIGURE2_INSTALL_HEADER_DIR ) SET( GOFIGURE2_INSTALL_HEADER_DIR "include/gofigure2/" ) ENDIF( NOT GOFIGURE2_INSTALL_HEADER_DIR ) IF( NOT GOFIGURE2_INSTALL_LIB_DIR ) SET( GOFIGURE2_INSTALL_LIB_DIR "lib/gofigure2" ) ENDIF( NOT GOFIGURE2_INSTALL_LIB_DIR ) IF( NOT GOFIGURE2_INSTALL_DOC_DIR ) SET( GOFIGURE2_INSTALL_DOC_DIR "share/doc/gofigure2" ) ENDIF( NOT GOFIGURE2_INSTALL_DOC_DIR ) IF( NOT GOFIGURE2_INSTALL_LICENSE_DIR ) SET( GOFIGURE2_INSTALL_LICENSE_DIR "share/doc/gofigure2/Licenses" ) ENDIF( NOT GOFIGURE2_INSTALL_LICENSE_DIR ) IF( NOT GOFIGURE2_INSTALL_RESOURCE_DIR ) SET( GOFIGURE2_INSTALL_RESOURCE_DIR "share/doc/gofigure2/Resources" ) ENDIF( NOT GOFIGURE2_INSTALL_RESOURCE_DIR ) #--------------------------------------------------------------------------- # Define CMAKE_whatever_OUTPUT_DIRECTORY #--------------------------------------------------------------------------- # all target executables will be # in ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${GOFIGURE2_BINARY_DIR}/bin ) # all target static libraries will be in ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${GOFIGURE2_BINARY_DIR}/lib ) IF( NOT APPLE ) # all shared libraries will be in ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} # Note that modules (plugins) are considered as shared libraries SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins ${GOFIGURE2_BINARY_DIR}/lib ) ELSE() SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${GOFIGURE2_BINARY_DIR}/bin/gofigure.app/Contents/MacOS/ ) ENDIF() SET( GOFIGURE2_LIBRARY_DIRS ${GOFIGURE2_BINARY_DIR}/lib ) #--------------------------------------------------------------------------- # Export files (body of emails, etc...) #--------------------------------------------------------------------------- # define useful variables IF( WIN32 ) SET( OS "Windows" ) ELSE( WIN32 ) IF ( APPLE ) SET( OS "Mac OS X" ) ELSE( APPLE ) SET( OS "Linux" ) ENDIF( APPLE ) ENDIF( WIN32 ) # Licences file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Licenses) file(COPY ${GOFIGURE2_SOURCE_DIR}/Licenses/ DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Licenses) # Resources file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Resources) CONFIGURE_FILE( ${GOFIGURE2_SOURCE_DIR}/Resources/BugEntry.txt.in ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Resources/BugEntry.txt @ONLY ) #--------------------------------------------------------------------------- # Define TESTING_DATA_PATH #--------------------------------------------------------------------------- SET( TESTING_DATA_PATH ${GOFIGURE2_SOURCE_DIR}/Testing/Data CACHE PATH "Directory which contains data for testing." ) #--------------------------------------------------------------------------- # Handle Documentation #--------------------------------------------------------------------------- OPTION( BUILD_DOCUMENTATION "Build Doxygen Documentation" OFF ) IF( BUILD_DOCUMENTATION ) INCLUDE( "${GOFIGURE2_SOURCE_DIR}/CMake/ConfigDoxygen.cmake" ) ENDIF( BUILD_DOCUMENTATION ) #--------------------------------------------------------------------------- # Main GoFigure Settings #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- # Everything depends on VTK first # that way we can get Qt info from VTK #### VTK #### INCLUDE( "${GOFIGURE2_SOURCE_DIR}/CMake/ConfigVTK.cmake" ) #---------------------------------------------------------- # Then find ITK #### ITK #### INCLUDE( "${GOFIGURE2_SOURCE_DIR}/CMake/ConfigITK.cmake" ) #---------------------------------------------------------- # Then find Boost #### BOOST #### INCLUDE( "${GOFIGURE2_SOURCE_DIR}/CMake/ConfigBoost.cmake" ) #---------------------------------------------------------- # Then find Qt. # Note that some command line tools will get compiled even without Qt #### Qt #### INCLUDE( "${GOFIGURE2_SOURCE_DIR}/CMake/ConfigQT.cmake" ) #---------------------------------------------------------- # SET( GOFIGURE2_EXTERNAL_SOURCE_DIR ${GOFIGURE2_SOURCE_DIR}/Code/ExternalCode ) SET( GOFIGURE2_EXTERNAL_BINARY_DIR ${GOFIGURE2_BINARY_DIR}/Code/ExternalCode ) SET( MEGAVTK2_SOURCE_DIR ${GOFIGURE2_EXTERNAL_SOURCE_DIR}/MegaVTK ) SET( MEGAVTK2_BINARY_DIR ${GOFIGURE2_EXTERNAL_BINARY_DIR}/MegaVTK ) LINK_DIRECTORIES( ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ) INCLUDE_DIRECTORIES( BEFORE ${QT_INCLUDES} ${GOFIGURE2_SOURCE_DIR}/Code/ ${GOFIGURE2_BINARY_DIR}/Code/ ${GOFIGURE2_SOURCE_DIR}/Code/IO/ ${GOFIGURE2_BINARY_DIR}/Code/IO/ ${GOFIGURE2_SOURCE_DIR}/Code/IO/GoDBRow/ ${GOFIGURE2_BINARY_DIR}/Code/IO/GoDBRow/ ${GOFIGURE2_SOURCE_DIR}/Code/IO/GoImage/ ${GOFIGURE2_BINARY_DIR}/Code/IO/GoImage/ ${GOFIGURE2_SOURCE_DIR}/Code/Filters/ ${GOFIGURE2_BINARY_DIR}/Code/Filters/ ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Contour/ ${GOFIGURE2_BINARY_DIR}/Code/Filters/Contour/ ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Mesh/ ${GOFIGURE2_BINARY_DIR}/Code/Filters/Mesh/ ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Mesh/Attributes/ ${GOFIGURE2_BINARY_DIR}/Code/Filters/Mesh/Attributes/ ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Mesh/Split/ ${GOFIGURE2_BINARY_DIR}/Code/Filters/Mesh/Split/ ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Mesh/Merge/ ${GOFIGURE2_BINARY_DIR}/Code/Filters/Mesh/Merge/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/Resources/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/DBManager/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/DBManager/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/SynchronizedViews/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/SynchronizedViews/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/VisualizationTraceContainers/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/VisualizationTraceContainers/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/Video/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/Video/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/Wizard/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/Wizard/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/TraceEditing/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/TraceEditing/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/TransferFunctionEditor/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/TransferFunctionEditor/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/LineageViewer/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/LineageViewer/ ${GOFIGURE2_SOURCE_DIR}/Interfaces/ ${GOFIGURE2_BINARY_DIR}/Interfaces/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/src/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/src/ ${MEGAVTK2_SOURCE_DIR} ${MEGAVTK2_BINARY_DIR} ${MEGAVTK2_SOURCE_DIR}/vtkItk ${MEGAVTK2_BINARY_DIR}/vtkItk ${MEGAVTK2_SOURCE_DIR}/vtkRenderingAddOn ${MEGAVTK2_BINARY_DIR}/vtkRenderingAddOn ${GOFIGURE2_EXTERNAL_SOURCE_DIR}/vtkLSM ${GOFIGURE2_EXTERNAL_BINARY_DIR}/vtkLSM ${GOFIGURE2_EXTERNAL_BINARY_DIR}/itkQt ${GOFIGURE2_EXTERNAL_SOURCE_DIR}/itkQt ${GOFIGURE2_EXTERNAL_SOURCE_DIR}/PoissonReconstruction ${GOFIGURE2_EXTERNAL_BINARY_DIR}/PoissonReconstruction ${GOFIGURE2_EXTERNAL_SOURCE_DIR}/ctk ${GOFIGURE2_EXTERNAL_BINARY_DIR}/ctk ${GOFIGURE2_SOURCE_DIR}/Main ${GOFIGURE2_BINARY_DIR}/Main ) #--------------------------------------------------------------------- #--------------------------------------------------------------------- SET( QGoResourceFile ${GOFIGURE2_SOURCE_DIR}/Resources/axes.qrc ) SET( QGoGUIINTERFACES_HDRS ${GOFIGURE2_SOURCE_DIR}/Interfaces/QGoPlugin.h ${GOFIGURE2_SOURCE_DIR}/Interfaces/QGoImageFilterPluginBase.h ) SET( QGoGUIINTERFACES_SRC ${GOFIGURE2_SOURCE_DIR}/Interfaces/QGoPluginHelper.cxx ${GOFIGURE2_SOURCE_DIR}/Interfaces/QGoPlugin.cxx ${GOFIGURE2_SOURCE_DIR}/Interfaces/QGoImageFilterPluginBase.cxx ) INSTALL( FILES ${QGoGUIINTERFACES_HDRS} ${GOFIGURE2_SOURCE_DIR}/Interfaces/QGoPluginHelper.h ${GOFIGURE2_SOURCE_DIR}/Interfaces/QGoImageSegmentationPluginBase.h ${GOFIGURE2_SOURCE_DIR}/Interfaces/PluginInformationBase.h DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) OPTION( BUILD_COMPARETOOL "Build image comparison tool" OFF ) ADD_SUBDIRECTORY( Code ) ADD_SUBDIRECTORY( Main ) #----------------------------------------------------------------------- # Plugins #----------------------------------------------------------------------- IF( VTK_BUILD_SHARED_LIBS ) OPTION( BUILD_PLUGINS "Build GoFigure Plugins" OFF ) ELSE( VTK_BUILD_SHARED_LIBS ) SET( BUILD_PLUGINS OFF ) ENDIF( VTK_BUILD_SHARED_LIBS ) IF( BUILD_PLUGINS ) ADD_SUBDIRECTORY( Plugins ) ENDIF( BUILD_PLUGINS ) #----------------------------------------------------------------------- # Examples and tests #----------------------------------------------------------------------- OPTION( BUILD_EXAMPLES "Build Examples" OFF ) IF( BUILD_TESTING ) INCLUDE( "${GOFIGURE2_SOURCE_DIR}/CMake/ConfigTests.cmake" ) ENDIF( BUILD_TESTING ) IF( BUILD_EXAMPLES ) INCLUDE( "${GOFIGURE2_SOURCE_DIR}/CMake/ConfigExamples.cmake" ) ELSE( BUILD_EXAMPLES ) SET( BUILD_TESTING OFF ) ENDIF( BUILD_EXAMPLES ) #----------------------------------------------------------------------- # #----------------------------------------------------------------------- INCLUDE( GoFigure2IncludeDirectories.cmake ) CONFIGURE_FILE( "${CMAKE_CURRENT_SOURCE_DIR}/GoFigure2Config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/GoFigure2Config.cmake" @ONLY ) INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/GoFigure2Config.cmake DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Development ) IF( UNIX AND NOT APPLE ) CONFIGURE_FILE( "${CMAKE_CURRENT_SOURCE_DIR}/Resources/GoFigure2.desktop.in" "${CMAKE_CURRENT_BINARY_DIR}/GoFigure2.desktop" @ONLY ) INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/GoFigure2.desktop DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} ) ENDIF() #----------------------------------------------------------------------- # PACKAGE With CPack #----------------------------------------------------------------------- # add the uninstall support CONFIGURE_FILE( "${CMAKE_CURRENT_SOURCE_DIR}/GOFIGURE2Uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/GOFIGURE2Uninstall.cmake" @ONLY ) ADD_CUSTOM_TARGET( uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/GOFIGURE2Uninstall.cmake" ) INCLUDE( GOFIGURE2CPack.cmake ) ENDIF( SUPERBUILD ) GoFigure2-v0.9.0/Examples/0000755000175000017500000000000011667757442015152 5ustar mathieumathieuGoFigure2-v0.9.0/Examples/IO/0000755000175000017500000000000011667757442015461 5ustar mathieumathieuGoFigure2-v0.9.0/Examples/IO/GoDBImportTracksTest.cxx0000644000175000017500000000542111667757442022165 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBImport.h" #include int main(int argc, char *argv[]) { (void) argc; (void) argv; std::string ServerName = "localhost"; std::string filename; std::string Login; std::string Password; std::string DBName = "gofiguredatabase"; int ImgSessionID; std::cout<<"Enter your mysql user:"<> Login; std::cout<<"Enter your mysql password:"<> Password; std::cout<<"Enter the path to your file to import:"<> filename; std::cout<<"Enter your imagingsessionID the traces will be imported to:"<> ImgSessionID; /*std::string ServerName = "localhost"; std::string filename = argv[1]; std::string Login = argv[2]; std::string Password = argv[3]; std::string DBName = "gofiguredatabase"; int ImgSessionID = argv[4];*/ //import into the database: GoDBImport ImportHelper(ServerName, Login, Password, ImgSessionID, filename, 0); ImportHelper.ImportTracks(); } GoFigure2-v0.9.0/Examples/IO/itkmegacapturereader.cxx0000644000175000017500000000532211667757442022377 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkMegaCaptureImport.h" #include "itkMegaCaptureReader.h" #include "vtkImageData.h" int main(int argc, char **argv) { if ( argc != 2 ) { std::cout << "Usage: ./itkmegacapturereader(.exe) filename(.png)" << std::endl; return EXIT_FAILURE; } itk::MegaCaptureImport::Pointer importer = itk::MegaCaptureImport::New(); importer->SetFileName(argv[1]); importer->Update(); GoFigureFileInfoHelperMultiIndexContainer listoffiles = importer->GetOutput(); itk::MegaCaptureReader::Pointer reader = itk::MegaCaptureReader::New(); reader->SetInput(listoffiles); reader->SetFileType(GoFigure::PNG); reader->SetTimeBased(true); reader->SetTimePoint(0); reader->Update(); unsigned int minch = reader->GetMinChannel(); unsigned int maxch = reader->GetMaxChannel(); for ( unsigned int ch = minch; ch < maxch; ch++ ) { vtkImageData *image = reader->GetOutput(ch); image->Delete(); } return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/vtkPolyDataMySQLContourReader.cxx0000644000175000017500000000642711667757442024043 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "vtkPolyDataReader.h" #include "vtkPolyDataWriter.h" #include "vtkPolyData.h" #include "vtkPolyDataMySQLContourWriter.h" #include "vtkPolyDataMySQLContourReader.h" int main(int argc, char **argv) { if ( argc != 2 ) { std::cout << "Usage:" << std::endl; std::cout << "./vtkPolyDataMySQLContourWriter vtkfile" << std::endl; return EXIT_FAILURE; } vtkPolyDataReader *vtk_reader = vtkPolyDataReader::New(); vtk_reader->SetFileName(argv[1]); vtk_reader->Update(); vtkPolyData *input = vtk_reader->GetOutput(); vtkPolyDataMySQLContourWriter *convert_writer = vtkPolyDataMySQLContourWriter::New(); std::string polydata_string = convert_writer->GetMySQLText(input); vtkPolyDataMySQLContourReader *convert_reader = vtkPolyDataMySQLContourReader::New(); vtkPolyData *output = vtkPolyData::New(); output->DeepCopy( convert_reader->GetPolyData(polydata_string) ); if ( output->GetNumberOfPoints() != input->GetNumberOfPoints() ) { std::cout << "Number of points have changed!!!" << std::endl; std::cout << "output->GetNumberOfPoints() " << output->GetNumberOfPoints() << std::endl; std::cout << "input->GetNumberOfPoints() " << input->GetNumberOfPoints() << std::endl; output->Delete(); convert_reader->Delete(); convert_writer->Delete(); vtk_reader->Delete(); return EXIT_FAILURE; } output->Delete(); convert_reader->Delete(); convert_writer->Delete(); vtk_reader->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBImgSessionRowTest.cxx0000644000175000017500000000363711667757442022322 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBImgSessionRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBImgSessionRow row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/gofigurefileinfomultiindexcontainerhelper.cxx0000644000175000017500000000574311667757442026747 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoFigureFileInfoMultiIndexContainerHelper.h" #include int main(int, char **) { GoFigureFileInfoHelperMultiIndexContainer container; int plaque = 0; int r = 0; int c = 0; int xtile = 0; int ytile = 0; int ztile = 0; int xs = 0; int ys = 0; for ( int t = 0; t < 10; t++ ) { for ( int ch = 0; ch < 5; ch++ ) { for ( int z = 0; z < 20; z++ ) { std::stringstream filename; filename << "yo_p0_r0_c0_xt0_yt0_zt0_zs" << z << "_ch" << ch << "_t" << t << ".png"; container.insert( GoFigureFileInfoHelper( plaque, r, c, xtile, ytile, ztile, xs, ys, z, t, ch, filename.str() ) ); } } } std::list< std::string > list = GetAllFileNamesForGivenTCoordAndChannel(container, 5, 2); for ( std::list< std::string >::iterator it = list.begin(); it != list.end(); ++it ) { std::cout << *it << std::endl; } list = GetAllFileNamesForGivenZCoordPointAndChannel(container, 12, 4); for ( std::list< std::string >::iterator it = list.begin(); it != list.end(); ++it ) { std::cout << *it << std::endl; } return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/mhatomegacapture.cxx0000644000175000017500000001104211667757442021531 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkMetaImageReader.h" #include "vtkImageData.h" #include "vtkExtractVOI.h" #include "vtkImageData.h" #include "vtkPNGWriter.h" #include #include #include #include #include #include #include #include int main(int argc, char **argv) { if ( argc != 5 ) { std::cerr << "1-filename (mha)" << std::endl; std::cerr << "2-megacapture header (.meg)" << std::endl; std::cerr << "3-time point" << std::endl; std::cerr << "4-channel" << std::endl; return EXIT_FAILURE; } vtkMetaImageReader *reader = vtkMetaImageReader::New(); reader->SetFileName(argv[1]); reader->Update(); vtkImageData *image = reader->GetOutput(); double spacing[3]; image->GetSpacing(spacing); int dim[3]; image->GetDimensions(dim); int extent[6]; image->GetExtent(extent); std::ofstream file(argv[2], std::ios_base::app); std::string prefix( argv[2] ); prefix = prefix.substr( 0, prefix.length() - 4 ); int iTimePoint = atoi(argv[3]); int iChannel = atoi(argv[4]); int plaque = 0; int column = 0; int row = 0; int ztile = 0; int ytile = 0; int xtile = 0; char timeStr[100] = ""; struct stat buf; if ( !stat(argv[1], &buf) ) { strftime( timeStr, 100, "%Y-%m-%d %H:%M:%S", localtime(&buf.st_mtime) ); } for ( int i = extent[4]; i <= extent[5]; i++ ) { std::stringstream filename; filename << prefix << "-PL" << setfill('0') << setw(2) << plaque; filename << "-CO" << setfill('0') << setw(2) << column; filename << "-RO" << setfill('0') << setw(2) << row; filename << "-ZT" << setfill('0') << setw(2) << ztile; filename << "-YT" << setfill('0') << setw(2) << ytile; filename << "-XT" << setfill('0') << setw(2) << xtile; filename << "-TM" << setfill('0') << setw(4) << iTimePoint; filename << "-ch" << setfill('0') << setw(2) << iChannel; filename << "-zs" << setfill('0') << setw(4) << i; filename << ".png"; file << "" << std::endl; file << "Filename " << filename.str() << std::endl; file << "DateTime " << timeStr << std::endl; file << "StageX 1000" << std::endl; file << "StageY -1000" << std::endl; file << "Pinhole 44.216" << std::endl; file << "" << std::endl; vtkExtractVOI *extract = vtkExtractVOI::New(); extract->SetSampleRate(1, 1, 1); extract->SetInput(image); extract->SetVOI(extent[0], extent[1], extent[2], extent[3], i, i); extract->Update(); vtkPNGWriter *writer2d = vtkPNGWriter::New(); writer2d->SetInput( extract->GetOutput() ); writer2d->SetFileName( filename.str().c_str() ); writer2d->Write(); writer2d->Delete(); extract->Delete(); } file.close(); reader->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBIntensityRowTest.cxx0000644000175000017500000000363511667757442022226 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBIntensityRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBIntensityRow row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBTrackRowTest.cxx0000644000175000017500000000362511667757442021303 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBTrackRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBTrackRow row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBProjectRowTest.cxx0000644000175000017500000000363111667757442021642 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBProjectRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBProjectRow row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/vtkPolyDataMySQLMeshWriter.cxx0000644000175000017500000000465511667757442023361 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "vtkPolyDataReader.h" #include "vtkPolyData.h" #include "vtkPolyDataMySQLMeshWriter.h" int main(int argc, char **argv) { if ( argc != 2 ) { std::cout << "Usage:" << std::endl; std::cout << "./vtkPolyDataMySQLMeshWriter vtkfile" << std::endl; return EXIT_FAILURE; } vtkPolyDataReader *reader = vtkPolyDataReader::New(); reader->SetFileName(argv[1]); reader->Update(); vtkPolyData *contour = reader->GetOutput(); vtkPolyDataMySQLMeshWriter *convert = vtkPolyDataMySQLMeshWriter::New(); std::cout << convert->GetMySQLText(contour) << std::endl; convert->Delete(); reader->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBBookmarkRowTest.cxx0000644000175000017500000000363311667757442022003 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBBookmarkRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBBookmarkRow row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBChannelRowTest.cxx0000644000175000017500000000363111667757442021604 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBChannelRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBChannelRow row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBImageRowTest.cxx0000644000175000017500000000362511667757442021261 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBImageRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBImageRow row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/vtkPolyDataMySQLContourWriter.cxx0000644000175000017500000000467111667757442024114 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "vtkPolyDataReader.h" #include "vtkPolyData.h" #include "vtkPolyDataMySQLContourWriter.h" int main(int argc, char **argv) { if ( argc != 2 ) { std::cout << "Usage:" << std::endl; std::cout << "./vtkPolyDataMySQLContourWriter vtkfile" << std::endl; return EXIT_FAILURE; } vtkPolyDataReader *reader = vtkPolyDataReader::New(); reader->SetFileName(argv[1]); reader->Update(); vtkPolyData *contour = reader->GetOutput(); vtkPolyDataMySQLContourWriter *convert = vtkPolyDataMySQLContourWriter::New(); std::cout << convert->GetMySQLText(contour) << std::endl; convert->Delete(); reader->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBLineageRowTest.cxx0000644000175000017500000000363111667757442021600 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBLineageRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBLineageRow row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBTraceRowTest.cxx0000644000175000017500000000415611667757442021275 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBTraceRow.h" class GoDBTraceRowTestHelper : public GoDBTraceRow { public: GoDBTraceRowTestHelper() : GoDBTraceRow() { } ~GoDBTraceRowTestHelper() { } int SaveInDB(vtkMySQLDatabase *) { return 0; } }; int main(int argc, char **argv) { (void)argc; (void)argv; GoDBTraceRowTestHelper row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/MegaCaptureHeaderReaderTest.cxx0000644000175000017500000000573311667757442023506 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "MegaCaptureHeaderReader.h" #include #include int main(int argc, char **argv) { if ( argc != 2 ) { std::cerr << "Requires 1 argument: " << std::endl; std::cerr << "1-FileName (.meg)" << std::endl; return EXIT_FAILURE; } MegaCaptureHeaderReader reader(argv[1]); reader.Read(); std::cout << "TimeInterval * " << reader.m_TimeInterval << std::endl; std::cout << "VoxelSizeX * " << reader.m_VoxelSizeX << std::endl; std::cout << "VoxelSizeY * " << reader.m_VoxelSizeY << std::endl; std::cout << "VoxelSizeZ * " << reader.m_VoxelSizeZ << std::endl; std::cout << "DimensionX * " << reader.m_DimensionX << std::endl; std::cout << "DimensionY * " << reader.m_DimensionY << std::endl; std::cout << "ChannelDepth * " << reader.m_ChannelDepth << std::endl; std::cout << "Number Of Channels * " << reader.m_NumberOfChannels << std::endl; for ( unsigned int i = 0; i < reader.m_NumberOfChannels; i++ ) { std::cout << "Channel Color " << i << " * [ " << reader.m_ChannelColor[i][0] << ", " << reader.m_ChannelColor[i][1] << ", " << reader.m_ChannelColor[i][2] << " ]" << std::endl; } return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/CMakeLists.txt0000644000175000017500000000437111667757442020226 0ustar mathieumathieuSET( QGOIO_EXAMPLES_SRC megacaptureimport gofigurefileinfomultiindexcontainerhelper MegaCaptureHeaderReaderTest lsm2mha lsmtomegacapture itkmegacapturereader GenerateImagingSessionPartInMegaCaptureHeaderFromMHA mhatomegacapture vtkPolyDataMySQLContourReader vtkPolyDataMySQLMeshReader vtkPolyDataMySQLContourWriter vtkPolyDataMySQLMeshWriter vtkPolyDataMySQLTrack GoDBImportTracksTest # kishmeshtextfilereader # trackTextFilesReader ) SET( GODB_SRC GoDBTraceRowTest GoDBContourRowTest GoDBMeshRowTest GoDBTrackRowTest GoDBLineageRowTest GoDBColorRowTest GoDBChannelRowTest GoDBBookmarkRowTest GoDBImageRowTest GoDBIntensityRowTest GoDBProjectRowTest GoDBCoordinateRowTest GoDBImgSessionRowTest ) SET( QGOIO_EXAMPLES_SRC ${QGOIO_EXAMPLES_SRC} ${GODB_SRC} ) FOREACH( var ${QGOIO_EXAMPLES_SRC} ) ADD_EXECUTABLE( ${var} ${var}.cxx ) TARGET_LINK_LIBRARIES( ${var} QGoIO ) ENDFOREACH( var ${QGOIO_EXAMPLES_SRC} ) ADD_TEST( gofigurefileinfomultiindexcontainerhelperTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gofigurefileinfomultiindexcontainerhelper ) ADD_TEST( vtkPolyDataMySQLContourReaderTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vtkPolyDataMySQLContourReader ${TESTING_DATA_PATH}/contour.vtk ) ADD_TEST( vtkPolyDataMySQLMeshReaderTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vtkPolyDataMySQLMeshReader ${TESTING_DATA_PATH}/sphere.vtk ) ADD_TEST( vtkPolyDataMySQLTrackTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vtkPolyDataMySQLTrack ) ADD_TEST( vtkPolyDataMySQLContourWriterTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vtkPolyDataMySQLContourWriter ${TESTING_DATA_PATH}/contour.vtk ) ADD_TEST( vtkPolyDataMySQLMeshWriterTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vtkPolyDataMySQLMeshWriter ${TESTING_DATA_PATH}/sphere.vtk ) ADD_TEST( MegaCaptureHeaderReaderTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/MegaCaptureHeaderReaderTest ${GOFIGURE2_BINARY_DIR}/Testing/earpax2isl11/earpax2isl11.lsm.meg ) ADD_TEST( lsmtomegacaptureTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lsmtomegacapture ${TESTING_DATA_PATH}/earpax2isl11.lsm ${GOFIGURE2_BINARY_DIR}/Testing/earpax2isl11_lsmtomegacapture/ png ) FOREACH( var ${GODB_SRC} ) ADD_TEST( ${var} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${var} ) ENDFOREACH( var ${GODB_SRC} ) GoFigure2-v0.9.0/Examples/IO/vtkPolyDataMySQLMeshReader.cxx0000644000175000017500000000640211667757442023277 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "vtkPolyDataReader.h" #include "vtkPolyDataWriter.h" #include "vtkPolyData.h" #include "vtkPolyDataMySQLMeshWriter.h" #include "vtkPolyDataMySQLMeshReader.h" int main(int argc, char **argv) { if ( argc != 2 ) { std::cout << "Usage:" << std::endl; std::cout << "./vtkPolyDataMySQLMeshWriter vtkfile" << std::endl; return EXIT_FAILURE; } vtkPolyDataReader *vtk_reader = vtkPolyDataReader::New(); vtk_reader->SetFileName(argv[1]); vtk_reader->Update(); vtkPolyData *input = vtk_reader->GetOutput(); vtkPolyDataMySQLMeshWriter *convert_writer = vtkPolyDataMySQLMeshWriter::New(); std::string polydata_string = convert_writer->GetMySQLText(input); vtkPolyDataMySQLMeshReader *convert_reader = vtkPolyDataMySQLMeshReader::New(); vtkPolyData *output = vtkPolyData::New(); output->DeepCopy( convert_reader->GetPolyData(polydata_string) ); if ( output->GetNumberOfPoints() != input->GetNumberOfPoints() ) { std::cout << "Number of points have changed!!!" << std::endl; std::cout << "output->GetNumberOfPoints() " << output->GetNumberOfPoints() << std::endl; std::cout << "input->GetNumberOfPoints() " << input->GetNumberOfPoints() << std::endl; output->Delete(); convert_reader->Delete(); convert_writer->Delete(); vtk_reader->Delete(); return EXIT_FAILURE; } output->Delete(); convert_reader->Delete(); convert_writer->Delete(); vtk_reader->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBContourRowTest.cxx0000644000175000017500000000363111667757442021665 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBContourRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBContourRow row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/vtkPolyDataMySQLTrack.cxx0000644000175000017500000000534011667757442022324 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "vtkSmartPointer.h" #include "vtkPolyDataWriter.h" #include "vtkPolyData.h" #include "vtkPolyDataMySQLTrackReader.h" #include "vtkPolyDataMySQLTrackWriter.h" int main(int argc, char **argv) { (void)argc; (void)argv; vtkSmartPointer< vtkPolyDataMySQLTrackReader > track_reader = vtkSmartPointer< vtkPolyDataMySQLTrackReader >::New(); std::string stringFromDB = "2 1 1 1 1 2 2 2 2 "; vtkSmartPointer< vtkPolyData > input = vtkSmartPointer< vtkPolyData >::New(); input->ShallowCopy( track_reader->GetPolyData(stringFromDB) ); vtkSmartPointer< vtkPolyDataMySQLTrackWriter > track_writer = vtkSmartPointer< vtkPolyDataMySQLTrackWriter >::New(); std::string output = track_writer->GetMySQLText(input); std::cout << "before: " << stringFromDB << std::endl; std::cout << "after: " << output << std::endl; if ( stringFromDB.compare(output) != 0 ) { return EXIT_FAILURE; } else { return EXIT_SUCCESS; } }GoFigure2-v0.9.0/Examples/IO/lsm2mha.cxx0000644000175000017500000001671311667757442017560 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkLSMReader.h" #include #include #include #include "vtkMetaImageWriter.h" #include "vtkImageAppendComponents.h" #include "vtkIndent.h" #include "vtkImageData.h" using namespace std; // Note alex // This code works but is an early version of the // code now in GoFigure App. // /todo update this code with the more efficient // code from GoFigure int main(int argc, char *argv[]) { const unsigned int Dimension = 3; if ( argc < 5 ) { std::cout << "Usage: "; std::cout << "(exe) FileName IsChannelToBeBlended DirCh1 DirCh2"; std::cout << std::endl; return 0; } if ( !( atoi(argv[2]) == 0 || atoi(argv[2]) == 1 ) ) { std::cout << "Second argument must be either 0 or 1." << std::endl; return 0; } //read the LSM file - can be multiple channels and time-points: vtkLSMReader *reader = vtkLSMReader::New(); reader->SetFileName(argv[1]); reader->Update(); // Get the number of time-points int NumberOfTimePoints = reader->GetNumberOfTimePoints(); // Get the number of channels int NumberOfChannels = reader->GetNumberOfChannels(); // Print out the number of time points and channels std::cout << NumberOfTimePoints << std::endl; std::cout << NumberOfChannels << std::endl; // Get the name of the file without the path unsigned int j = 0; unsigned int len = strlen(argv[1]); for ( unsigned int i = len - 1; i != 0; i-- ) { if ( argv[1][i] == '/' ) { j = i; break; } } j++; char *fname = new char[len - j + 1]; for ( unsigned int i = 0; i < len - j + 1; i++ ) { fname[i] = argv[1][j + i]; } vtkMetaImageWriter *writer = vtkMetaImageWriter::New(); writer->SetFileDimensionality(Dimension); for ( int timePoint = 0; timePoint < NumberOfTimePoints; timePoint++ ) { if ( atoi(argv[2]) == 0 || NumberOfChannels == 1 ) { for ( int channel = 0; channel < NumberOfChannels; channel++ ) { // Select the specified time-point and channel for write-out vtkLSMReader *treader = vtkLSMReader::New(); treader->SetFileName(argv[1]); treader->SetUpdateTimePoint(timePoint); treader->SetUpdateChannel(channel); treader->Update(); // Determine the name of the file std::stringstream namebuffer; namebuffer << argv[3 + channel]; namebuffer << fname; namebuffer << "_T_" << timePoint; namebuffer << "_C_" << channel; namebuffer << ".mha"; std::cout << namebuffer.str().c_str() << std::endl; // Write-out writer->SetFileName( namebuffer.str().c_str() ); writer->SetInputConnection( treader->GetOutputPort() ); writer->Write(); } } else { // read the first channel, then Append other channel as components // of myImage. Finally, write it. // note that jpgwriter only handles 1 or 3 comp images. // if only one channel, no compositing // if two channel, compose with a dummy (empty) third channel // if three channels, no problem // if more than three channel, we should blend (TBD) if ( NumberOfChannels < 4 ) { vtkImageData *myImage_ch1; vtkImageData *myImage_ch2; vtkImageData *myImage_ch3; { vtkLSMReader *treader = vtkLSMReader::New(); treader->SetFileName(argv[1]); treader->SetUpdateTimePoint(timePoint); treader->SetUpdateChannel(0); treader->Update(); myImage_ch1 = treader->GetOutput(); } { vtkLSMReader *treader = vtkLSMReader::New(); treader->SetFileName(argv[1]); treader->SetUpdateTimePoint(timePoint); treader->SetUpdateChannel(1); treader->Update(); myImage_ch2 = treader->GetOutput(); } { vtkLSMReader *treader = vtkLSMReader::New(); treader->SetFileName(argv[1]); treader->SetUpdateTimePoint(timePoint); treader->SetUpdateChannel(2); treader->Update(); std::cout << "Third reader done." << std::endl; int *dimensions = treader->GetDimensions(); int flatindex = dimensions[0] * dimensions[1] * dimensions[2]; myImage_ch3 = treader->GetOutput(); if ( NumberOfChannels == 2 ) // dummy third channel { // here we suppose the type to be char // to be improved char *ptr = (char *)( myImage_ch3->GetScalarPointer() ); for ( int k = 0; k < flatindex; k++ ) { *ptr++ = 0; } } std::cout << "third channel ready." << std::endl; } vtkImageAppendComponents *appendFilter1 = vtkImageAppendComponents::New(); appendFilter1->AddInput(myImage_ch1); appendFilter1->AddInput(myImage_ch2); appendFilter1->Update(); std::cout << "Two first channel composed." << std::endl; vtkImageAppendComponents *appendFilter2 = vtkImageAppendComponents::New(); appendFilter2->AddInput( appendFilter1->GetOutput() ); appendFilter2->AddInput(myImage_ch3); appendFilter2->Update(); std::cout << "Third channel composed." << std::endl; std::stringstream namebuffer; namebuffer << argv[1]; namebuffer << "_T_" << timePoint; namebuffer << ".mha"; std::cout << namebuffer.str().c_str() << std::endl; writer->SetFileName( namebuffer.str().c_str() ); writer->SetInput( appendFilter2->GetOutput() ); writer->Write(); } else { // num of channel > 3 // TBD } } } return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBCoordinateRowTest.cxx0000644000175000017500000000363711667757442022331 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBCoordinateRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBCoordinateRow row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBColorRowTest.cxx0000644000175000017500000000362511667757442021315 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBColorRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBColorRow row; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/megacaptureimport.cxx0000644000175000017500000000464011667757442021741 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkMegaCaptureImport.h" #include int main(int argc, char **argv) { if ( argc != 2 ) { std::cout << "Usage: ./megacaptureimport(.exe) filename(.jpg)" << std::endl; return EXIT_FAILURE; } itk::MegaCaptureImport::Pointer importer = itk::MegaCaptureImport::New(); importer->SetFileName(argv[1]); importer->Update(); GoFigureFileInfoHelperMultiIndexContainer listoffiles = importer->GetOutput(); for ( GoFigureFileInfoHelperMultiIndexContainer::iterator it = listoffiles.begin(); it != listoffiles.end(); ++it ) { std::cout << it->m_Filename << std::endl; } return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/lsmtomegacapture.cxx0000644000175000017500000000516211667757442021565 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "LSMToMegaCapture.h" int main(int argc, char **argv) { if ( argc != 4 ) { std::cerr << "lsmtomegacapture requires 3 argument:" << std::endl; std::cerr << "1-lsm filename" << std::endl; std::cerr << "2-Output directory" << std::endl; std::cerr << "3-png or tiff (png by default)" << std::endl; return EXIT_FAILURE; } std::string type(argv[3]); GoFigure::FileType filetype = GoFigure::PNG; if ( type.compare("tiff") == 0 ) { filetype = GoFigure::TIFF; } LSMToMegaCapture converter; converter.SetFileName(argv[1]); converter.SetPlaque(0); converter.SetRow(0); converter.SetColumn(0); converter.SetXTile(0); converter.SetYTile(0); converter.SetZTile(0); converter.SetOutputFileType(filetype); converter.Export(argv[2]); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GenerateImagingSessionPartInMegaCaptureHeaderFromMHA.cxx0000644000175000017500000001136511667757442030324 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkMetaImageReader.h" #include "vtkImageData.h" #include #include int main(int argc, char **argv) { if ( argc != 6 ) { std::cerr << "1-mha filename" << std::endl; std::cerr << "2-megacapture header (*.meg)" << std::endl; std::cerr << "3-Time Interval (in sec)" << std::endl; std::cerr << "4-Number of time points" << std::endl; std::cerr << "5-Number of channels" << std::endl; return EXIT_FAILURE; } vtkMetaImageReader *reader = vtkMetaImageReader::New(); reader->SetFileName(argv[1]); reader->Update(); vtkImageData *image = reader->GetOutput(); double spacing[3]; image->GetSpacing(spacing); int dim[3]; image->GetDimensions(dim); int extent[6]; image->GetExtent(extent); double iTimeInterval = atof(argv[3]); int iNumberOfTimePoints = atoi(argv[4]); int iNumberOfChannels = atoi(argv[5]); std::ofstream file(argv[2]); file << "MegaCapture" << std::endl; file << "" << std::endl; file << "Version 3.0" << std::endl; file << "ExperimentTitle " << std::endl; file << "ExperimentDescription " << std::endl; file << "TimeInterval " << iTimeInterval << std::endl; file << "Objective " << std::endl; file << "VoxelSizeX " << spacing[0] << std::endl; file << "VoxelSizeY " << spacing[1] << std::endl; file << "VoxelSizeZ " << spacing[2] << std::endl; file << "DimensionX " << dim[0] << std::endl; file << "DimensionY " << dim[1] << std::endl; file << "DimensionPL 1" << std::endl; file << "DimensionCO 1" << std::endl; file << "DimensionRO 1" << std::endl; file << "DimensionZT 1" << std::endl; file << "DimensionYT 1" << std::endl; file << "DimensionXT 1" << std::endl; file << "DimensionTM " << iNumberOfTimePoints << std::endl; file << "DimensionZS " << dim[2] << std::endl; if ( iNumberOfChannels == 1 ) { file << "DimensionCH 1" << std::endl; int blue = 255; file << "ChannelColor00 " << blue << std::endl; } else { if( iNumberOfChannels == 2 ) { file << "DimensionCH 2" << std::endl; int green = 255; int blue = 0; file << "ChannelColor00 " << green * 256 + blue << std::endl; green = 0; blue = 255; file << "ChannelColor01 " << green * 256 + blue << std::endl; } else { file << "DimensionCH 3" << std::endl; int red = 255; int green = 0; int blue = 0; file << "ChannelColor00 " << red * 256 * 256 + green * 256 + blue << std::endl; red = 0; green = 255; blue = 0; file << "ChannelColor01 " << red * 256 * 256 + green * 256 + blue << std::endl; red = 0; green = 0; blue = 255; file << "ChannelColor02 " << red * 256 * 256 + green * 256 + blue << std::endl; } } file << "ChannelDepth 8" << std::endl; file << "FileType PNG" << std::endl; file << "" << std::endl; file.close(); reader->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/IO/GoDBMeshRowTest.cxx0000644000175000017500000000674411667757442021140 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "GoDBMeshRow.h" int main(int argc, char **argv) { (void)argc; (void)argv; GoDBMeshRow row; std::cout << "std::cout TEST... " << std::endl; std::cout << row << std::endl; std::cout << "DONE!" << std::endl; std::cout << std::endl; std::cout << "GetTableName TEST... " << std::endl; std::cout << row.GetTableName() << std::endl; std::cout << "DONE!" << std::endl; std::cout << "GetTableIDName TEST... " << std::endl; std::cout << row.GetTableIDName() << std::endl; std::cout << "DONE!" << std::endl; std::cout << std::endl; std::cout << "PrintValues TEST... " << std::endl; std::cout << row.PrintValues() << std::endl; std::cout << "DONE!" << std::endl; std::cout << std::endl; std::cout << "PrintColumnNames TEST... " << std::endl; std::cout << row.PrintColumnNames() << std::endl; std::cout << "DONE!" << std::endl; std::cout << std::endl; std::cout << "iterator TEST... " << std::endl; GoDBMeshRow::StringMapIterator it = row.MapBegin(); while ( it != row.MapEnd() ) { ++it; } std::cout << "DONE!" << std::endl; std::cout << std::endl; std::cout << "const iterator TEST... " << std::endl; GoDBMeshRow::StringMapConstIterator c_it = row.ConstMapBegin(); while ( c_it != row.ConstMapEnd() ) { ++c_it; } std::cout << "DONE!" << std::endl; std::cout << std::endl; std::cout << "erroneous GetMapValue TEST... " << std::endl; std::cout << row.GetMapValue("contour") << std::endl; std::cout << "DONE!" << std::endl; std::cout << std::endl; std::cout << "GetMapValue TEST... " << std::endl; std::cout << row.GetMapValue("CellTypeID") << std::endl; std::cout << "DONE!" << std::endl; std::cout << std::endl; return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/Filters/0000755000175000017500000000000011667757442016562 5ustar mathieumathieuGoFigure2-v0.9.0/Examples/Filters/itkvtkPolyDatatoBinaryMaskImageFilterTest.cxx0000644000175000017500000000722611667757442027564 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "vtkSphereSource.h" #include "itkvtkPolyDataToBinaryMaskImageFilter.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cerr << "./itkvtkPolyDataToBinaryMaskImageFilter(.exe) takes 2 arguments" << std::endl; std::cerr << "1- input image filename" << std::endl; std::cerr << "2- output image filename" << std::endl; return EXIT_FAILURE; } const unsigned int Dimension = 3; typedef unsigned char PixelType; typedef itk::Image< PixelType, Dimension > ImageType; typedef itk::ImageFileReader< ImageType > ReaderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(argv[1]); reader->Update(); ImageType::Pointer image = reader->GetOutput(); ImageType::SizeType size = image->GetLargestPossibleRegion().GetSize(); ImageType::PointType org = image->GetOrigin(); ImageType::SpacingType spacing = image->GetSpacing(); ImageType::PointType center; center[0] = org[0] + 0.5 * spacing[0] * size[0]; center[1] = org[1] + 0.5 * spacing[1] * size[1]; center[2] = org[2] + 0.5 * spacing[2] * size[2]; vtkSphereSource *sphere_source = vtkSphereSource::New(); sphere_source->SetCenter(center[0], center[1], center[2]); sphere_source->SetRadius(0.25 * spacing[0] * size[0]); sphere_source->Update(); typedef itk::vtkPolyDataToBinaryMaskImageFilter< ImageType, ImageType > BinarizerType; BinarizerType::Pointer binarize = BinarizerType::New(); binarize->SetInput( reader->GetOutput() ); binarize->SetPolyData( sphere_source->GetOutput() ); binarize->Update(); typedef itk::ImageFileWriter< ImageType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetInput( binarize->GetOutput() ); writer->SetFileName(argv[2]); writer->Write(); sphere_source->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/Filters/ContourToMeshFilterTest.cxx0000644000175000017500000001147311667757442024073 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkPolyData.h" #include "vtkSmartPointer.h" #include "vtkCellArray.h" #include "vtkMath.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include #include "ContourToMeshFilter.h" void CreateCircle(const double & iZ, const double & iRadius, const int & iResolution, vtkPolyData *ioContour) { vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New(); points->SetNumberOfPoints(iResolution); vtkSmartPointer< vtkCellArray > lines = vtkSmartPointer< vtkCellArray >::New(); lines->Allocate(1, iResolution); vtkIdType *lineIndices = new vtkIdType[iResolution + 1]; for ( int i = 0; i < iResolution; ++i ) { double theta = vtkMath::RadiansFromDegrees( 360. * i / double(iResolution) ); double x = iRadius * cos(theta); double y = iRadius * sin(theta); points->SetPoint(i, x, y, iZ); lineIndices[i] = static_cast< vtkIdType >( i ); } lineIndices[iResolution] = 0; lines->InsertNextCell(iResolution + 1, lineIndices); delete[] lineIndices; ioContour->Initialize(); ioContour->SetLines(lines); ioContour->SetPoints(points); } int main(int argc, char *argv[]) { if ( argc != 2 ) { std::cerr << "./ContourToMeshFilter(.exe) takes 1 arguments" << std::endl; std::cerr << "1- boolean value (test)" << std::endl; return EXIT_FAILURE; } int resolution = 100; double z = 0.; double sphereRadius = 1.; double zmin = -0.9 * sphereRadius; double zmax = -zmin; std::vector< vtkSmartPointer< vtkPolyData > > contours(20); for ( int i = 0; i < 20; i++ ) { if ( ( i < 4 ) || ( i > 10 ) ) { double u = static_cast< double >( i ) / 20.; z = ( 1. - u ) * zmin + u * zmax; double radius = sqrt(sphereRadius * sphereRadius - z * z); contours[i] = vtkSmartPointer< vtkPolyData >::New(); CreateCircle(z, radius, resolution, contours[i]); } else { contours[i] = NULL; } } typedef itk::ContourToMeshFilter< std::vector< vtkSmartPointer< vtkPolyData > > > FilterType; FilterType::Pointer filter = FilterType::New(); filter->ProcessContours(contours); vtkSmartPointer< vtkPolyDataMapper > mapper = vtkSmartPointer< vtkPolyDataMapper >::New(); mapper->SetInput( filter->GetOutput() ); vtkSmartPointer< vtkActor > actor = vtkSmartPointer< vtkActor >::New(); actor->SetMapper(mapper); vtkSmartPointer< vtkRenderer > renderer = vtkSmartPointer< vtkRenderer >::New(); renderer->AddActor(actor); vtkSmartPointer< vtkRenderWindow > renwin = vtkSmartPointer< vtkRenderWindow >::New(); renwin->AddRenderer(renderer); vtkSmartPointer< vtkRenderWindowInteractor > iren = vtkSmartPointer< vtkRenderWindowInteractor >::New(); iren->SetRenderWindow(renwin); renwin->Render(); if ( atoi(argv[1]) == 1 ) { iren->CreateOneShotTimer(1); } else { iren->Start(); } filter->GetOutput()->Delete(); return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/Filters/MeshToContourFilterTest.cxx0000644000175000017500000000737411667757442024100 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkSphereSource.h" #include "vtkPolyData.h" #include "vtkSmartPointer.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "MeshToContourFilter.h" int main(int argc, char *argv[]) { if ( argc != 2 ) { std::cerr << "./ContourToMeshFilter(.exe) takes 1 arguments" << std::endl; std::cerr << "1- boolean value (test)" << std::endl; return EXIT_FAILURE; } // create sphere vtkSmartPointer sphereSource2 = vtkSmartPointer::New(); sphereSource2->SetRadius(10); sphereSource2->SetCenter(25,0,0); sphereSource2->SetThetaResolution(10); sphereSource2->SetPhiResolution(10); sphereSource2->Update(); // split sphere MeshToContourFilter filter; filter.SetInput(sphereSource2->GetOutput()); filter.SetSpacing(1, 1, 1); std::map output = filter.ExtractPolyData( MeshToContourFilter::XY ); vtkSmartPointer< vtkRenderer > renderer = vtkSmartPointer< vtkRenderer >::New(); std::map::iterator it = output.begin(); while (it!=output.end()) { vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInput( it->second ); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); renderer->AddActor(actor); ++it; } vtkSmartPointer< vtkRenderWindow > renwin = vtkSmartPointer< vtkRenderWindow >::New(); renwin->AddRenderer(renderer); vtkSmartPointer< vtkRenderWindowInteractor > iren = vtkSmartPointer< vtkRenderWindowInteractor >::New(); iren->SetRenderWindow(renwin); renwin->Render(); if ( atoi(argv[1]) == 1 ) { iren->CreateOneShotTimer(1); } else { iren->Start(); } // clean map it = output.begin(); while (it!=output.end()) { (it->second)->Delete(); ++it; } return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/Filters/ConvertMeshesToLabelImageFilter.cxx0000644000175000017500000001050111667757442025444 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkConvertMeshesToLabelImageFilter.h" #include "itkVTKPolyDataReader.h" #include "itkNumericSeriesFileNames.h" #include int main (int argc, char *argv[]) { if (argc < 5) { std::cout << "Usage: " << argv[0] << " InfoVolume InputMeshFormat OutputVolume numOfThreads numOfMeshes" << std::endl; return EXIT_FAILURE; } const unsigned int Dimension = 3; typedef itk::Image< unsigned int, Dimension > SegmentImageType; typedef itk::ImageFileReader< SegmentImageType > ReaderType; typedef itk::ConvertMeshesToLabelImageFilter< SegmentImageType > ImageSourceType; typedef ImageSourceType::MeshType MeshType; typedef itk::VTKPolyDataReader< MeshType > MeshReaderType; typedef itk::NumericSeriesFileNames NameGeneratorType; typedef itk::ImageFileWriter< SegmentImageType > WriterType; // Define all of the variables unsigned int numOfThreads = atoi( argv[4] ); unsigned int numOfMeshes = atoi( argv[5] ); ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName ( argv[1] ); reader->Update(); SegmentImageType::Pointer input = reader->GetOutput(); SegmentImageType::Pointer m_OutputImage = SegmentImageType::New(); m_OutputImage->CopyInformation( input ); m_OutputImage->SetRegions( input->GetLargestPossibleRegion() ); m_OutputImage->Allocate(); m_OutputImage->FillBuffer( 0 ); NameGeneratorType::Pointer nameGeneratorOutput = NameGeneratorType::New(); nameGeneratorOutput->SetSeriesFormat( argv[2] ); nameGeneratorOutput->SetStartIndex( 1 ); nameGeneratorOutput->SetEndIndex( numOfMeshes ); nameGeneratorOutput->SetIncrementIndex( 1 ); ImageSourceType::Pointer imageSource = ImageSourceType::New(); ImageSourceType::MeshVectorType meshes( numOfMeshes ); for( unsigned int i = 0; i < numOfMeshes; ++i ) { std::stringstream ss; ss << nameGeneratorOutput->GetFileNames()[i]; // std::cout << argv[0] << " writing " << ss.str() << std::endl; MeshReaderType::Pointer meshReader = MeshReaderType::New( ); meshReader->SetFileName( ss.str().c_str() ); meshReader->Update(); meshes[i] = meshReader->GetOutput(); meshes[i]->DisconnectPipeline(); } imageSource->SetInput( m_OutputImage ); imageSource->SetNumberOfThreads( numOfThreads ); imageSource->SetMeshes( meshes ); imageSource->Update(); WriterType::Pointer writer = WriterType::New( ); writer->SetInput( m_OutputImage ); writer->SetFileName( argv[3] ); writer->Update(); return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/Filters/SingleCellSplitImageFilter.cxx0000644000175000017500000000655611667757442024470 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkPointSet.h" #include "itkSingleCellSplitImageFilter.h" #include #include int main ( int argc, char* argv[] ) { if ( argc < 3 ) { std::cerr << "Usage: " << std::endl; std::cerr << argv[0] << " input output" << std::endl; return EXIT_FAILURE; } const unsigned int Dimension = 2; typedef itk::Image< unsigned char, Dimension > ImageType; typedef ImageType::PointType ImagePointType; typedef itk::PointSet< ImagePointType::CoordRepType, 2 > PointSetType; typedef itk::ImageFileReader< ImageType > ReaderType; typedef itk::ImageFileWriter< ImageType > WriterType; typedef itk::SingleCellSplitImageFilter< ImageType, PointSetType > FilterType; ImageType::Pointer input; { ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName ( argv[1] ); reader->Update(); input = reader->GetOutput(); input->DisconnectPipeline(); } FilterType::Pointer filter = FilterType::New(); filter->SetInput ( input ); filter->SetForegroundValue( 1 ); PointSetType::Pointer seeds = PointSetType::New(); ImagePointType p; p[0] = 40; p[1] = 40; seeds->SetPoint( 0, p ); p[0] = 60; p[1] = 60; seeds->SetPoint( 1, p ); filter->SetSeeds( seeds ); filter->Update(); WriterType::Pointer writer = WriterType::New(); writer->SetInput ( filter->GetOutput() ); writer->SetFileName ( argv[2] ); try { writer->Update(); } catch ( itk::ExceptionObject e ) { std::cerr << "Error: " << e << std::endl; } return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/Filters/CMakeLists.txt0000644000175000017500000000760511667757442021332 0ustar mathieumathieuADD_EXECUTABLE( itkvtkPolyDatatoBinaryMaskImageFilterTest itkvtkPolyDatatoBinaryMaskImageFilterTest.cxx ) TARGET_LINK_LIBRARIES( itkvtkPolyDatatoBinaryMaskImageFilterTest ${ITK_LIBRARIES} vtkGraphics vtkHybrid ) ADD_TEST( itkvtkPolyDatatoBinaryMaskImageFilterTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/itkvtkPolyDatatoBinaryMaskImageFilterTest ${TESTING_DATA_PATH}/Circle3D.mhd temp.mhd ) ADD_EXECUTABLE( itkBinaryMaskImageToGoFigureMeshAttributesTest itkBinaryMaskImageToGoFigureMeshAttributesTest.cxx ) TARGET_LINK_LIBRARIES( itkBinaryMaskImageToGoFigureMeshAttributesTest QGoGui ) ADD_TEST( itkBinaryMaskImageToGoFigureMeshAttributesTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/itkBinaryMaskImageToGoFigureMeshAttributesTest ${TESTING_DATA_PATH}/Circle3D.mhd temp.mhd ) ADD_EXECUTABLE( itkvtkPolyDataToGoFigureMeshAttributesTest itkvtkPolyDataToGoFigureMeshAttributesTest.cxx ) TARGET_LINK_LIBRARIES( itkvtkPolyDataToGoFigureMeshAttributesTest QGoGui vtkGraphics vtkHybrid ) ADD_TEST( itkvtkPolyDataToGoFigureMeshAttributesTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/itkvtkPolyDataToGoFigureMeshAttributesTest ${TESTING_DATA_PATH}/Circle3D.mhd ) SET_TESTS_PROPERTIES( itkBinaryMaskImageToGoFigureMeshAttributesTest PROPERTIES DEPENDS itkvtkPolyDatatoBinaryMaskImageFilterTest ) ADD_EXECUTABLE( ContourToMeshFilterTest ContourToMeshFilterTest.cxx ) TARGET_LINK_LIBRARIES( ContourToMeshFilterTest PoissonReconstruction vtkHybrid vtkRenderingAddOn2 ${ITK_LIBRARIES} ) ADD_TEST( ContourToMeshFilterTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ContourToMeshFilterTest 1 ) ADD_EXECUTABLE( MeshToContourFilterTest MeshToContourFilterTest.cxx ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Mesh/MeshToContourFilter.cxx ) TARGET_LINK_LIBRARIES( MeshToContourFilterTest vtkHybrid ) ADD_TEST( MeshToContourFilterTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/MeshToContourFilterTest 1 ) #ADD_EXECUTABLE( singleCellSplitImageFilter # SingleCellSplitImageFilter.cxx # ) #TARGET_LINK_LIBRARIES( # singleCellSplitImageFilter # ITKReview # ITKIO # ) ADD_EXECUTABLE( cellMergeImageFilter CellMergeImageFilter.cxx ) TARGET_LINK_LIBRARIES( cellMergeImageFilter vtkHybrid ) #ADD_TEST( singleCellSplitImageFilterTest # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/singleCellSplitImageFilter # ${TESTING_DATA_PATH}/MultiphaseCells2D.png # split.mhd #) ADD_EXECUTABLE( itkvtkMeshSplitterDanielssonImageFilterTest itkvtkMeshSplitterDanielssonImageFilterTest.cxx ) TARGET_LINK_LIBRARIES( itkvtkMeshSplitterDanielssonImageFilterTest QGoGui ) ADD_TEST( itkvtkMeshSplitterDanielssonImageFilterTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/itkvtkMeshSplitterDanielssonImageFilterTest ${TESTING_DATA_PATH}/Circle3D.mhd ) ADD_EXECUTABLE( ExtractMeshesFromLabelImageFilter ExtractMeshesFromLabelImageFilter.cxx ) TARGET_LINK_LIBRARIES( ExtractMeshesFromLabelImageFilter #ITKCommon #ITKIO #ITKReview ${ITK_LIBRARIES} ) ADD_EXECUTABLE(ConvertMeshesToLabelImageFilter ConvertMeshesToLabelImageFilter.cxx ) TARGET_LINK_LIBRARIES( ConvertMeshesToLabelImageFilter # ITKIO ITKReview ${ITK_LIBRARIES} ) ADD_EXECUTABLE( itkQuadEdgeMeshTovtkPolyDataTest itkQuadEdgeMeshTovtkPolyDataTest.cxx ) TARGET_LINK_LIBRARIES( itkQuadEdgeMeshTovtkPolyDataTest #ITKCommon ${ITK_LIBRARIES} vtkHybrid ) ADD_EXECUTABLE( itkvtkPolyDataToitkQuadEdgeMeshTest itkvtkPolyDataToitkQuadEdgeMeshTest.cxx ) TARGET_LINK_LIBRARIES( itkvtkPolyDataToitkQuadEdgeMeshTest #ITKCommon ${ITK_LIBRARIES} vtkHybrid ) ADD_TEST( itkvtkPolyDataToitkQuadEdgeMeshTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/itkvtkPolyDataToitkQuadEdgeMeshTest ) ADD_EXECUTABLE( itkvtkMeshMergeConvexHullFilterTest itkvtkMeshMergeConvexHullFilterTest.cxx ) TARGET_LINK_LIBRARIES( itkvtkMeshMergeConvexHullFilterTest QGoGui ) ADD_TEST( itkvtkMeshMergeConvexHullFilterTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/itkvtkMeshMergeConvexHullFilterTest ${TESTING_DATA_PATH}/Circle3D.mhd ) GoFigure2-v0.9.0/Examples/Filters/itkvtkPolyDataToitkQuadEdgeMeshTest.cxx0000644000175000017500000000517711667757442026362 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkSphereSource.h" #include "itkQuadEdgeMesh.h" #include "itkvtkPolyDataToitkQuadEdgeMesh.h" #include "itkVTKPolyDataWriter.h" int main( int , char** ) { vtkSmartPointer< vtkSphereSource > sphere_source = vtkSmartPointer< vtkSphereSource >::New(); sphere_source->SetCenter( 0., 0., 0. ); sphere_source->Update(); typedef itk::QuadEdgeMesh< double, 3 > MeshType; typedef itk::vtkPolyDataToitkQuadEdgeMesh< MeshType > ConverterType; ConverterType::Pointer converter = ConverterType::New(); converter->SetInput( sphere_source->GetOutput() ); converter->Update(); MeshType::Pointer mesh = converter->GetOutput(); typedef itk::VTKPolyDataWriter< MeshType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetInput( mesh ); writer->SetFileName( "ConvertVTKtoITKMesh.vtk" ); writer->Update(); return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/Filters/itkBinaryMaskImageToGoFigureMeshAttributesTest.cxx0000644000175000017500000000637111667757442030507 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkImage.h" #include "itkImageFileReader.h" #include "itkBinaryMaskImageToGoFigureMeshAttributes.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cerr << "./BinaryMaskImageToGoFigureMeshAttributesTest(.exe) takes 2 arguments" << std::endl; std::cerr << "1- input image filename" << std::endl; std::cerr << "2- input mask filename" << std::endl; return EXIT_FAILURE; } const unsigned int Dimension = 3; typedef double PixelType; typedef itk::Image< PixelType, Dimension > ImageType; typedef itk::ImageFileReader< ImageType > ReaderType; typedef itk::BinaryMaskImageToGoFigureMeshAttributes< ImageType, ImageType > AttributesFitlerType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(argv[1]); reader->Update(); ReaderType::Pointer reader2 = ReaderType::New(); reader2->SetFileName(argv[2]); reader2->Update(); AttributesFitlerType::Pointer filter = AttributesFitlerType::New(); filter->SetImage( reader->GetOutput() ); filter->SetMaskImage( reader2->GetOutput() ); filter->Update(); std::cout << "size " << filter->GetSize() << std::endl; std::cout << "volume " << filter->GetPhysicalSize() << std::endl; std::cout << "mean intensity " << filter->GetMeanIntensity() << std::endl; std::cout << "total intensity " << filter->GetSumIntensity() << std::endl; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/Filters/itkQuadEdgeMeshTovtkPolyDataTest.cxx0000644000175000017500000000705611667757442025650 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkQuadEdgeMesh.h" #include "itkRegularSphereMeshSource.h" #include "itkQuadEdgeMeshTovtkPolyData.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkProperty.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" int main( int, char** ) { typedef double CoordType; const unsigned int Dimension = 3; typedef itk::QuadEdgeMesh< CoordType, Dimension > MeshType; typedef itk::RegularSphereMeshSource< MeshType > SphereSourceType; MeshType::PointType center; center.Fill( 0. ); SphereSourceType::Pointer sphere = SphereSourceType::New(); sphere->SetCenter( center ); sphere->SetResolution( 5 ); sphere->Update(); typedef itk::QuadEdgeMeshTovtkPolyData< MeshType > ConverterType; ConverterType::Pointer converter = ConverterType::New(); converter->SetInput( sphere->GetOutput() ); converter->Update(); vtkSmartPointer< vtkPolyData > vtk_mesh = converter->GetOutput(); vtkSmartPointer< vtkPolyDataMapper > mapper = vtkSmartPointer< vtkPolyDataMapper >::New(); mapper->SetInput( vtk_mesh ); vtkSmartPointer< vtkActor > actor = vtkSmartPointer< vtkActor >::New(); actor->SetMapper( mapper ); actor->GetProperty()->SetColor( 0.5, 0.5, 0.5 ); vtkSmartPointer< vtkRenderer > renderer = vtkSmartPointer< vtkRenderer >::New(); renderer->AddActor( actor ); // Create a render window vtkSmartPointer renwin = vtkSmartPointer::New(); renwin->AddRenderer(renderer); // Create an interactor vtkSmartPointer iren = vtkSmartPointer::New(); iren->SetRenderWindow(renwin); iren->Initialize(); iren->Start(); return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/Filters/ExtractMeshesFromLabelImageFilter.cxx0000644000175000017500000001042311667757442025762 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkImageFileReader.h" #include "itkVTKPolyDataReader.h" #include "itkVTKPolyDataWriter.h" #include "itkExtractMeshesFromLabelImageFilter.h" #include "itkNumericSeriesFileNames.h" #include int main (int argc, char *argv[]) { if (argc < 3) { std::cout << "Usage: " << argv[0] << " InputVolume OutputMeshFormat numOfThreads" << std::endl; return EXIT_FAILURE; } const unsigned int Dimension = 3; typedef itk::Image< unsigned int, Dimension > SegmentImageType; typedef itk::ImageFileReader< SegmentImageType > ReaderType; typedef itk::ExtractMeshesFromLabelImageFilter< SegmentImageType > MeshSourceType; typedef MeshSourceType::MeshType MeshType; typedef itk::VTKPolyDataReader< MeshType > MeshReaderType; typedef itk::VTKPolyDataWriter< MeshType > MeshWriterType; typedef itk::NumericSeriesFileNames NameGeneratorType; typedef itk::VTKPolyDataWriter< MeshType > MeshWriterType; // Define all of the variables unsigned int smoothingIterations = 8; double relaxationFactor = 0.75; unsigned int numberOfTriangles = 200; unsigned int numOfThreads = atoi( argv[3] ); ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName ( argv[1] ); reader->Update(); SegmentImageType::Pointer input = reader->GetOutput(); MeshSourceType::Pointer meshSource = MeshSourceType::New(); meshSource->SetInput( input ); meshSource->SetUseSmoothing( true ); meshSource->SetUseDecimation( true ); meshSource->SetNumberOfTrianglesPerMesh( numberOfTriangles ); meshSource->SetNumberOfSmoothingIterations( smoothingIterations ); meshSource->SetSmoothingRelaxationFactor( relaxationFactor ); meshSource->SetDelaunayConforming( false ); meshSource->SetNumberOfThreads( numOfThreads ); meshSource->Update(); NameGeneratorType::Pointer nameGeneratorOutput = NameGeneratorType::New(); nameGeneratorOutput->SetSeriesFormat( argv[2] ); nameGeneratorOutput->SetStartIndex( 1 ); nameGeneratorOutput->SetEndIndex( meshSource->GetNumberOfMeshes() ); nameGeneratorOutput->SetIncrementIndex( 1 ); for( unsigned int i = 0; i < meshSource->GetNumberOfMeshes(); ++i ) { std::stringstream ss; ss << nameGeneratorOutput->GetFileNames()[i]; // std::cout << argv[0] << " writing " << ss.str() << std::endl; MeshWriterType::Pointer writer = MeshWriterType::New( ); writer->SetInput( meshSource->GetOutputs()[i] ); writer->SetFileName( ss.str().c_str() ); writer->Update(); } return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/Filters/CellMergeImageFilter.cxx0000644000175000017500000000621711667757442023264 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkPolyDataReader.h" #include "vtkPolyDataWriter.h" #include "vtkSmartPointer.h" #include "vtkAppendPolyData.h" #include "vtkHull.h" int main( int argc, char** argv ) { if( argc < 3 ) { std::cerr << "Missing arguments" << std::endl; std::cerr << "Usage: " << std::endl; std::cerr << argv[0] << " polydata1 polydata2 hullOutput" << std::endl; return EXIT_FAILURE; } vtkSmartPointer reader1 = vtkSmartPointer::New(); reader1->SetFileName( argv[1] ); reader1->Update(); vtkPolyData* contour1 = reader1->GetOutput(); vtkSmartPointer reader2 = vtkSmartPointer::New(); reader2->SetFileName( argv[2] ); reader2->Update(); vtkPolyData* contour2 = reader2->GetOutput(); // Append the local and remote data vtkSmartPointer append = vtkSmartPointer::New(); append->AddInput( contour1 ); append->AddInput( contour2 ); vtkSmartPointer hullFilter = vtkSmartPointer::New(); hullFilter->SetInputConnection( append->GetOutputPort() ); hullFilter->AddRecursiveSpherePlanes( 2 ); hullFilter->Update(); vtkSmartPointer writer = vtkSmartPointer::New(); writer->SetFileName( argv[3] ); writer->SetInput( hullFilter->GetOutput() ); writer->Write(); return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/Filters/itkvtkMeshMergeConvexHullFilterTest.cxx0000644000175000017500000001014011667757442026431 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkvtkMeshMergeConvexHullFilter.h" #include "itkImage.h" #include "itkImageFileReader.h" #include "vtkSmartPointer.h" #include "vtkSphereSource.h" #include "vtkPolyDataWriter.h" #include "vcl_algorithm.h" int main( int argc, char* argv[] ) { const unsigned int Dimension = 3; typedef unsigned char PixelType; typedef itk::Image< PixelType, Dimension > ImageType; typedef itk::ImageFileReader< ImageType > ReaderType; ImageType::Pointer input; { ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName ( argv[1] ); reader->Update(); input = reader->GetOutput(); input->DisconnectPipeline(); } ImageType::PointType im_org = input->GetOrigin(); ImageType::SizeType im_size = input->GetLargestPossibleRegion().GetSize(); ImageType::IndexType idx; idx[0] = im_size[0] - 1; idx[1] = im_size[1] - 1; idx[2] = im_size[2] - 1; ImageType::PointType p; input->TransformIndexToPhysicalPoint( idx, p ); ImageType::PointType center; center.SetToMidPoint( im_org, p ); ImageType::PointType::CoordRepType radius; radius = vcl_min( p[0] - im_org[0], p[1] - im_org[1] ); radius = vcl_min( radius, p[2] - im_org[2] ); radius *= 0.25; vtkSmartPointer< vtkSphereSource > sphere_source = vtkSmartPointer< vtkSphereSource >::New(); sphere_source->SetCenter( center[0] - 0.5 * radius, center[1], center[2] ); sphere_source->SetRadius( radius ); sphere_source->Update(); vtkSmartPointer< vtkSphereSource > sphere_source2 = vtkSmartPointer< vtkSphereSource >::New(); sphere_source2->SetCenter( center[0] + 0.5 * radius, center[1], center[2] ); sphere_source2->SetRadius( radius ); sphere_source2->Update(); typedef std::list< vtkPolyData* > PolyDataListType; typedef itk::vtkMeshMergeConvexHullFilter< ImageType, PolyDataListType > MergerType; MergerType::Pointer filter = MergerType::New(); PolyDataListType meshes; meshes.push_back( sphere_source->GetOutput() ); meshes.push_back( sphere_source2->GetOutput() ); filter->SetInputs( meshes ); filter->SetNumberOfImages( 1 ); filter->SetFeatureImage( 0, input ); filter->Update(); vtkSmartPointer< vtkPolyDataWriter > writer = vtkSmartPointer< vtkPolyDataWriter >::New(); writer->SetInput( filter->GetOutput() ); writer->SetFileName( "merged.vtk" ); writer->Write(); return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/Filters/itkvtkPolyDataToGoFigureMeshAttributesTest.cxx0000644000175000017500000000653411667757442027747 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkImage.h" #include "itkImageFileReader.h" #include "itkvtkPolyDataToGoFigureMeshAttributes.h" #include "vtkSphereSource.h" int main(int argc, char **argv) { if ( argc != 2 ) { std::cerr << "./BinaryMaskImageToGoFigureMeshAttributesTest(.exe) takes 1 arguments" << std::endl; std::cerr << "1- input image filename" << std::endl; return EXIT_FAILURE; } const unsigned int Dimension = 3; typedef unsigned char PixelType; typedef itk::Image< PixelType, Dimension > ImageType; typedef itk::ImageFileReader< ImageType > ReaderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(argv[1]); reader->Update(); ImageType::Pointer image = reader->GetOutput(); ImageType::SizeType size = image->GetLargestPossibleRegion().GetSize(); ImageType::PointType org = image->GetOrigin(); ImageType::SpacingType spacing = image->GetSpacing(); ImageType::PointType center; center[0] = org[0] + 0.5 * spacing[0] * size[0]; center[1] = org[1] + 0.5 * spacing[1] * size[1]; center[2] = org[2] + 0.5 * spacing[2] * size[2]; vtkSphereSource *sphere_source = vtkSphereSource::New(); sphere_source->SetCenter(center[0], center[1], center[2]); sphere_source->SetRadius(0.25 * spacing[0] * size[0]); sphere_source->Update(); typedef itk::vtkPolyDataToGoFigureMeshAttributes< ImageType > CalculatorType; CalculatorType::Pointer cal = CalculatorType::New(); cal->SetImage( reader->GetOutput() ); cal->SetPolyData( sphere_source->GetOutput() ); cal->Update(); sphere_source->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/Filters/itkvtkMeshSplitterDanielssonImageFilterTest.cxx0000644000175000017500000001056211667757442030163 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkvtkMeshSplitterDanielssonDistanceImageFilter.h" #include "itkImage.h" #include "itkImageFileReader.h" #include "vtkSmartPointer.h" #include "vtkSphereSource.h" #include "vtkPolyDataWriter.h" #include "vcl_algorithm.h" int main( int argc, char* argv[] ) { const unsigned int Dimension = 3; typedef unsigned char PixelType; typedef itk::Image< PixelType, Dimension > ImageType; typedef itk::ImageFileReader< ImageType > ReaderType; ImageType::Pointer input; { ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName ( argv[1] ); reader->Update(); input = reader->GetOutput(); input->DisconnectPipeline(); } ImageType::PointType im_org = input->GetOrigin(); ImageType::SizeType im_size = input->GetLargestPossibleRegion().GetSize(); ImageType::IndexType idx; idx[0] = im_size[0] - 1; idx[1] = im_size[1] - 1; idx[2] = im_size[2] - 1; ImageType::PointType p; input->TransformIndexToPhysicalPoint( idx, p ); ImageType::PointType center; center.SetToMidPoint( im_org, p ); ImageType::PointType::CoordRepType radius; radius = vcl_min( p[0] - im_org[0], p[1] - im_org[1] ); radius = vcl_min( radius, p[2] - im_org[2] ); radius *= 0.25; vtkSmartPointer< vtkSphereSource > sphere_source = vtkSmartPointer< vtkSphereSource >::New(); sphere_source->SetCenter( center[0], center[1], center[2] ); sphere_source->SetRadius( radius ); sphere_source->Update(); typedef itk::vtkMeshSplitterDanielssonDistanceImageFilter< ImageType > SplitterType; SplitterType::Pointer filter = SplitterType::New(); filter->SetMesh( sphere_source->GetOutput() ); filter->SetNumberOfImages( 1 ); filter->SetFeatureImage( 0, input ); typedef SplitterType::PointSetType PointSetType; PointSetType::Pointer seeds = PointSetType::New(); p[0] = center[0] - 0.5 * radius; p[1] = center[1]; p[2] = center[2]; seeds->SetPoint( 0, p ); p[0] = center[0] + 0.5 * radius; seeds->SetPoint( 1, p ); filter->SetSeeds( seeds ); filter->Update(); std::vector< vtkPolyData* > outputs = filter->GetOutputs(); std::vector< vtkPolyData* >::iterator it = outputs.begin(); size_t i = 0; while( it != outputs.end() ) { vtkSmartPointer< vtkPolyDataWriter > writer = vtkSmartPointer< vtkPolyDataWriter >::New(); writer->SetInput( *it ); std::stringstream os; os << i; std::string filename = "mesh"; filename += os.str(); filename += ".vtk"; std::cout << filename.c_str() << std::endl; writer->SetFileName( filename.c_str() ); writer->Write(); ++i; ++it; } return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/GUI/0000755000175000017500000000000011667757442015576 5ustar mathieumathieuGoFigure2-v0.9.0/Examples/GUI/CMakeLists.txt0000644000175000017500000000003011667757442020327 0ustar mathieumathieuADD_SUBDIRECTORY( lib ) GoFigure2-v0.9.0/Examples/GUI/lib/0000755000175000017500000000000011667757442016344 5ustar mathieumathieuGoFigure2-v0.9.0/Examples/GUI/lib/qgosynchronizedviewmanagertest.cxx0000644000175000017500000001232711667757442025451 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "vtkSmartPointer.h" #include "vtkPNGReader.h" #include "vtkImageGaussianSmooth.h" #include "vtkImageGradient.h" #include "vtkMetaImageReader.h" #include "QGoSynchronizedView.h" #include "QGoSynchronizedViewManager.h" #include "QGoSynchronizedView3D.h" #include "itkImage.h" #include "itkSmartPointer.h" #include "itkImageFileReader.h" #include #include int main(int argc, char **argv) { if ( argc != 4 ) { std::cout << "Usage : QGoSynchronizedViewManagerTest(.exe) " << std::endl; std::cout << "1-file.png" << std::endl; std::cout << "2-file.mhd" << std::endl; std::cout << "3-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); // ITK Typedefs // ITK Reader Typedef typedef double InputPixelType; const unsigned int Dimension = 3; typedef itk::Image< InputPixelType, Dimension > InputImage3DType; typedef InputImage3DType::Pointer InputImage3DPointer; //itk reader typedef itk::ImageFileReader< InputImage3DType > itkReaderType; itkReaderType::Pointer itkReader = itkReaderType::New(); itkReader->SetFileName(argv[2]); itkReader->Update(); // create 3 2D images from 1 vtkSmartPointer< vtkPNGReader > reader = vtkSmartPointer< vtkPNGReader >::New(); reader->SetFileName(argv[1]); reader->Update(); vtkSmartPointer< vtkImageGaussianSmooth > filter1 = vtkSmartPointer< vtkImageGaussianSmooth >::New(); filter1->SetInputConnection( reader->GetOutputPort() ); filter1->Update(); vtkSmartPointer< vtkImageGradient > filter2 = vtkSmartPointer< vtkImageGradient >::New(); filter2->SetInputConnection( reader->GetOutputPort() ); filter2->Update(); // create 3 3D images from 1 vtkSmartPointer< vtkMetaImageReader > reader3D = vtkSmartPointer< vtkMetaImageReader >::New(); reader3D->SetFileName(argv[2]); reader3D->Update(); vtkSmartPointer< vtkImageGaussianSmooth > filter13D = vtkSmartPointer< vtkImageGaussianSmooth >::New(); filter13D->SetInputConnection( reader3D->GetOutputPort() ); filter13D->Update(); vtkSmartPointer< vtkImageGradient > filter23D = vtkSmartPointer< vtkImageGradient >::New(); filter23D->SetInputConnection( reader3D->GetOutputPort() ); filter23D->Update(); QString cp0 = "comp0"; QString cp1 = "comp1"; QString cp2 = "comp3"; QString cp03D = "comp03D"; QString cp13D = "comp13D"; QString cp23D = "comp33D"; QString cp33D = "compITK_3D"; QGoSynchronizedViewManager *syncViewManage = new QGoSynchronizedViewManager(); syncViewManage->newSynchronizedView( cp0, reader->GetOutput() ); syncViewManage->newSynchronizedView( cp1, filter1->GetOutput() ); syncViewManage->newSynchronizedView( cp03D, reader3D->GetOutput() ); syncViewManage->newSynchronizedView( cp13D, filter13D->GetOutput() ); syncViewManage->newSynchronizedView< InputPixelType >( cp33D, itkReader->GetOutput() ); syncViewManage->Update(); syncViewManage->show(); syncViewManage->synchronizeOpenSynchronizedViews(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), qApp, SLOT( closeAllWindows() ) ); if ( atoi(argv[3]) == 1 ) { timer->start(1000); } app.processEvents(); int output = app.exec(); delete timer; delete syncViewManage; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/comparepipelineexample.cxx0000644000175000017500000001032011667757442023614 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "vtkImageReader2Factory.h" #include "vtkImageReader2.h" #include "vtkSmartPointer.h" #include "vtkImageReader2Collection.h" #include "vtkImageGaussianSmooth.h" #include "QGoSynchronizedViewManager.h" /* This simple examples shows how to use the high level interface * of the QGoSynchronize classes. * It takes a list of images as an input and displays the readable ones * with the standard VTK reader. * It synchronize the visualizations. */ int main(int argc, char **argv) { if ( argc != 2 ) { std::cout << "Usage : QGoSynchronizedViewManagerTest(.exe) " << std::endl; std::cout << "1-imagefile" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); vtkSmartPointer< vtkImageReader2Factory > imageFactory = vtkSmartPointer< vtkImageReader2Factory >::New(); vtkSmartPointer< vtkImageGaussianSmooth > filter = vtkSmartPointer< vtkImageGaussianSmooth >::New(); /* we simply create a new manager that will take care of ∗ creation/deletion of visualization and callbacks for us. */ QGoSynchronizedViewManager *ViewManager = new QGoSynchronizedViewManager (); QString ViewName; vtkImageReader2 *imageReader = imageFactory->CreateImageReader2(argv[1]); if ( imageReader != NULL ) { // Image before filtering : imageReader->SetFileName(argv[1]); imageReader->Update(); ViewName.clear(); ViewName.append(argv[1]); /* the synchronization manager can create visualization windows given * a valid pointer to a VTK image and * a string encoding the name of the visualization. */ ViewManager->newSynchronizedView( ViewName, imageReader->GetOutput() ); // Filtered Image : filter->SetInputConnection( imageReader->GetOutputPort() ); filter->Update(); ViewName.append(" - filtered"); ViewManager->newSynchronizedView( ViewName, filter->GetOutput() ); ViewManager->Update(); ViewManager->show(); } else { std::cerr << argv[1] << "is not a readable image by standard vtk reader" << std::endl; } /* the synchronization manager can synchronize the opened images ∗ with a simple function call */ ViewManager->synchronizeOpenSynchronizedViews(); app.processEvents(); int output = app.exec(); delete ViewManager; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoVideoRecorderTest.cxx0000644000175000017500000000611511667757442023076 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoVideoRecorder.h" #include "vtkRenderWindow.h" //**************************************************************************// // MAIN // //**************************************************************************// int main(int argc, char *argv[]) { if ( argc != 2 ) { std::cout << "Usage : ./VideoRecorderTest " << std::endl; std::cout << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QTimer * timer = new QTimer; timer->setSingleShot(true); QGoVideoRecorder *window = new QGoVideoRecorder(NULL); // Stupid tests window->SetCurrentX(10); window->SetCurrentY(10); window->SetCurrentZ(10); window->SetCurrentT(10); vtkRenderWindow *iRenderingWindow = vtkRenderWindow::New(); window->SetRenderingWindow(iRenderingWindow); iRenderingWindow->Delete(); window->SetSpecificParametersFrameRate(10); window->SetSpecificParametersQuality(2); QObject::connect( timer, SIGNAL( timeout() ), window, SLOT( close() ) ); if ( atoi(argv[1]) == 1 ) { timer->start(1000); } window->show(); app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete timer; delete window; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoDBInitCreateMicroscopePageTest.cxx0000644000175000017500000000552511667757442025424 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoDBInitCreateAuthorsPage.h" #include "vtkRenderWindow.h" //**************************************************************************// // MAIN // //**************************************************************************// int main(int argc, char *argv[]) { if ( argc != 2 ) { std::cout << "Usage : ./VideoRecorderTest " << std::endl; std::cout << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QTimer * timer = new QTimer; timer->setSingleShot(true); QGoDBInitCreateAuthorsPage *window = new QGoDBInitCreateAuthorsPage(NULL); //window->validatePage(); window->SetDatabaseVariables("user", "password"); QObject::connect( timer, SIGNAL( timeout() ), window, SLOT( close() ) ); if ( atoi(argv[1]) == 1 ) { timer->start(1000); } window->show(); app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete timer; delete window; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/qgomanualsegmentationsettingsdialog.cxx0000644000175000017500000000524011667757442026434 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoManualSegmentationSettingsDialog.h" int main(int argc, char **argv) { if ( argc != 2 ) { std::cout << "Usage : qgomanualsegmentationsettingsdialog(.exe) " << std::endl; std::cout << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QTimer *timer = new QTimer; timer->setSingleShot(true); QGoManualSegmentationSettingsDialog *dlg = new QGoManualSegmentationSettingsDialog; QObject::connect( timer, SIGNAL( timeout() ), dlg, SLOT( accept() ) ); if ( atoi(argv[1]) == 1 ) { timer->start(1000); } dlg->show(); app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete dlg; delete timer; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoColorCodingDialogTest.cxx0000644000175000017500000000444011667757442023663 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "QGoColorCodingDialog.h" int main(int argc, char *argv[]) { if ( argc != 2 ) { std::cerr << "QGoColorComboTest requires 1 arguments:" << std::endl; std::cerr << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QGoColorCodingDialog *win = new QGoColorCodingDialog(std::string("Contour"), true); win->show(); int output = app.exec(); app.closeAllWindows(); delete win; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/qgoimageview2d.cxx0000644000175000017500000001177711667757442022017 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "vtkSmartPointer.h" #include "vtkPNGReader.h" #include "vtkImageData.h" #include "vtkLookupTable.h" #include "vtkLookupTableManager.h" #include "vtksys/SystemTools.hxx" #include "QGoImageView2D.h" bool CheckSnapshot(QGoImageView2D *iViewer, GoFigure::FileType iType) { QString filename = iViewer->SnapshotViewXY(iType); std::string path = vtksys::SystemTools::GetCurrentWorkingDirectory(); path += "/"; path += filename.toStdString(); if ( vtksys::SystemTools::FileExists( path.c_str() ) ) { vtksys::SystemTools::RemoveFile( path.c_str() ); return true; } else { std::cerr << "FAILURE * viewer->SnapshotViewXY( " << iType << " )" << std::endl; return false; } } int main(int argc, char **argv) { if ( argc != 3 ) { std::cout << "Usage : qgoimageview2d(.exe) " << std::endl; std::cout << "1-file.png" << std::endl; std::cout << "2-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoImageView2D *viewer = new QGoImageView2D; vtkSmartPointer< vtkPNGReader > reader = vtkSmartPointer< vtkPNGReader >::New(); reader->SetFileName(argv[1]); reader->Update(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), viewer, SLOT( close() ) ); viewer->SetImage( reader->GetOutput() ); viewer->Update(); viewer->show(); if ( atoi(argv[2]) == 1 ) { if ( !CheckSnapshot(viewer, GoFigure::BMP) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(viewer, GoFigure::PNG) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(viewer, GoFigure::JPEG) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(viewer, GoFigure::EPS) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(viewer, GoFigure::TIFF) ) { return EXIT_FAILURE; } timer->start(1000); } viewer->ShowScalarBar(true); std::cout << viewer->GetImageActor(0) << std::endl; std::cout << viewer->GetImageActor(1) << std::endl; std::cout << viewer->GetInteractor(0) << std::endl; std::cout << viewer->GetInteractor(1) << std::endl; std::cout << viewer->GetImage() << std::endl; vtkLookupTable *LUT = vtkLookupTableManager::GetHotMetalLookupTable(); viewer->SetLookupTable(LUT); double rgb[3]; rgb[0] = 1.; rgb[1] = 0.; rgb[2] = 0.; viewer->SetBackgroundColor(rgb); if ( viewer->GetNumberOfImageViewers() != 1 ) { return EXIT_FAILURE; } viewer->ResetWindowLevel(); // Modes viewer->DefaultMode(); viewer->ZoomMode(); viewer->PanMode(); viewer->EnableContourPickingMode(); // Widgets viewer->EnableDistanceWidget(true); viewer->EnableDistanceWidget(false); viewer->EnableAngleWidget(true); viewer->EnableAngleWidget(false); viewer->EnableContourWidget(true); viewer->EnableContourWidget(false); viewer->EnableSeedWidget(true); viewer->EnableSeedWidget(false); app.processEvents(); int output = app.exec(); app.closeAllWindows(); LUT->Delete(); delete timer; delete viewer; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoAlgorithmWidgetTest.cxx0000644000175000017500000000602011667757442023427 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "QGoAlgorithmWidget.h" //**************************************************************************// // MAIN // //**************************************************************************// int main(int argc, char *argv[]) { if ( argc != 1 ) { return EXIT_FAILURE; } QApplication app(argc, argv); QTimer * timer = new QTimer; timer->setSingleShot(true); QGoAlgorithmWidget* AlgoWidget = new QGoAlgorithmWidget("Test", NULL); QStringList ChannelName; ChannelName.append("Channel 1"); ChannelName.append("Channel 2"); ChannelName.append("All Channels"); AlgoWidget->AddParameter("Channel", ChannelName); AlgoWidget->AddParameter("IntParam", 0, 100, 50); AlgoWidget->AddParameter("DoubleParam", 20.56, 53.21, 24, 2); AlgoWidget->AddAdvParameter("IntParam", 20, 50, 40); AlgoWidget->AddAdvParameter("DoubleParam", 11, 23.00, 15, 3); //QObject::connect( timer, SIGNAL( timeout() ), AlgoWidget, SLOT( close() ) ); AlgoWidget->show(); timer->start(1000); app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete timer; delete AlgoWidget; return output; } GoFigure2-v0.9.0/Examples/GUI/lib/QGoDBCreateBookmarkDialogTest.cxx0000644000175000017500000000555411667757442024567 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoDBBookmarkManager.h" #include "vtkMySQLDatabase.h" #include "QueryDataBaseHelper.h" int main(int argc, char *argv[]) { if ( argc != 2 ) { std::cout << "Usage : QGoDBCreateBookmarkDialogTest(.exe) " << std::endl; std::cout << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); vtkMySQLDatabase *connector = OpenDatabaseConnection("localhost", "gofigure", "gofigure", "gofiguredatabase"); QGoDBBookmarkManager *win = new QGoDBBookmarkManager(0, 1); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), win, SLOT( close() ) ); win->show(); if ( atoi(argv[1]) == 1 ) { timer->start(1000); } app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete timer; delete win; connector->Delete(); return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoDBInitializationWizardTest.cxx0000644000175000017500000000572411667757442024725 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoDBInitializationWizard.h" int main(int argc, char *argv[]) { if ( argc != 1 ) { std::cerr << "QGoDBInitializationWizardTest don't need argument" << std::endl; return EXIT_FAILURE; } //Q_INIT_RESOURCE(qgocreatedb); QApplication app(argc, argv); QGoDBInitializationWizard *wizard = new QGoDBInitializationWizard; wizard->show(); wizard->exec(); /* QTimer* timer = new QTimer; timer->setSingleShot( true ); QObject::connect( timer, SIGNAL( timeout() ), wizard, SLOT( close() ) ); int output; bool test = ( atoi( argv[1] ) == 1 ); if( test ) { timer->start( 1000 ); output = EXIT_SUCCESS; } else { output = app.exec(); } app.closeAllWindows(); if( !test ) { std::vector > filenames = wizard->GetFilenamesFromDB(); for (unsigned int i =0; i < filenames.size(); i++) { for (unsigned int j = 0; j < filenames[i].size();j++) { std::cout<<"image filename with channel " < AddTrace(vtkPolyData *, vtkProperty *) { return std::vector< vtkActor * >(); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoImageView3D *viewer = new QGoImageView3D; ContourMeshContainerTestHelper container(NULL, viewer); unsigned TimePoint = 0; bool highlighted = true; bool visible = true; unsigned int i = 0; for (; i < 20; i++ ) { ContourMeshStructure element(i, 0, vtkActor::New(), vtkActor::New(), vtkActor::New(), vtkActor::New(), vtkPolyData::New(), TimePoint, highlighted, visible, 1., 0., 0., 1.); container.Insert(element); } TimePoint = 1; for (; i < 30; i++ ) { ContourMeshStructure element(i, 0, vtkActor::New(), vtkActor::New(), vtkActor::New(), vtkActor::New(), vtkPolyData::New(), TimePoint, !highlighted, visible, 0., 1., 0., 1.); container.Insert(element); } container.Print(); container.RemoveActorsWithGivenTimePoint(0); container.AddActorsWithGivenTimePoint(1); container.DeleteAllHighlightedElements(); for ( i = 0; i < 30; i++ ) { container.DeleteElement(i); } delete viewer; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoPrintDatabaseTest.cxx0000644000175000017500000000617011667757442023064 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoPrintDatabase.h" int main(int argc, char *argv[]) { if ( ( argc != 2 ) && ( argc != 5 ) ) { std::cerr << "QGoPrintDatabaseTest requires 1 argument:" << std::endl; std::cerr << "1- test (boolean)" << std::endl; std::cerr << "2- database name (if not test)" << std::endl; std::cerr << "3- Imaging Session ID (if not test)" << std::endl; std::cerr << "4- Imaging Session Name (if not test)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoPrintDatabase *win = new QGoPrintDatabase; if ( atoi(argv[1]) == 0 ) { win->SetDatabaseVariables(argv[2], "localhost", "gofigure", "gofigure", atoi(argv[3]), argv[4]); win->FillTableFromDatabase(atoi(argv[3])); } //win->SetDatabaseVariables( // "gofiguredatabase", "localhost", "gofigure", // "gofigure", 8, "LSM_Converter"); win->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), win, SLOT( close() ) ); if ( atoi(argv[1]) == 1 ) { timer->start(1000); } int output = app.exec(); app.closeAllWindows(); delete win; delete timer; return output; } GoFigure2-v0.9.0/Examples/GUI/lib/QGoLsmToMegaExportThreadTest.cxx0000644000175000017500000000761211667757442024527 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "LSMToMegaCapture.h" #include #include #include #include "fstream" #include "GoFigureGlobalDefinition.h" #include "ConversionLsmToMegaThread.h" #include "vtksys/SystemTools.hxx" #include #include #include #include "LSMToMegaCapture.h" int main(int argc, char **argv) { QApplication app(argc, argv); if ( argc != 5 ) { std::cerr << "lsmtomegacapture requires 3 argument:" << std::endl; std::cerr << "1-lsm filename (without.lsm)" << std::endl; std::cerr << "2-lsm full name (full path with .lsm)" << std::endl; std::cerr << "3-lsm output path (output directory with folder/)" << std::endl; std::cerr << "4-test (boolean)" << std::endl; return EXIT_FAILURE; } // Note: EXIT_SUCCESS = 0 int err = EXIT_SUCCESS; ConversionLsmToMegaThread *ConversionLsmToMegaThreadSend = new ConversionLsmToMegaThread; QString BaseName(argv[1]); QString LsmPath(argv[2]); QString MegaPath(argv[3]); vtksys::SystemTools::MakeDirectory(argv[3]); ConversionLsmToMegaThreadSend->SetBaseName( BaseName.toStdString() ); ConversionLsmToMegaThreadSend->SetLsmPath( LsmPath.toStdString() ); ConversionLsmToMegaThreadSend->SetOutputFileType(GoFigure::PNG); ConversionLsmToMegaThreadSend->SetMegaPath( MegaPath.toStdString() ); ConversionLsmToMegaThreadSend->start(); // Wait until thread finishes running while ( ConversionLsmToMegaThreadSend->isRunning() ) { // waiting loop } if ( atoi(argv[4]) == 1 ) { // check if the directory containing Meg files is empty unsigned long length = 0; length = vtksys::SystemTools::FileLength(argv[3]); if ( length == 0 ) { err = EXIT_FAILURE; std::cerr << "ERROR: Test failing because directory is empty..." << std::endl; } // other test will use resulting megacapture as inputs // these files will be removed via cmake // vtksys::SystemTools::RemoveADirectory( argv[3] ); } delete ConversionLsmToMegaThreadSend; // err = 0 means that the test succeeded return err; }GoFigure2-v0.9.0/Examples/GUI/lib/vtkFFMPEGRenderWindowRecorderTest.cxx0000644000175000017500000001120411667757442025435 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ //For the visualization #include "vtkSphereSource.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRenderWindow.h" #include "vtkRenderer.h" #include "vtkRenderWindowInteractor.h" #include "vtkProperty.h" #include "vtksys/SystemTools.hxx" #include "vtkFFMPEGRenderWindowRecorder.h" #include int main(int argc, char *argv[]) { if ( argc != 2 ) { std::cerr << "Usage: " << std::endl; std::cerr << "" << std::endl; return EXIT_FAILURE; } int err = 0; int exists = 0; unsigned long length = 0; // create sphere geometry vtkSphereSource *sphere = vtkSphereSource::New(); sphere->SetRadius(1.0); sphere->SetThetaResolution(18); sphere->SetPhiResolution(18); // map to graphics library vtkPolyDataMapper *map = vtkPolyDataMapper::New(); map->SetInput( sphere->GetOutput() ); // actor creation and properties definition vtkActor *aSphere = vtkActor::New(); aSphere->SetMapper(map); aSphere->GetProperty()->SetColor(1, 1, 1); aSphere->GetProperty()->SetOpacity(0.5); // a renderer and render window vtkRenderer * ren1 = vtkRenderer::New(); vtkRenderWindow *renWin = vtkRenderWindow::New(); renWin->AddRenderer(ren1); // an interactor vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); iren->SetRenderWindow(renWin); iren->Initialize(); // add the actor to the scene ren1->AddActor(aSphere); ren1->SetBackground(1, 0, 0); // Background color white // create the video vtkFFMPEGRenderWindowRecorder *testRecorder = vtkFFMPEGRenderWindowRecorder::New(); testRecorder->SetRenderingWindow(renWin); testRecorder->SetFileName(argv[1]); testRecorder->StartCapture(); for ( int i = 0; i < 30; i++ ) { renWin->Render(); testRecorder->TakeSnapshot(); } ren1->SetBackground(0, 1, 0); for ( int i = 0; i < 30; i++ ) { renWin->Render(); testRecorder->TakeSnapshot(); } ren1->SetBackground(0, 0, 1); for ( int i = 0; i < 30; i++ ) { renWin->Render(); testRecorder->TakeSnapshot(); } testRecorder->EndCapture(); // Test exists = (int)vtksys::SystemTools::FileExists(argv[1]); length = vtksys::SystemTools::FileLength(argv[1]); cout << "TestFFMPEGRecorder file exists: " << exists << endl; cout << "TestFFMPEGRecorder file length: " << length << endl; if ( !exists ) { err = 1; cerr << "ERROR: 1 - Test failing because TestFFMPEGRecorder file doesn't exist..." << endl; } else { vtksys::SystemTools::RemoveFile(argv[1]); } if ( 0 == length ) { err = 2; cerr << "ERROR: 2 - Test failing because TestFFMPEGRecorder file has zero length..." << endl; } // Delete everything sphere->Delete(); map->Delete(); aSphere->Delete(); ren1->Delete(); renWin->Delete(); iren->Delete(); testRecorder->Delete(); // err = 0 means that the test succeeded return err; }GoFigure2-v0.9.0/Examples/GUI/lib/qgotabimageview3dwt.cxx0000644000175000017500000000734111667757442023052 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "vtkSmartPointer.h" #include "vtkLSMReader.h" #include "vtkImageData.h" #include "QGoTabImageView3DwT.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cerr << "qgotabimageview3dwt requires 2 arguments:" << std::endl; std::cerr << "1-filename" << std::endl; std::cerr << "2-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); vtkLSMReader *reader = vtkLSMReader::New(); reader->SetFileName(argv[1]); reader->SetUpdateTimePoint(0); reader->Update(); QGoTabImageView3DwT *tab = new QGoTabImageView3DwT; tab->SetLSMReader(reader, 0); tab->show(); QMenuBar * menubar = new QMenuBar; std::vector< QAction * > action_vector = tab->ViewActions(); for ( std::vector< QAction * >::iterator q_it = action_vector.begin(); q_it != action_vector.end(); ++q_it ) { menubar->addAction(*q_it); } menubar->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), tab, SLOT( close() ) ); QObject::connect( timer, SIGNAL( timeout() ), menubar, SLOT( close() ) ); std::list< std::pair< QGoDockWidgetStatus *, QDockWidget * > > dockwidget_list = tab->DockWidget(); for ( std::list< std::pair< QGoDockWidgetStatus *, QDockWidget * > >::iterator it = dockwidget_list.begin(); it != dockwidget_list.end(); ++it ) { if ( it->second ) { it->second->show(); QObject::connect( timer, SIGNAL( timeout() ), it->second, SLOT( close() ) ); } } if ( atoi(argv[2]) == 1 ) { tab->SetTimePoint(0); timer->start(1000); } app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete menubar; delete tab; return output; } GoFigure2-v0.9.0/Examples/GUI/lib/qgolutdialog.cxx0000644000175000017500000000505311667757442021566 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "vtkLookupTable.h" #include "QGoLUTDialog.h" int main(int argc, char **argv) { QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoLUTDialog *lut = new QGoLUTDialog; lut->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), lut, SLOT( accept() ) ); if ( atoi(argv[1]) == 1 ) { timer->start(1000); } for ( int i = 0; i < 10; i++ ) { lut->ChangeLookupTable(i); } vtkLookupTable *temp = lut->GetLookupTable(); int output = app.exec(); app.closeAllWindows(); delete lut; temp->Delete(); delete timer; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/qgoimageview3d.cxx0000644000175000017500000001711611667757442022011 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "vtkMetaImageReader.h" #include "vtkImageData.h" #include "vtkSmartPointer.h" #include "vtkPoints.h" #include "QGoImageView3D.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cout << "Usage : qgoimageview3d(.exe) " << std::endl; std::cout << "1-file.mhd" << std::endl; std::cout << "2-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoImageView3D *viewer = new QGoImageView3D; vtkSmartPointer< vtkMetaImageReader > reader = vtkSmartPointer< vtkMetaImageReader >::New(); reader->SetFileName(argv[1]); reader->Update(); vtkImageData *image = reader->GetOutput(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), viewer, SLOT( close() ) ); viewer->SetImage(image); std::cout << viewer->GetImage() << std::endl; viewer->Update(); viewer->show(); // Stupid tests to increase coverage and track leaks viewer->ShowAnnotations(); viewer->ShowSplinePlane(); viewer->ShowCube3D(); viewer->UpdateRenderWindows(); /// \todo Fix it //viewer->SetCamera(1); //viewer->SetCamera(2); //viewer->SetCamera(3); // Modes viewer->DefaultMode(); viewer->ZoomMode(); viewer->PanMode(); viewer->EnableContourPickingMode(); // Protected should be public //viewer->EnableMeshPickingMode(); // Widgets viewer->EnableDistanceWidget(true); viewer->EnableDistanceWidget(false); viewer->EnableAngleWidget(true); viewer->EnableAngleWidget(false); viewer->EnableContourWidget(true); viewer->EnableContourWidget(false); viewer->EnableSeedWidget(true); viewer->EnableSeedWidget(false); viewer->EnableBoxWidget(true); viewer->EnableBoxWidget(false); //vtkPoints *points = viewer->GetAllSeeds(); //points->Delete(); //viewer->ClearAllSeeds(); if ( atoi(argv[2]) == 1 ) { timer->start(1000); viewer->SetFullScreenView(1); if ( viewer->GetFullScreenView() != 1 ) { std::cerr << "viewer->GetFullScreenView() = " << viewer->GetFullScreenView(); std::cerr << " != 1" << std::endl; app.closeAllWindows(); reader->Delete(); delete timer; delete viewer; return EXIT_FAILURE; } viewer->SetFullScreenView(2); if ( viewer->GetFullScreenView() != 2 ) { std::cerr << "viewer->GetFullScreenView() = " << viewer->GetFullScreenView(); std::cerr << " != 2" << std::endl; app.closeAllWindows(); delete timer; delete viewer; return EXIT_FAILURE; } viewer->SetFullScreenView(3); if ( viewer->GetFullScreenView() != 3 ) { std::cerr << "viewer->GetFullScreenView() = " << viewer->GetFullScreenView(); std::cerr << " != 3" << std::endl; app.closeAllWindows(); delete timer; delete viewer; return EXIT_FAILURE; } viewer->SetFullScreenView(4); if ( viewer->GetFullScreenView() != 4 ) { std::cerr << "viewer->GetFullScreenView() = " << viewer->GetFullScreenView(); std::cerr << " != 4" << std::endl; app.closeAllWindows(); delete timer; delete viewer; return EXIT_FAILURE; } viewer->SetFullScreenView(0); if ( viewer->GetFullScreenView() != 0 ) { std::cerr << "viewer->GetFullScreenView() = " << viewer->GetFullScreenView(); std::cerr << " != 0" << std::endl; app.closeAllWindows(); delete timer; delete viewer; return EXIT_FAILURE; } int slice = viewer->GetSliceViewXY(); viewer->SetSliceViewXY(slice + 1); if ( viewer->GetSliceViewXY() != slice + 1 ) { std::cerr << "viewer->GetSliceViewXY() = " << viewer->GetSliceViewXY(); std::cerr << " != slice + 1" << std::endl; app.closeAllWindows(); delete timer; delete viewer; return EXIT_FAILURE; } slice = viewer->GetSliceViewXZ(); viewer->SetSliceViewXZ(slice - 1); if ( viewer->GetSliceViewXZ() != slice - 1 ) { std::cerr << "viewer->GetSliceViewXZ() = " << viewer->GetSliceViewXZ(); std::cerr << " != slice - 1" << std::endl; app.closeAllWindows(); delete timer; delete viewer; return EXIT_FAILURE; } slice = viewer->GetSliceViewYZ(); viewer->SetSliceViewYZ(slice + 1); if ( viewer->GetSliceViewYZ() != slice + 1 ) { std::cerr << "viewer->GetSliceViewYZ() = " << viewer->GetSliceViewYZ(); std::cerr << " != slice + 1" << std::endl; app.closeAllWindows(); delete timer; delete viewer; return EXIT_FAILURE; } double r(0.), g(0.), b(0.); viewer->SetBackgroundColor(0.5, 0.5, 0.5); viewer->GetBackgroundColor(r, g, b); if ( r != 0.5 || g != 0.5 || b != 0.5 ) { std::cerr << r << " " << g << " " << b << " != {0.5, 0.5, 0.5}" << std::endl; app.closeAllWindows(); delete timer; delete viewer; return EXIT_FAILURE; } viewer->SetBackgroundColor(0.1, 0.6, 0.7); viewer->GetBackgroundColor(r, g, b); if ( r != 0.1 || g != 0.6 || b != 0.7 ) { std::cerr << r << " " << g << " " << b << " != {0.1, 0.6, 0.7}" << std::endl; app.closeAllWindows(); delete timer; delete viewer; return EXIT_FAILURE; } viewer->SetBackgroundColor(0., 0., 0.); viewer->GetBackgroundColor(r, g, b); if ( r != 0. || g != 0. || b != 0. ) { std::cerr << r << " " << g << " " << b << " != {0., 0., 0.}" << std::endl; app.closeAllWindows(); delete timer; delete viewer; return EXIT_FAILURE; } } app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete timer; delete viewer; return output; } GoFigure2-v0.9.0/Examples/GUI/lib/CMakeLists.txt0000644000175000017500000001516011667757442021107 0ustar mathieumathieuSET( QGOGUILIB_EXAMPLE_SRC qgoimageview2d qgoimageview3d QGoImageInfoTest qgolutdialog qgotabelementbase qgotabimageviewelementbase qgotabimageview2d qgotabimageview3d qgotabimageview3dwt qgomanualsegmentationsettingsdialog qgonavigationdockwidget QGoContourManualSegmentationDockWidgetTest ContourMeshContainerTest QGoWizardDBTest QGoPrintDatabaseTest QGoColorCodingDialogTest qgocreatemeshdialogtest QGoLsmToMegaExportDialogTest QGoLsmToMegaExportThreadTest QGoDBCreateBookmarkDialogTest QGoTraceSettingsWidgetTest QGoDBInitializationWizardTest qgotabimageview3dwt2 QGoLevelset2DTest QGoDBInitCreateAuthorPageTest QGoDBInitCreateMicroscopePageTest QGoColorComboBoxTest QGoSegmentationAlgoTest #QGoTrackEditingWidgetTest # QGoTraceEditingWidgetTest # QGoAlgorithmsManagerWidgetTest # QGoAlgorithmWidgetTest # QGoModesManagerWidgetTest # QGoMeshEditingWidgetManagerTest ) IF( BUILD_COMPARETOOL ) SET( QGOGUILIB_EXAMPLE_SRC ${QGOGUILIB_EXAMPLE_SRC} qgosynchronizedview2dtest qgosynchronizedview3dtest qgosynchronizedviewmanagertest compareexample comparepipelineexample ) ENDIF( BUILD_COMPARETOOL ) #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- #ADD QGoVideoRecorderTest if ENABLE_VIDEO_RECORD IS ON IF( ENABLE_VIDEO_RECORD_FFMPEG ) SET(QGOGUILIB_EXAMPLE_SRC ${QGOGUILIB_EXAMPLE_SRC} QGoVideoRecorderTest vtkFFMPEGRenderWindowRecorderTest ) ENDIF( ENABLE_VIDEO_RECORD_FFMPEG ) #ADD QGoVideoRecorderTest if ENABLE_VIDEO_RECORD IS ON IF( ENABLE_VIDEO_RECORD_AVI ) SET(QGOGUILIB_EXAMPLE_SRC ${QGOGUILIB_EXAMPLE_SRC} QGoVideoRecorderTest vtkAVIRenderWindowRecorderTest ) ENDIF( ENABLE_VIDEO_RECORD_AVI ) #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- FOREACH( var ${QGOGUILIB_EXAMPLE_SRC} ) ADD_EXECUTABLE( ${var} ${var} ) TARGET_LINK_LIBRARIES( ${var} QGoGui ) ENDFOREACH( var ${QGOGUILIB_EXAMPLE_SRC} ) ADD_TEST( qgoimageview2dTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgoimageview2d ${TESTING_DATA_PATH}/Circle.png 1 ) ADD_TEST( qgoimageview3dTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgoimageview3d ${TESTING_DATA_PATH}/Circle3D.mhd 1 ) ADD_TEST( QGoImageInfoTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoImageInfoTest 1 ) ADD_TEST( qgolutdialogTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgolutdialog 1 ) ADD_TEST( qgotabelementbaseTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgotabelementbase ) ADD_TEST( qgotabimageviewelementbaseTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgotabimageviewelementbase ) ADD_TEST( qgotabimageview2dTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgotabimageview2d ${TESTING_DATA_PATH}/Circle.png 1 ) ADD_TEST( qgotabimageview3dTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgotabimageview3d ${TESTING_DATA_PATH}/Circle3D.mhd 1 ) ADD_TEST( qgotabimageview3dwtTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgotabimageview3dwt ${TTestESTING_DATA_PATH}/earpax2isl11.lsm 1 ) ADD_TEST( qgomanualsegmentationsettingsdialogTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgomanualsegmentationsettingsdialog 1 ) ADD_TEST( qgonavigationdockwidgetTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgonavigationdockwidget 1 ) ADD_TEST( QGoContourManualSegmentationDockWidgetTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoContourManualSegmentationDockWidgetTest 1 ) ADD_TEST( ContourMeshContainerTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ContourMeshContainerTest ) ADD_TEST( QGoLsmToMegaExportDialogTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoLsmToMegaExportDialogTest 1 ) ADD_TEST( QGoLsmToMegaExportThreadTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoLsmToMegaExportThreadTest earpax2isl11.lsm ${TESTING_DATA_PATH}/earpax2isl11.lsm ${GOFIGURE2_BINARY_DIR}/Testing/earpax2isl11/ 1 ) ADD_TEST( QGoWizardDBTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoWizardDBTest 1 ) ADD_TEST( QGoPrintDatabaseTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoPrintDatabaseTest 1 ) ADD_TEST( QGoDBCreateBookmarkDialogTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoDBCreateBookmarkDialogTest 1 ) ADD_TEST( qgotabimageview3dwtTest2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgotabimageview3dwt2 ${GOFIGURE2_BINARY_DIR}/Testing/earpax2isl11/earpax2isl11.lsm-PL00-CO00-RO00-ZT00-YT00-XT00-TM0000-ch00-zs0000.png ) SET_TESTS_PROPERTIES( qgotabimageview3dwtTest2 PROPERTIES DEPENDS lsmtomegacaptureTest ) IF( BUILD_COMPARETOOL ) ADD_TEST( qgosynchronizedview2dtest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgosynchronizedview2dtest ${TESTING_DATA_PATH}/Circle.png 1 ) ADD_TEST( qgosynchronizedview3dtest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgosynchronizedview3dtest ${TESTING_DATA_PATH}/Circle3D.mhd 1 ) ADD_TEST( qgosynchronizedviewmanagertest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qgosynchronizedviewmanagertest ${TESTING_DATA_PATH}/Circle.png ${TESTING_DATA_PATH}/Circle3D.mhd 1 ) ENDIF( BUILD_COMPARETOOL ) ADD_TEST( QGoLevelset2DTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoLevelset2DTest ${TESTING_DATA_PATH}/Circle3D.mhd 1 ) ADD_TEST( QGoDBInitCreateAuthorPageTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoDBInitCreateAuthorPageTest 1 ) ADD_TEST( QGoDBInitCreateMicroscopePageTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoDBInitCreateMicroscopePageTest 1 ) ADD_TEST( QGoSegmentationAlgoTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoSegmentationAlgoTest ${TESTING_DATA_PATH}/Circle3D.mhd 1 ) #ADD_TEST( QGoTrackEditingWidgetTest # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoTrackEditingWidgetTest # 1 #) #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- # ADD THIS TEST IF ENABLE_VIDEO_RECORD_FFMPEG IS ON IF( ENABLE_VIDEO_RECORD_FFMPEG ) ADD_TEST( QGoVideoRecorderTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoVideoRecorderTest 1 ) ADD_TEST( vtkFFMPEGRenderWindowRecorderTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vtkFFMPEGRenderWindowRecorderTest test.avi ) ENDIF( ENABLE_VIDEO_RECORD_FFMPEG ) # ADD THIS TEST IF ENABLE_VIDEO_RECORD_AVI IS ON IF( ENABLE_VIDEO_RECORD_AVI ) ADD_TEST( QGoVideoRecorderTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoVideoRecorderTest 1 ) ADD_TEST( vtkAVIRenderWindowRecorderTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vtkAVIRenderWindowRecorderTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test.avi ) ENDIF( ENABLE_VIDEO_RECORD_AVI ) #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- GoFigure2-v0.9.0/Examples/GUI/lib/qgonavigationdockwidget.cxx0000644000175000017500000000644111667757442024010 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoNavigationDockWidget.h" #include int main(int argc, char **argv) { if ( argc != 2 ) { std::cerr << "qgovisualizationdockwidget requires 1 argument1:" << std::endl; std::cerr << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoNavigationDockWidget * dock2d = new QGoNavigationDockWidget(0, GoFigure::TWO_D); dock2d->show(); QGoNavigationDockWidget * dock2dwt = new QGoNavigationDockWidget(0, GoFigure::TWO_D_WITH_T); dock2dwt->show(); QGoNavigationDockWidget * dock3d = new QGoNavigationDockWidget(0, GoFigure::THREE_D); dock3d->show(); QGoNavigationDockWidget * dock3dwt = new QGoNavigationDockWidget(0, GoFigure::THREE_D_WITH_T); dock3dwt->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), dock2d, SLOT( close() ) ); QObject::connect( timer, SIGNAL( timeout() ), dock2dwt, SLOT( close() ) ); QObject::connect( timer, SIGNAL( timeout() ), dock3d, SLOT( close() ) ); QObject::connect( timer, SIGNAL( timeout() ), dock3dwt, SLOT( close() ) ); if ( atoi(argv[1]) == 1 ) { timer->start(100); } app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete dock2d; delete dock2dwt; delete dock3d; delete dock3dwt; delete timer; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/qgotabimageview3dwt2.cxx0000644000175000017500000000757011667757442023140 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "vtkSmartPointer.h" #include "vtkLSMReader.h" #include "vtkImageData.h" #include "itkMegaCaptureImport.h" #include "QGoTabImageView3DwT.h" int main(int argc, char **argv) { if ( argc != 2 ) { std::cerr << "qgotabimageview3dwt2 requires 2 arguments:" << std::endl; std::cerr << "1-filename (megacapture)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); itk::MegaCaptureImport::Pointer importer = itk::MegaCaptureImport::New(); importer->SetFileName(argv[1]); importer->Update(); int t = importer->GetOutput().get< m_TCoord >().begin()->m_TCoord; QGoTabImageView3DwT *tab = new QGoTabImageView3DwT; tab->SetMegaCaptureFile(importer->GetOutput(), GoFigure::PNG, importer->GetHeaderFilename(), t); tab->show(); QMenuBar * menubar = new QMenuBar; std::vector< QAction * > action_vector = tab->ViewActions(); for ( std::vector< QAction * >::iterator q_it = action_vector.begin(); q_it != action_vector.end(); ++q_it ) { menubar->addAction(*q_it); } menubar->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), tab, SLOT( close() ) ); QObject::connect( timer, SIGNAL( timeout() ), menubar, SLOT( close() ) ); std::list< std::pair< QGoDockWidgetStatus *, QDockWidget * > > dockwidget_list = tab->DockWidget(); for ( std::list< std::pair< QGoDockWidgetStatus *, QDockWidget * > >::iterator it = dockwidget_list.begin(); it != dockwidget_list.end(); ++it ) { if ( it->second ) { it->second->show(); QObject::connect( timer, SIGNAL( timeout() ), it->second, SLOT( close() ) ); } } { tab->SetTimePoint(0); timer->start(1000); } app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete menubar; delete tab; delete timer; return output; } GoFigure2-v0.9.0/Examples/GUI/lib/compareexample.cxx0000644000175000017500000000742211667757442022077 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "vtkImageReader2Factory.h" #include "vtkImageReader2.h" #include "vtkSmartPointer.h" #include "vtkImageReader2Collection.h" #include "QGoSynchronizedViewManager.h" /* This simple examples shows how to use the high level interface * of the QGoSynchronize classes. * It takes a list of images as an input and displays the readable ones * with the standard VTK reader. * It synchronize the visualizations. */ int main(int argc, char **argv) { QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); vtkSmartPointer< vtkImageReader2Factory > imageFactory = vtkSmartPointer< vtkImageReader2Factory >::New(); /* we simply create a new manager that will take care of ∗ creation/deletion of visualization and callbacks for us. */ QGoSynchronizedViewManager *ViewManager = new QGoSynchronizedViewManager (); QString ViewName; for ( int i = 1; i < argc; ++i ) { std::cout << argv[i] << std::endl; vtkImageReader2 *imageReader = imageFactory->CreateImageReader2(argv[i]); if ( imageReader != NULL ) { imageReader->SetFileName(argv[i]); imageReader->Update(); ViewName.clear(); ViewName.append(argv[i]); /* the synchronization manager can create visualization windows given * a valid pointer to a VTK image and * a string encoding the name of the visualization. */ ViewManager->newSynchronizedView( ViewName, imageReader->GetOutput() ); ViewManager->Update(); ViewManager->show(); } else { std::cerr << argv[i] << "is not a readable image by standard vtk reader" << std::endl; } } /* the synchronization manager can synchronize the opened images ∗ with a simple function call */ ViewManager->synchronizeOpenSynchronizedViews(); app.processEvents(); int output = app.exec(); delete ViewManager; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoLevelset2DTest.cxx0000644000175000017500000000711111667757442022310 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "vtkMetaImageReader.h" #include "vtkSmartPointer.h" #include "vtkImageCast.h" #include "vtkImageData.h" #include "QGoFilterChanAndVese.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cout << "Usage : qgoimageview3d(.exe) " << std::endl; std::cout << "1-file.mhd" << std::endl; std::cout << "2-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); vtkSmartPointer< vtkMetaImageReader > reader = vtkSmartPointer< vtkMetaImageReader >::New(); reader->SetFileName(argv[1]); reader->Update(); vtkSmartPointer< vtkImageCast > castFilter = vtkSmartPointer< vtkImageCast >::New(); castFilter->SetInput( reader->GetOutput() ); castFilter->SetOutputScalarTypeToUnsignedChar(); castFilter->Update(); // Initialize the segmentation QGoFilterChanAndVese * levelSet2DFilter = new QGoFilterChanAndVese(NULL, 2); std::vector< vtkSmartPointer< vtkImageData > > imagesVector(1); imagesVector[0] = castFilter->GetOutput(); levelSet2DFilter->setOriginalImageMC(&imagesVector); // levelSet2DFilter->setIterations(50); // levelSet2DFilter->setRadius(2); // levelSet2DFilter->setCurvature(10); double seedPos[3]; seedPos[0] = 5; seedPos[1] = 5; seedPos[2] = 5; vtkPoints *seeds = vtkPoints::New(); seeds->InsertNextPoint(seedPos); levelSet2DFilter->setCenter(seedPos); levelSet2DFilter->setPoints(seeds); // if there is an output int oResult; if ( levelSet2DFilter->getOutput() ) { oResult = EXIT_SUCCESS; } else { oResult = EXIT_FAILURE; } delete levelSet2DFilter; seeds->Delete(); return oResult; } GoFigure2-v0.9.0/Examples/GUI/lib/QGoAlgorithmsManagerWidgetTest.cxx0000644000175000017500000001042011667757442025104 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "QGoAlgorithmsManagerWidget.h" #include "QGoAlgorithmWidget.h" //**************************************************************************// // MAIN // //**************************************************************************// int main(int argc, char *argv[]) { if ( argc != 1 ) { return EXIT_FAILURE; } QApplication app(argc, argv); QTimer * timer = new QTimer; timer->setSingleShot(true); QGoAlgorithmsManagerWidget* SemiAutoModeMeshEditingAlgoWidget = new QGoAlgorithmsManagerWidget("SemiAutomatedWidget", NULL); QGoAlgorithmWidget* LevelSetWidget = new QGoAlgorithmWidget("LevelSet", SemiAutoModeMeshEditingAlgoWidget); QStringList ChannelName; ChannelName.append("Channel 1"); ChannelName.append("Channel 2"); LevelSetWidget->AddParameter("Channel", ChannelName); LevelSetWidget->AddParameter("Radius", 0, 10, 3); LevelSetWidget->AddAdvParameter("Curvature", 0, 100, 20); LevelSetWidget->AddAdvParameter("Iterations", 0, 1000, 100); QGoAlgorithmWidget* Shape3D = new QGoAlgorithmWidget("Shape 3D", SemiAutoModeMeshEditingAlgoWidget); Shape3D->AddParameter("Channel", ChannelName); Shape3D->AddParameter("Radius", 0, 10, 3); QStringList ShapeList; ShapeList.append("Sphere"); ShapeList.append("Cube"); Shape3D->AddAdvParameter("Shape", ShapeList); QGoAlgorithmWidget* WaterShedWidget = new QGoAlgorithmWidget("WaterShed", SemiAutoModeMeshEditingAlgoWidget); WaterShedWidget->AddParameter("Channel", ChannelName); WaterShedWidget->AddParameter("Radius", 0, 10, 3); WaterShedWidget->AddAdvParameter("Thres.Min.", 0, 10, 20); WaterShedWidget->AddAdvParameter("Thres.Min.", 0, 30, 50); WaterShedWidget->AddAdvParameter("Corr.Thres.", 0, 5, 2, 2); WaterShedWidget->AddAdvParameter("Alpha", 0, 5, 1.50, 2); WaterShedWidget->AddAdvParameter("Beta", 0, 5, 3, 1); SemiAutoModeMeshEditingAlgoWidget->AddMethod(LevelSetWidget); SemiAutoModeMeshEditingAlgoWidget->AddMethod(WaterShedWidget); SemiAutoModeMeshEditingAlgoWidget->AddMethod(Shape3D); SemiAutoModeMeshEditingAlgoWidget->SetCurrentIndex(0); QObject::connect( timer, SIGNAL( timeout() ), SemiAutoModeMeshEditingAlgoWidget, SLOT( close() ) ); timer->start(1000); SemiAutoModeMeshEditingAlgoWidget->show(); app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete timer; delete SemiAutoModeMeshEditingAlgoWidget; return output; } GoFigure2-v0.9.0/Examples/GUI/lib/qgotabimageview3d.cxx0000644000175000017500000000745411667757442022504 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "vtkMetaImageReader.h" #include "vtkImageData.h" #include "vtkSmartPointer.h" #include "QGoTabImageView3D.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cerr << "qgotabimageview3d requires 2 arguments:" << std::endl; std::cerr << "1-filename" << std::endl; std::cerr << "2-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); vtkSmartPointer< vtkMetaImageReader > reader = vtkSmartPointer< vtkMetaImageReader >::New(); reader->SetFileName(argv[1]); reader->Update(); QGoTabImageView3D *tab = new QGoTabImageView3D; tab->SetImage( reader->GetOutput() ); tab->Update(); // tab->ActivateManualSegmentationEditor( true ); tab->show(); QMenuBar * menubar = new QMenuBar; std::vector< QAction * > action_vector = tab->ViewActions(); for ( std::vector< QAction * >::iterator q_it = action_vector.begin(); q_it != action_vector.end(); ++q_it ) { menubar->addAction(*q_it); } menubar->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), tab, SLOT( close() ) ); QObject::connect( timer, SIGNAL( timeout() ), menubar, SLOT( close() ) ); std::list< std::pair< QGoDockWidgetStatus *, QDockWidget * > > dockwidget_list = tab->DockWidget(); for ( std::list< std::pair< QGoDockWidgetStatus *, QDockWidget * > >::iterator it = dockwidget_list.begin(); it != dockwidget_list.end(); ++it ) { if ( it->second ) { ( it->second )->show(); QObject::connect( timer, SIGNAL( timeout() ), it->second, SLOT( close() ) ); } } if ( atoi(argv[2]) == 1 ) { timer->start(1000); } app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete menubar; delete tab; return output; } GoFigure2-v0.9.0/Examples/GUI/lib/qgotabelementbase.cxx0000644000175000017500000000547511667757442022565 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "QGoTabElementBase.h" class QGoTabElementTestHelper : public QGoTabElementBase { public: QGoTabElementTestHelper(QWidget *iParent = 0) : QGoTabElementBase(iParent) { } virtual ~QGoTabElementTestHelper() { } virtual void WriteSettings() { } virtual void ReadSettings() { } virtual GoFigure::TabDimensionType GetTabDimensionType() const { return GoFigure::TWO_D; } protected: virtual void PopulateMenus(QObject *iPlugin) { (void)iPlugin; } private: QGoTabElementTestHelper(const QGoTabElementTestHelper &); void operator=(const QGoTabElementTestHelper &); }; int main(int argc, char **argv) { QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoTabElementTestHelper *test = new QGoTabElementTestHelper; test->ViewActions(); test->DockWidget(); test->GetPluginActions(); test->SetPluginActions( std::list< QAction * >() ); delete test; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoImageInfoTest.cxx0000644000175000017500000000701311667757442022176 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "QGoImageInfo.h" int main(int argc, char **argv) { if ( argc != 2 ) { return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoImageInfo *info = new QGoImageInfo; const unsigned int Dim3 = 3; info->setDimension(Dim3); info->setNumberOfChannels(Dim3); std::vector< unsigned int > size3(Dim3, 512); std::vector< float > spacing3( Dim3, static_cast< const float >( 0.1 ) ); info->setSize(size3); info->setSpacing(spacing3); info->setMemory(1234567890); std::vector< unsigned int > ppos3(Dim3, 12); std::vector< float > wpos3( Dim3, static_cast< const float >( 1.2 ) ); info->setPixelPosition(ppos3); info->setWorldPosition(wpos3); std::vector< float > value(Dim3, 128.); info->setValue(value); info->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), info, SLOT( close() ) ); if ( atoi(argv[1]) == 1 ) { timer->start(500); } const unsigned int Dim4 = 4; info->setDimension(Dim4); info->setNumberOfChannels(Dim3); std::vector< unsigned int > size4(Dim4, 512); std::vector< float > spacing4( Dim4, static_cast< const float >( 0.1 ) ); info->setSize(size4); info->setSpacing(spacing4); info->setMemory(1234567890); info->setPixelPosition(ppos3); info->setWorldPosition(wpos3); info->setTimePoint(0.); info->setValue(value); info->show(); if ( atoi(argv[1]) == 1 ) { timer->start(500); } int output = app.exec(); app.closeAllWindows(); delete info; delete timer; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoContourManualSegmentationDockWidgetTest.cxx0000644000175000017500000000567711667757442027470 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoContourManualSegmentationWidget.h" int main(int argc, char **argv) { if ( argc != 2 ) { std::cerr << "QGoContourManualSegmentationDockWidgetTest requires 1 argument:" << std::endl; std::cerr << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoContourManualSegmentationWidget *dock = new QGoContourManualSegmentationWidget; dock->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), dock, SLOT( close() ) ); if ( atoi(argv[1]) == 1 ) { timer->start(100); } app.processEvents(); int output = app.exec(); app.closeAllWindows(); // std::cout <GetMeshId() <GetValidatedColor(); // std::cout < #include #include "vtkSmartPointer.h" #include "vtkPNGReader.h" #include "vtkImageGaussianSmooth.h" #include "vtkImageGradient.h" #include "QGoSynchronizedView2D.h" #include #include #include "vtksys/SystemTools.hxx" #include "itkImage.h" #include "itkSmartPointer.h" #include "itkImageFileReader.h" bool CheckSnapshot(QGoSynchronizedView *iViewer, GoFigure::FileType iType) { QString filename = iViewer->SnapshotViewXY(iType); std::string path = vtksys::SystemTools::GetCurrentWorkingDirectory(); path += "/"; path += filename.toStdString(); if ( vtksys::SystemTools::FileExists( path.c_str() ) ) { vtksys::SystemTools::RemoveFile( path.c_str() ); return true; } else { std::cerr << "FAILURE * viewer->SnapshotViewXY( " << iType << " )" << std::endl; return false; } } int main(int argc, char **argv) { if ( argc != 3 ) { std::cout << "Usage : QGoSynchronizedView2DTest(.exe) " << std::endl; std::cout << "1-file.png" << std::endl; std::cout << "2-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); // ITK Typedefs // ITK Reader and filters Typedef typedef double InputPixelType; typedef itk::Image< InputPixelType, 2 > InputImage2DType; typedef InputImage2DType::Pointer InputImage2DPointer; //itk reader typedef itk::ImageFileReader< InputImage2DType > itkReaderType; itkReaderType::Pointer itkReader = itkReaderType::New(); itkReader->SetFileName(argv[1]); itkReader->Update(); //vtk reader vtkSmartPointer< vtkPNGReader > reader = vtkSmartPointer< vtkPNGReader >::New(); reader->SetFileName(argv[1]); reader->Update(); QString cp0 = "itkImage"; QGoSynchronizedView2D *SynchronizedView0 = new QGoSynchronizedView2D(cp0, 0); QString cp1 = "vtkImage"; QGoSynchronizedView2D *SynchronizedView1 = new QGoSynchronizedView2D(cp1, 0); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), SynchronizedView0, SLOT( close() ) ); QObject::connect( timer, SIGNAL( timeout() ), SynchronizedView1, SLOT( close() ) ); SynchronizedView0->SetImage< InputPixelType >( itkReader->GetOutput() ); SynchronizedView0->Update(); SynchronizedView0->show(); SynchronizedView1->SetImage( reader->GetOutput() ); SynchronizedView1->Update(); SynchronizedView1->show(); if ( atoi(argv[2]) == 1 ) { if ( !CheckSnapshot(SynchronizedView0, GoFigure::BMP) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(SynchronizedView0, GoFigure::PNG) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(SynchronizedView0, GoFigure::JPEG) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(SynchronizedView0, GoFigure::EPS) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(SynchronizedView0, GoFigure::TIFF) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(SynchronizedView1, GoFigure::BMP) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(SynchronizedView1, GoFigure::PNG) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(SynchronizedView1, GoFigure::JPEG) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(SynchronizedView1, GoFigure::EPS) ) { return EXIT_FAILURE; } if ( !CheckSnapshot(SynchronizedView1, GoFigure::TIFF) ) { return EXIT_FAILURE; } timer->start(1000); } app.processEvents(); int output = app.exec(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/qgocreatemeshdialogtest.cxx0000644000175000017500000000375111667757442024005 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoCreateMeshDialog.h" int main(int argc, char *argv[]) { /* if( argc != 2 ) { return false; }*/ QApplication app(argc, argv); QGoCreateMeshDialog win; win.show(); return app.exec(); }GoFigure2-v0.9.0/Examples/GUI/lib/QGoDBInitCreateAuthorPageTest.cxx0000644000175000017500000000550211667757442024556 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoDBInitCreateMicroscopePage.h" #include "vtkRenderWindow.h" //**************************************************************************// // MAIN // //**************************************************************************// int main(int argc, char *argv[]) { if ( argc != 2 ) { std::cout << "Usage : ./VideoRecorderTest " << std::endl; std::cout << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QTimer * timer = new QTimer; timer->setSingleShot(true); QGoDBInitCreateMicroscopePage *window = new QGoDBInitCreateMicroscopePage(NULL); window->SetDatabaseVariables("user", "password"); QObject::connect( timer, SIGNAL( timeout() ), window, SLOT( close() ) ); if ( atoi(argv[1]) == 1 ) { timer->start(1000); } window->show(); app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete timer; delete window; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoSegmentationAlgoTest.cxx0000644000175000017500000001744311667757442023610 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "vtkSmartPointer.h" #include "vtkMetaImageReader.h" #include "itkImage.h" // helper for debugging #include "VisualizePolydataHelper.h" //converter to be tested #include "QGoMeshLevelSetAlgo.h" int main(int argc, char **argv) { QApplication app(argc, argv); if ( argc != 3 ) { std::cout << "Usage : QGoSynchronizedView2DTest(.exe) " << std::endl; std::cout << "1-file.mhd" << std::endl; std::cout << "2-test (boolean)" << std::endl; return EXIT_FAILURE; } vtkSmartPointer< vtkMetaImageReader > reader = vtkSmartPointer< vtkMetaImageReader >::New(); reader->SetFileName( argv[1] ); reader->Update(); std::cout << "Data Range: " << reader->GetOutput()->GetScalarRange()[0] << " to " << reader->GetOutput()->GetScalarRange()[1] << std::endl; std::cout << "Data Dimensions: " << reader->GetOutput()->GetDimensions()[0] << " x " << reader->GetOutput()->GetDimensions()[1] << " x " << reader->GetOutput()->GetDimensions()[2] < ImageType; typedef ImageType::Pointer ImageTypePointer; //------------------------------------------------------------------ // 3d //------------------------------------------------------------------ // extract roi std::vector< double > voi3D(6); voi3D[0] = 10; voi3D[1] = 20; voi3D[2] = 10; voi3D[3] = 20; voi3D[4] = 10; voi3D[5] = 20; vtkSmartPointer roi3D = vtkSmartPointer::New(); roi3D->ShallowCopy( algo.VTKExtractROI( voi3D, reader->GetOutput() )); assert( roi3D->GetDataDimension() == 3); // convert vtk to itk ImageTypePointer itkImage3D = algo.ConvertVTK2ITK< PixelType, dimension >(roi3D); // convert itk to vtk vtkSmartPointer vtkImage3D = vtkSmartPointer::New(); vtkImage3D->ShallowCopy(algo.ConvertITK2VTK< PixelType, dimension >(itkImage3D)); vtkImage3D->Update(); std::cout << "Dimension 3D: " << vtkImage3D->GetDataDimension() <GetDimensions()[0] << " x " << vtkImage3D->GetDimensions()[1] << " x " << vtkImage3D->GetDimensions()[2] <GetDataDimension() == 3); // Reconstruct polydata vtkSmartPointer poly3D = vtkSmartPointer::New(); poly3D->ShallowCopy(algo.ExtractPolyData( vtkImage3D, 100 )); ShowPolyData(poly3D); //------------------------------------------------------------------ // 3d - too large ROI //------------------------------------------------------------------ // extract roi std::vector< double > voi3D2Large(6); voi3D2Large[0] = 0; voi3D2Large[1] = 30; voi3D2Large[2] = 0; voi3D2Large[3] = 50; voi3D2Large[4] = 0; voi3D2Large[5] = 50; vtkSmartPointer roi3D2Large = vtkSmartPointer::New(); roi3D2Large->ShallowCopy(algo.VTKExtractROI( voi3D2Large, reader->GetOutput() )); assert( roi3D2Large->GetDataDimension() == 3); // convert vtk to itk ImageTypePointer itkImage3D2Large = algo.ConvertVTK2ITK< PixelType, dimension >(roi3D2Large); // convert itk to vtk vtkSmartPointer vtkImage3D2Large = vtkSmartPointer::New(); vtkImage3D2Large->ShallowCopy(algo.ConvertITK2VTK< PixelType, dimension >(itkImage3D2Large)); vtkImage3D2Large->Update(); std::cout << "Dimension 3D Too Large: " << vtkImage3D2Large->GetDataDimension() <GetDimensions()[0] << " x " << vtkImage3D2Large->GetDimensions()[1] << " x " << vtkImage3D2Large->GetDimensions()[2] <GetDataDimension() == 3); // Reconstruct polydata vtkSmartPointer poly3D2Large = vtkSmartPointer::New(); poly3D2Large->ShallowCopy(algo.ExtractPolyData( vtkImage3D2Large, 100 )); ShowPolyData(poly3D2Large); // Decimate polydata vtkSmartPointer decimate3D = vtkSmartPointer::New(); decimate3D->ShallowCopy(algo.DecimatePolyData(poly3D2Large, 200)); ShowPolyData(decimate3D); //------------------------------------------------------------------ // 2d //------------------------------------------------------------------ // extract roi std::vector< double > voi2D(6); voi2D[0] = 15; voi2D[1] = 15; voi2D[2] = 0; voi2D[3] = 30; voi2D[4] = 0; voi2D[5] = 30; vtkSmartPointer roi2D = vtkSmartPointer::New(); roi2D->ShallowCopy(algo.VTKExtractROI( voi2D, reader->GetOutput() )); assert( roi2D->GetDataDimension() == 2); // convert vtk to itk ImageTypePointer itkImage2D = algo.ConvertVTK2ITK< PixelType, dimension >(roi2D); // convert itk to vtk vtkSmartPointer vtkImage2D = vtkSmartPointer::New(); vtkImage2D->ShallowCopy(algo.ConvertITK2VTK< PixelType, dimension >(itkImage2D)); vtkImage2D->Update(); std::cout << "Dimension 2D: " << vtkImage2D->GetDataDimension() <GetDimensions()[0] << " x " << vtkImage2D->GetDimensions()[1] << " x " << vtkImage2D->GetDimensions()[2] <GetDataDimension() == 2); // Reconstruct polydata vtkSmartPointer poly2D = vtkSmartPointer::New(); poly2D->ShallowCopy(algo.ExtractPolyData( vtkImage2D, 100 )); ShowPolyData(poly2D); vtkSmartPointer decimate2D = vtkSmartPointer::New(); decimate2D->ShallowCopy(algo.DecimatePolyData(poly2D, 10)); ShowPolyData(decimate2D); return EXIT_SUCCESS; } GoFigure2-v0.9.0/Examples/GUI/lib/qgotabimageviewelementbase.cxx0000644000175000017500000000726011667757442024455 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "QGoTabImageViewElementBase.h" #include "vtkImageData.h" class QGoTabImageViewElementBaseTestHelper : public QGoTabImageViewElementBase { public: explicit QGoTabImageViewElementBaseTestHelper(QWidget *iParent = 0) : QGoTabImageViewElementBase(iParent) { } virtual ~QGoTabImageViewElementBaseTestHelper() { } GoFigure::TabDimensionType GetTabDimensionType() const { return GoFigure::TWO_D; } virtual void Update() { } virtual void WriteSettings() { } virtual void ReadSettings() { } public slots: virtual void ShowAllChannels(bool iChecked) { (void)iChecked; } virtual void ShowOneChannel(int iChannel) { (void)iChannel; } virtual void TakeSnapshot() { } protected: virtual void PopulateMenus(QObject *iPlugin) { (void)iPlugin; } virtual void GetBackgroundColorFromImageViewer() { } virtual void SetBackgroundColorToImageViewer() { } virtual void SetImageToImageViewer(vtkImageData *) { } virtual int * GetImageCoordinatesFromWorldCoordinates(double iPos[3]) { (void)iPos; return 0; } virtual void RemoveActorFromViewer(const int &, vtkActor *) { } virtual void DisplayActorInViewer(const int &, vtkActor *) { } virtual std::vector< vtkActor * > AddContour(vtkPolyData *, vtkProperty *iProperty = NULL) { (void)iProperty; return std::vector< vtkActor * >(); } virtual void SetSlice(int, int *) { } }; int main(int argc, char **argv) { QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QCoreApplication::setApplicationName("qgotabimageviewelementbase"); QGoTabImageViewElementBaseTestHelper *test = new QGoTabImageViewElementBaseTestHelper; test->SetColor(true); delete test; return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/GUI/lib/qgotabimageview2d.cxx0000644000175000017500000000653411667757442022501 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "vtkPNGReader.h" #include "vtkImageData.h" #include "vtkSmartPointer.h" #include "QGoTabImageView2D.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cerr << "qgotabimageview2d requires 2 arguments:" << std::endl; std::cerr << "1-png filename" << std::endl; std::cerr << "2-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); vtkSmartPointer< vtkPNGReader > reader = vtkSmartPointer< vtkPNGReader >::New(); reader->SetFileName(argv[1]); reader->Update(); QGoTabImageView2D *tab = new QGoTabImageView2D; tab->SetImage( reader->GetOutput() ); tab->Update(); tab->ActivateManualSegmentationEditor(true); tab->show(); QMenuBar * menubar = new QMenuBar; std::vector< QAction * > action_vector = tab->ViewActions(); for ( std::vector< QAction * >::iterator q_it = action_vector.begin(); q_it != action_vector.end(); ++q_it ) { menubar->addAction(*q_it); } menubar->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), tab, SLOT( close() ) ); QObject::connect( timer, SIGNAL( timeout() ), menubar, SLOT( close() ) ); if ( atoi(argv[2]) == 1 ) { timer->start(1000); } app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete menubar; delete tab; return output; } GoFigure2-v0.9.0/Examples/GUI/lib/QGoLsmToMegaExportDialogTest.cxx0000644000175000017500000000516411667757442024517 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoLsmToMegaExportDialog.h" int main(int argc, char **argv) { if ( argc != 2 ) { std::cout << "Usage : ./QGoLsmToMegaExportDialogTest " << std::endl; std::cout << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QTimer *timer = new QTimer; timer->setSingleShot(true); QGoLsmToMegaExportDialog *dlg = new QGoLsmToMegaExportDialog; QObject::connect( timer, SIGNAL( timeout() ), dlg, SLOT( accept() ) ); if ( atoi(argv[1]) == 1 ) { timer->start(1000); } dlg->show(); app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete dlg; delete timer; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/qgosynchronizedview3dtest.cxx0000644000175000017500000001776011667757442024353 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "vtkSmartPointer.h" #include "vtkMetaImageReader.h" #include "QGoSynchronizedView3D.h" #include #include #include "itkImage.h" #include "itkSmartPointer.h" #include "itkImageFileReader.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cout << "Usage : QGoSynchronizedView3DTest(.exe) " << std::endl; std::cout << "1-file.mhd" << std::endl; std::cout << "2-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); // ITK Typedefs // ITK Reader and filters Typedef typedef double InputPixelType; typedef itk::Image< InputPixelType, 3 > InputImage3DType; typedef InputImage3DType::Pointer InputImage3DPointer; //itk reader typedef itk::ImageFileReader< InputImage3DType > itkReaderType; itkReaderType::Pointer itkReader = itkReaderType::New(); itkReader->SetFileName(argv[1]); itkReader->Update(); //vtk reader vtkSmartPointer< vtkMetaImageReader > reader = vtkSmartPointer< vtkMetaImageReader >::New(); reader->SetFileName(argv[1]); reader->Update(); QString cp0 = "itk sync view"; QGoSynchronizedView3D *SynchronizedView0 = new QGoSynchronizedView3D(cp0, 0); QString cp1 = "vtk sync view"; QGoSynchronizedView3D *SynchronizedView1 = new QGoSynchronizedView3D(cp1, 0); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), SynchronizedView0, SLOT( close() ) ); QObject::connect( timer, SIGNAL( timeout() ), SynchronizedView1, SLOT( close() ) ); SynchronizedView0->SetImage< InputPixelType >( itkReader->GetOutput() ); SynchronizedView0->Update(); SynchronizedView0->show(); SynchronizedView1->SetImage( reader->GetOutput() ); SynchronizedView1->Update(); SynchronizedView1->show(); if ( atoi(argv[2]) == 1 ) { timer->start(1500); SynchronizedView0->SetFullScreenView(1); if ( SynchronizedView0->GetFullScreenView() != 1 ) { std::cerr << "SynchronizedView0->GetFullScreenView() = " << SynchronizedView0->GetFullScreenView(); std::cerr << " != 1" << std::endl; app.closeAllWindows(); reader->Delete(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return EXIT_FAILURE; } SynchronizedView0->SetFullScreenView(2); if ( SynchronizedView0->GetFullScreenView() != 2 ) { std::cerr << "SynchronizedView0->GetFullScreenView() = " << SynchronizedView0->GetFullScreenView(); std::cerr << " != 2" << std::endl; app.closeAllWindows(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return EXIT_FAILURE; } SynchronizedView0->SetFullScreenView(3); if ( SynchronizedView0->GetFullScreenView() != 3 ) { std::cerr << "SynchronizedView0->GetFullScreenView() = " << SynchronizedView0->GetFullScreenView(); std::cerr << " != 3" << std::endl; app.closeAllWindows(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return EXIT_FAILURE; } SynchronizedView0->SetFullScreenView(4); if ( SynchronizedView0->GetFullScreenView() != 4 ) { std::cerr << "SynchronizedView0->GetFullScreenView() = " << SynchronizedView0->GetFullScreenView(); std::cerr << " != 4" << std::endl; app.closeAllWindows(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return EXIT_FAILURE; } SynchronizedView0->SetFullScreenView(0); if ( SynchronizedView0->GetFullScreenView() != 0 ) { std::cerr << "SynchronizedView0->GetFullScreenView() = " << SynchronizedView0->GetFullScreenView(); std::cerr << " != 0" << std::endl; app.closeAllWindows(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return EXIT_FAILURE; } SynchronizedView1->SetFullScreenView(1); if ( SynchronizedView1->GetFullScreenView() != 1 ) { std::cerr << "SynchronizedView1->GetFullScreenView() = " << SynchronizedView1->GetFullScreenView(); std::cerr << " != 1" << std::endl; app.closeAllWindows(); reader->Delete(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return EXIT_FAILURE; } SynchronizedView1->SetFullScreenView(2); if ( SynchronizedView1->GetFullScreenView() != 2 ) { std::cerr << "SynchronizedView1->GetFullScreenView() = " << SynchronizedView1->GetFullScreenView(); std::cerr << " != 2" << std::endl; app.closeAllWindows(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return EXIT_FAILURE; } SynchronizedView1->SetFullScreenView(3); if ( SynchronizedView1->GetFullScreenView() != 3 ) { std::cerr << "SynchronizedView1->GetFullScreenView() = " << SynchronizedView1->GetFullScreenView(); std::cerr << " != 3" << std::endl; app.closeAllWindows(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return EXIT_FAILURE; } SynchronizedView1->SetFullScreenView(4); if ( SynchronizedView1->GetFullScreenView() != 4 ) { std::cerr << "SynchronizedView1->GetFullScreenView() = " << SynchronizedView1->GetFullScreenView(); std::cerr << " != 4" << std::endl; app.closeAllWindows(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return EXIT_FAILURE; } SynchronizedView1->SetFullScreenView(0); if ( SynchronizedView1->GetFullScreenView() != 0 ) { std::cerr << "SynchronizedView1->GetFullScreenView() = " << SynchronizedView1->GetFullScreenView(); std::cerr << " != 0" << std::endl; app.closeAllWindows(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return EXIT_FAILURE; } } app.processEvents(); int output = app.exec(); delete timer; delete SynchronizedView0; delete SynchronizedView1; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoWizardDBTest.cxx0000644000175000017500000000603611667757442022012 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoWizardDB.h" int main(int argc, char *argv[]) { if ( argc != 2 ) { std::cerr << "QGoWizardTest requires 1 argument:" << std::endl; std::cerr << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } //Q_INIT_RESOURCE(qgocreatedb); QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoWizardDB *wizard = new QGoWizardDB; wizard->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), wizard, SLOT( close() ) ); int output; bool test = ( atoi(argv[1]) == 1 ); if ( test ) { timer->start(1000); output = EXIT_SUCCESS; } else { output = app.exec(); } if ( !test ) { std::vector< std::vector< std::string > > filenames = wizard->GetFilenamesFromDB(); for ( unsigned int i = 0; i < filenames.size(); i++ ) { for ( unsigned int j = 0; j < filenames[i].size(); j++ ) { std::cout << "image filename with channel " << i << " " << filenames[i][j].c_str() << std::endl; } } } delete wizard; delete timer; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoColorComboBoxTest.cxx0000644000175000017500000000641111667757442023050 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "QGoSelectedColorComboBox.h" #include "QGoPrintDatabase.h" int main(int argc, char *argv[]) { if ( argc != 3 ) { std::cerr << "QGoColorComboTest requires 2 arguments:" << std::endl; std::cerr << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoSelectedColorComboBox *win = new QGoSelectedColorComboBox; QGoPrintDatabase * DBTables = new QGoPrintDatabase; DBTables->SetDatabaseVariables("gofiguredatabase", "localhost", "gofigure", "gofigure", atoi(argv[1]), argv[2]); //win->setItemsWithColorFromDB(DBTables->GetColorComboBoxInfofromDB()); //DBTables->SetColorComboBoxInfofromDB(); //QGoPrintDatabase* win = new QGoPrintDatabase; // win.FillTableFromDatabase(argv[1],"localhost","gofigure", // "gofigure",atoi(argv[2]), argv[3]); //win->SetDatabaseVariables( // "gofiguredatabase", "localhost", "gofigure", // "gofigure", 8, "LSM_Converter"); // win->FillTableFromDatabase(2); win->show(); /* QTimer* timer = new QTimer; timer->setSingleShot(true); QObject::connect(timer, SIGNAL(timeout()), win, SLOT(close())); if (atoi(argv[1]) == 0) { timer->start(1000); }*/ int output = app.exec(); app.closeAllWindows(); delete win; // delete timer; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoMeshEditingWidgetManagerTest.cxx0000644000175000017500000000636411667757442025207 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "QGoMeshEditingWidgetManager.h" #include "QGoTraceSettingsWidget.h" #include "QGoModesManagerWidget.h" #include "QGoAlgorithmWidget.h" #include "QGoTraceSettingsWidget.h" #include "QGoAlgoParameter.h" #include "vtkSmartPointer.h" #include "vtkPolyData.h" #include "vtkImageData.h" //**************************************************************************// // MAIN // //**************************************************************************// int main(int argc, char *argv[]) { if ( argc != 1 ) { return EXIT_FAILURE; } QApplication app(argc, argv); //QTimer * timer = new QTimer; //timer->setSingleShot(true); std::vector ChannelName; ChannelName.push_back("Channel 1"); ChannelName.push_back("Channel 2"); QStringList ListTimePoint; ListTimePoint.append("t-1"); ListTimePoint.append("t"); ListTimePoint.append("t+1"); vtkPoints* Seeds = NULL; std::vector< vtkSmartPointer< vtkImageData > >* Images = NULL; QGoMeshEditingWidgetManager* MeshEditing = new QGoMeshEditingWidgetManager(ChannelName, ListTimePoint, Seeds, Images, NULL); //QObject::connect( timer, SIGNAL( timeout() ), window, SLOT( close() ) ); //timer->start(1000); MeshEditing->showWidget(); app.processEvents(); int output = app.exec(); app.closeAllWindows(); //delete timer; delete MeshEditing; return output; } GoFigure2-v0.9.0/Examples/GUI/lib/vtkAVIRenderWindowRecorderTest.cxx0000644000175000017500000001141211667757442025111 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ //For the visualization #include "vtkSphereSource.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRenderWindow.h" #include "vtkRenderer.h" #include "vtkRenderWindowInteractor.h" #include "vtkProperty.h" #include "vtksys/SystemTools.hxx" #include "vtkAVIRenderWindowRecorder.h" #include int main(int argc, char *argv[]) { if ( argc != 2 ) { std::cerr << "Usage: " << std::endl; std::cerr << "" << std::endl; return EXIT_FAILURE; } int err = 0; int exists = 0; unsigned long length = 0; // create sphere geometry vtkSphereSource *sphere = vtkSphereSource::New(); sphere->SetRadius(1.0); sphere->SetThetaResolution(18); sphere->SetPhiResolution(18); // map to graphics library vtkPolyDataMapper *map = vtkPolyDataMapper::New(); map->SetInput( sphere->GetOutput() ); // actor creation and properties definition vtkActor *aSphere = vtkActor::New(); aSphere->SetMapper(map); aSphere->GetProperty()->SetColor(1, 1, 1); aSphere->GetProperty()->SetOpacity(0.5); // a renderer and render window vtkRenderer * ren1 = vtkRenderer::New(); vtkRenderWindow *renWin = vtkRenderWindow::New(); renWin->AddRenderer(ren1); // an interactor vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); iren->SetRenderWindow(renWin); iren->Initialize(); // add the actor to the scene ren1->AddActor(aSphere); ren1->SetBackground(1, 0, 0); // Background color white // create the video vtkAVIRenderWindowRecorder *testRecorder = vtkAVIRenderWindowRecorder::New(); testRecorder->SetRenderingWindow(renWin); testRecorder->SetFileName(argv[1]); testRecorder->SetFrameRate(10); testRecorder->SetVideoQuality(1); testRecorder->SetSpecificParameters(); testRecorder->StartCapture(); for ( int i = 0; i < 30; i++ ) { renWin->Render(); testRecorder->TakeSnapshot(); } ren1->SetBackground(0, 1, 0); for ( int i = 0; i < 30; i++ ) { renWin->Render(); testRecorder->TakeSnapshot(); } ren1->SetBackground(0, 0, 1); for ( int i = 0; i < 30; i++ ) { renWin->Render(); testRecorder->TakeSnapshot(); } testRecorder->EndCapture(); std::cout << "End capture" << std::endl; // Test exists = (int)vtksys::SystemTools::FileExists(argv[1]); length = vtksys::SystemTools::FileLength(argv[1]); cout << "TestAVIRecorder file exists: " << exists << endl; cout << "TestAVIRecorder file length: " << length << endl; if ( !exists ) { err = 1; cerr << "ERROR: 1 - Test failing because TestAVIRecorder file doesn't exist..." << endl; } else { vtksys::SystemTools::RemoveFile(argv[1]); } if ( 0 == length ) { err = 2; cerr << "ERROR: 2 - Test failing because TestAVIRecorder file has zero length..." << endl; } // Delete everything sphere->Delete(); map->Delete(); aSphere->Delete(); ren1->Delete(); renWin->Delete(); iren->Delete(); testRecorder->Delete(); // err = 0 means that the test succeeded return err; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoTraceSettingsWidgetTest.cxx0000644000175000017500000000447511667757442024274 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoTraceSettingsWidget.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QGoTraceSettingsWidget *win = new QGoTraceSettingsWidget(); //QTimer* timer = new QTimer; //timer->setSingleShot( true ); //QObject::connect( timer, SIGNAL( timeout() ), win, SLOT( close() ) ); win->show(); // if( atoi( argv[1] ) == 1 ) // { // timer->start( 1000 ); // } app.processEvents(); int output = app.exec(); app.closeAllWindows(); // delete timer; delete win; return output; }GoFigure2-v0.9.0/Examples/GUI/lib/QGoTraceEditingWidgetTest.cxx0000644000175000017500000001332211667757442024046 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "QGoTraceEditingWidget.h" #include "QGoTraceSettingsWidget.h" #include "QGoModesManagerWidget.h" #include "QGoAlgorithmWidget.h" #include "QGoTraceSettingsWidget.h" #include "QGoAlgoParameter.h" //**************************************************************************// // MAIN // //**************************************************************************// int main(int argc, char *argv[]) { if ( argc != 1 ) { return EXIT_FAILURE; } QApplication app(argc, argv); //QTimer * timer = new QTimer; //timer->setSingleShot(true); QStringList ChannelName; ChannelName.append("Channel 1"); ChannelName.append("Channel 2"); QStringList ListTimePoint; ListTimePoint.append("t-1"); ListTimePoint.append("t"); ListTimePoint.append("t+1"); QGoTraceEditingWidget* MeshEditing = new QGoTraceEditingWidget( "Mesh", ChannelName, ListTimePoint, NULL); //semi automated mode //QGoAlgorithmsManagerWidget* SemiAutomatedMethodsWidget = new QGoAlgorithmsManagerWidget("Semi Automated", // ChannelName, ListTimePoint, MeshEditing); //levelSet QGoAlgorithmWidget* LevelSetWidget = new QGoAlgorithmWidget("LevelSet", MeshEditing);//SemiAutomatedMethodsWidget); //def of the parameters: QGoAlgoParameter Radius ("Radius", false, 0, 10, 3); QGoAlgoParameter Curvature ("Curvature", true, 0, 100, 20); QGoAlgoParameter Iteration ("Iterations", true,0, 1000, 100); LevelSetWidget->AddParameter(&Radius); LevelSetWidget->AddParameter(&Curvature); LevelSetWidget->AddParameter(&Iteration); //Shape3D QGoAlgorithmWidget* Shape3D = new QGoAlgorithmWidget("Shape 3D", MeshEditing);//SemiAutomatedMethodsWidget); Shape3D->AddParameter(&Radius); QStringList ShapeList; ShapeList.append("Sphere"); ShapeList.append("Cube"); QGoAlgoParameter Shape("Shape", true, ShapeList, "Sphere"); Shape3D->AddParameter(&Shape); //watershed QGoAlgorithmWidget* WaterShedWidget = new QGoAlgorithmWidget("WaterShed", MeshEditing);//SemiAutomatedMethodsWidget); WaterShedWidget->AddParameter(&Radius); QGoAlgoParameter ThresMin("Thres.Min.", true, 0, 10, 20); WaterShedWidget->AddParameter(&ThresMin); QGoAlgoParameter ThresMax("Thres.Max.", true, 0, 50, 30); WaterShedWidget->AddParameter(&ThresMax); QGoAlgoParameter CorrThres("Corr.Thres.", true, 0, 5, 2, 2); WaterShedWidget->AddParameter(&CorrThres); QGoAlgoParameter Alpha("Alpha", true, 0, 5, 2, 1.5); WaterShedWidget->AddParameter(&Alpha); QGoAlgoParameter Beta("Beta", true, 0, 5, 1, 3); WaterShedWidget->AddParameter(&Beta); //SemiAutomatedMethodsWidget->AddMethod(LevelSetWidget); //SemiAutomatedMethodsWidget->AddMethod(WaterShedWidget); //SemiAutomatedMethodsWidget->AddMethod(Shape3D); MeshEditing->AddAlgoWidgetForSemiAutomatedMode(LevelSetWidget); MeshEditing->AddAlgoWidgetForSemiAutomatedMode(WaterShedWidget); MeshEditing->AddAlgoWidgetForSemiAutomatedMode(Shape3D); //QGoModesManagerWidget* SemiAutomatedMode = new QGoModesManagerWidget(NULL); //SemiAutomatedMode->AddAlgoManagerWidget(SemiAutomatedMethodsWidget); //MeshEditing->SetModesManager(SemiAutomatedMode); //add mode: QGoTraceSettingsWidget* TestAddMode = new QGoTraceSettingsWidget(MeshEditing); MeshEditing->AddMode("TestAddMode", TestAddMode); MeshEditing->CheckDefaultModes(); //QObject::connect( timer, SIGNAL( timeout() ), window, SLOT( close() ) ); //timer->start(1000); MeshEditing->show(); app.processEvents(); int output = app.exec(); std::cout<< "Alpha "<< Alpha.GetValue()< #include #include #include "QGoModesManagerWidget.h" #include "QGoAlgorithmWidget.h" #include "QGoAlgoParameter.h" //**************************************************************************// // MAIN // //**************************************************************************// int main(int argc, char *argv[]) { if ( argc != 1 ) { return EXIT_FAILURE; } QApplication app(argc, argv); //QTimer * timer = new QTimer; //timer->setSingleShot(true); QStringList ChannelName; ChannelName.append("Channel 1"); ChannelName.append("Channel 2"); QStringList ListTimePoint; ListTimePoint.append("t-1"); ListTimePoint.append("t"); ListTimePoint.append("t+1"); QGoModesManagerWidget* MeshMode = new QGoModesManagerWidget(ChannelName, ListTimePoint, NULL); //QGoAlgorithmsManagerWidget* SemiAutoModeMeshEditingAlgoWidget = new QGoAlgorithmsManagerWidget( // "Semi Automated",ChannelName, ListTimePoint, NULL); QGoAlgorithmWidget* LevelSetWidget = new QGoAlgorithmWidget("LevelSet", MeshMode); //SemiAutoModeMeshEditingAlgoWidget); QGoAlgoParameter Radius ("Radius", false, 0, 10, 2, 3); LevelSetWidget->AddParameter(&Radius); QGoAlgoParameter Curvature ("Curvature", true, 0, 100, 20); LevelSetWidget->AddParameter(&Curvature); QGoAlgoParameter Iteration ("Iterations", true, 0, 1000, 100); LevelSetWidget->AddParameter(&Iteration); //LevelSetWidget->AddParameter("Channel", ChannelName); //LevelSetWidget->AddParameter("Radius", 0, 10, 3); //LevelSetWidget->AddAdvParameter("Curvature", 0, 100, 20); //LevelSetWidget->AddAdvParameter("Iterations", 0, 1000, 100); QGoAlgorithmWidget* Shape3D = new QGoAlgorithmWidget("Shape 3D", MeshMode);//SemiAutoModeMeshEditingAlgoWidget); //Shape3D->AddParameter("Channel", ChannelName); //Shape3D->AddParameter("Radius", 0, 10, 3); Shape3D->AddParameter(&Radius); QStringList ShapeList; ShapeList.append("Sphere"); ShapeList.append("Cube"); QGoAlgoParameter Shape("Shape",true, ShapeList, "Sphere"); //Shape3D->AddAdvParameter("Shape", ShapeList); Shape3D->AddParameter(&Shape); QGoAlgorithmWidget* WaterShedWidget = new QGoAlgorithmWidget("WaterShed", MeshMode);//SemiAutoModeMeshEditingAlgoWidget); //WaterShedWidget->AddParameter("Channel", ChannelName); //WaterShedWidget->AddParameter("Radius", 0, 10, 3); WaterShedWidget->AddParameter(&Radius); QGoAlgoParameter ThresMin ("Thres.Min.", true, 0, 100, 20); WaterShedWidget->AddParameter(&ThresMin); //WaterShedWidget->AddAdvParameter ("Thres.Min.", 0, 100, 20); QGoAlgoParameter ThresMax ("Thres.Max.", true, 0, 30, 50); WaterShedWidget->AddParameter(&ThresMax); // WaterShedWidget->AddAdvParameter("Thres.Min.", 0, 30, 50); QGoAlgoParameter CorrThres ("Corr.Thres.", true, 0, 5, 2, 2); WaterShedWidget->AddParameter(&CorrThres); //WaterShedWidget->AddAdvParameter("Corr.Thres.", 0, 5, 2, 2); QGoAlgoParameter Alpha ("Alpha", true, 0, 5, 1.50, 2); WaterShedWidget->AddParameter(&Alpha); //WaterShedWidget->AddAdvParameter("Alpha", 0, 5, 1.50, 2); QGoAlgoParameter Beta ("Beta", true, 0, 5, 3, 1); WaterShedWidget->AddParameter(&Beta); //WaterShedWidget->AddAdvParameter("Beta", 0, 5, 3, 1); //SemiAutoModeMeshEditingAlgoWidget->AddMethod(LevelSetWidget); //SemiAutoModeMeshEditingAlgoWidget->AddMethod(WaterShedWidget); //SemiAutoModeMeshEditingAlgoWidget->AddMethod(Shape3D); MeshMode->AddAlgoWidgetForSemiAutomatedMode(LevelSetWidget); MeshMode->AddAlgoWidgetForSemiAutomatedMode(WaterShedWidget); MeshMode->AddAlgoWidgetForSemiAutomatedMode(Shape3D); MeshMode->CheckDefaultModes(); //MeshMode->AddAlgoManagerWidget(SemiAutoModeMeshEditingAlgoWidget); //MeshMode->AddWidgetWithModeName("Test", SemiAutoModeMeshEditingAlgoWidget); //SemiAutomatedMode->AddMethod(WaterShedWidget); //SemiAutomatedMode->AddMethod(Shape3D); //QObject::connect( timer, SIGNAL( timeout() ), SemiAutoModeMeshEditingAlgoWidget, SLOT( close() ) ); //timer->start(1000); MeshMode->show(); app.processEvents(); int output = app.exec(); app.closeAllWindows(); //delete timer; // delete SemiAutoModeMeshEditingAlgoWidget; delete MeshMode; return output; } GoFigure2-v0.9.0/Examples/GUI/lib/QGoTrackEditingWidgetTest.cxx0000644000175000017500000001105311667757442024053 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include "QGoTrackEditingWidget.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QGoTrackEditingWidget *win = new QGoTrackEditingWidget(); // Define some tracks manually typedef std::pair< int, std::pair< int, double * > > Mesh; typedef std::pair< int, std::list< Mesh > > Track; // Create meshes Mesh mesh0; mesh0.first = 1; mesh0.second.first = 2; double *position0 = new double[3]; position0[0] = 10; position0[1] = 10; position0[2] = 10; mesh0.second.second = position0; Mesh mesh1; mesh1.first = 3; mesh1.second.first = 4; double *position1 = new double[3]; position1[0] = 20; position1[1] = 20; position1[2] = 20; mesh1.second.second = position1; Mesh mesh2; mesh2.first = 5; mesh2.second.first = 6; double *position2 = new double[3]; position2[0] = 30; position2[1] = 30; position2[2] = 30; mesh2.second.second = position2; Track track0; track0.first = 9; track0.second.push_back(mesh0); track0.second.push_back(mesh1); track0.second.push_back(mesh2); // Create meshes Mesh mesh02; mesh02.first = 12; mesh02.second.first = 22; double *position02 = new double[3]; position02[0] = 102; position02[1] = 102; position02[2] = 102; mesh02.second.second = position02; Mesh mesh12; mesh12.first = 32; mesh12.second.first = 42; double *position12 = new double[3]; position12[0] = 202; position12[1] = 202; position12[2] = 202; mesh12.second.second = position12; Mesh mesh22; mesh22.first = 52; mesh22.second.first = 62; double *position22 = new double[3]; position22[0] = 302; position22[1] = 302; position22[2] = 302; mesh22.second.second = position22; Track track02; track02.first = 92; track02.second.push_back(mesh02); track02.second.push_back(mesh12); track02.second.push_back(mesh22); std::list< Track > trackList; trackList.push_back(track0); trackList.push_back(track02); /* Mesh mesh0; mesh0.first = 1; mesh0.second.first = 2; double* position0 = new double[3]; position0[0] = 10; position0[1] = 10; position0[2] = 10; mesh0.second.second = 2; Mesh mesh0; mesh0.first = 1; mesh0.second.first = 2; double* position0 = new double[3]; position0[0] = 10; position0[1] = 10; position0[2] = 10; mesh0.second.second = 2; Mesh mesh0; mesh0.first = 1; mesh0.second.first = 2; double* position0 = new double[3]; position0[0] = 10; position0[1] = 10; position0[2] = 10; mesh0.second.second = 2; */ win->setTracks(trackList); win->generateTrackRepresentation(); win->show(); // if( atoi( argv[1] ) == 1 ) // { // timer->start( 1000 ); // } app.processEvents(); int output = app.exec(); app.closeAllWindows(); // delete timer; delete win; return output; }GoFigure2-v0.9.0/Examples/CMakeLists.txt0000644000175000017500000000015411667757442017712 0ustar mathieumathieuADD_SUBDIRECTORY( ExternalCode ) ADD_SUBDIRECTORY( Filters ) ADD_SUBDIRECTORY( IO ) ADD_SUBDIRECTORY( GUI ) GoFigure2-v0.9.0/Examples/Attic/0000755000175000017500000000000011667757442016216 5ustar mathieumathieuGoFigure2-v0.9.0/Examples/Attic/multifilereader.cxx0000644000175000017500000000702711667757442022125 0ustar mathieumathieu/*========================================================================= Author: $Author$ // Author of last commit Version: $Rev$ // Revision of last commit Date: $Date$ // Date of last commit =========================================================================*/ /*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "itkMegaCaptureImport.h" #include "itkMultiFileReader.h" #include "vtkImageData.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cout << "Usage: ./multifilereader(.exe) takes 2 arguments" << std::endl; std::cout << "1-filename (.jpg)" << std::endl; std::cout << "2-timebased (boolean)" << std::endl; return EXIT_FAILURE; } itk::MegaCaptureImport::Pointer importer = itk::MegaCaptureImport::New(); importer->SetFileName(argv[1]); importer->Update(); GoFigureFileInfoHelperMultiIndexContainer listoffiles = importer->GetOutput(); // bool timebased = ( atoi( argv[2] ) == 0 ); // // itk::MultiFileReader::Pointer reader = itk::MultiFileReader::New(); // reader->SetTimeBased( timebased ); // reader->SetDimensionality( 2 ); // reader->SetFileType( itk::MultiFileReader::JPEG ); // reader->MultiChannelImagesOn(); // // if( timebased ) // { // std::sort( listoffiles->begin(), listoffiles->end(), // GoFigureFileInfoHelperTimeBasedCompare() ); // } // else // { // std::sort( listoffiles->begin(), listoffiles->end(), // GoFigureFileInfoHelperZCoordBasedCompare() ); // } // // reader->SetInput( listoffiles ); // // if( timebased ) // { // reader->SetTimePoint( 0 ); // } // else // { // reader->SetZDepth( 0 ); // } // // reader->Update(); // // vtkImageData* image = reader->GetOutput(); // std::cout <<*image <Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/Attic/kishmeshtextfilereader.cxx0000644000175000017500000000463511667757442023515 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "MeshTextFileImport.h" #include #include int main(int argc, char **argv) { if ( argc != 4 ) { std::cerr << "./kishmeshtextfilereader 3 arguments:" << std::endl; std::cerr << "1-directory (path: ex: ~/Data/)" << std::endl; std::cerr << "2-filename (ex: 0.txt)" << std::endl; std::cerr << "3-ImagingSessionId (number)" << std::endl; return EXIT_FAILURE; } MeshTextFileImport reader( "localhost", "gofigure", "gofigure", "gofiguredatabase", atoi(argv[3]) ); reader.SetDirectory(argv[1]); reader.SetFileName(argv[2]); reader.Read(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/Attic/qgotabimageview4d.cxx0000644000175000017500000000755611667757442022362 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "QGoTabImageView4D.h" #include "itkMegaCaptureImport.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cerr << "qgotabimageview4d requires 2 arguments:" << std::endl; std::cerr << "1-filename(.jpg)" << std::endl; std::cerr << "2-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); typedef itk::MegaCaptureImport MegaCaptureImportType; MegaCaptureImportType::Pointer importFileInfoList = MegaCaptureImportType::New(); importFileInfoList->SetFileName(argv[1]); importFileInfoList->Update(); QGoTabImageView4D *tab = new QGoTabImageView4D; tab->SetMegaCaptureFile( importFileInfoList->GetOutput(), GoFigure::PNG, importFileInfoList->GetHeaderFilename() ); tab->Update(); tab->show(); QMenuBar * menubar = new QMenuBar; std::vector< QAction * > action_vector = tab->ViewActions(); for ( std::vector< QAction * >::iterator q_it = action_vector.begin(); q_it != action_vector.end(); ++q_it ) { menubar->addAction(*q_it); } menubar->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), tab, SLOT( close() ) ); QObject::connect( timer, SIGNAL( timeout() ), menubar, SLOT( close() ) ); std::list< std::pair< QGoDockWidgetStatus *, QDockWidget * > > dockwidget_list = tab->DockWidget(); for ( std::list< std::pair< QGoDockWidgetStatus *, QDockWidget * > >::iterator it = dockwidget_list.begin(); it != dockwidget_list.end(); ++it ) { if ( it->second ) { it->second->show(); QObject::connect( timer, SIGNAL( timeout() ), it->second, SLOT( close() ) ); } } if ( atoi(argv[2]) == 1 ) { timer->start(1000); } tab->show(); app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete tab; return output; } GoFigure2-v0.9.0/Examples/Attic/trackTextFilesReader.cxx0000644000175000017500000000464011667757442023025 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "TrackTextFileImport.h" #include #include int main(int argc, char **argv) { if ( argc != 4 ) { std::cerr << "./kishmeshtextfilereader 3 arguments:" << std::endl; std::cerr << "1-directory (path: ex: ~/Data/)" << std::endl; std::cerr << "2-filename (ex: 0.txt)" << std::endl; std::cerr << "3-ImagingSessionId (number)" << std::endl; return EXIT_FAILURE; } TrackTextFileImport reader( "localhost", "gofigure", "gofigure", "gofiguredatabase", atoi(argv[3]) ); reader.SetDirectory(argv[1]); reader.SetFileName(argv[2]); reader.Read(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/ExternalCode/0000755000175000017500000000000011667757442017527 5ustar mathieumathieuGoFigure2-v0.9.0/Examples/ExternalCode/MegaVTK/0000755000175000017500000000000011667757442020765 5ustar mathieumathieuGoFigure2-v0.9.0/Examples/ExternalCode/MegaVTK/vtkviewimage3dtest.cxx0000644000175000017500000000524711667757442025352 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkMetaImageReader.h" #include "vtkImageData.h" #include "vtkViewImage3D.h" #include "vtkRenderWindowInteractor.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cout << "Usage: imageview2d(.exe)" << std::endl; std::cout << "1- file.mha" << std::endl; std::cout << "2- Test (boolean)" << std::endl; return EXIT_FAILURE; } vtkMetaImageReader *reader = vtkMetaImageReader::New(); reader->SetFileName(argv[1]); reader->Update(); vtkViewImage3D *view = vtkViewImage3D::New(); vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); view->SetupInteractor(iren); view->SetTriPlanarRenderingOn(); view->SetInput( reader->GetOutput() ); view->Render(); if ( atoi(argv[2]) == 1 ) { iren->CreateOneShotTimer(1); } else { iren->Start(); } view->Delete(); iren->Delete(); reader->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/ExternalCode/MegaVTK/CMakeLists.txt0000644000175000017500000000157411667757442023534 0ustar mathieumathieuSET( MEGAVTK_EXAMPLE_SRC imageview2d imageview3d imageviewcollection vtkviewimage3dtest SeedWidget ) FOREACH( var ${MEGAVTK_EXAMPLE_SRC} ) ADD_EXECUTABLE( ${var} ${var}.cxx ) TARGET_LINK_LIBRARIES( ${var} vtkRenderingAddOn2 ) ENDFOREACH( var ${MEGAVTK_EXAMPLE_SRC} ) ADD_TEST( imageview2dTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/imageview2d ${TESTING_DATA_PATH}/Circle.png 1 ) ADD_TEST( imageview3dTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/imageview3d ${TESTING_DATA_PATH}/Circle3D.mhd 1 ) ADD_TEST( vtkviewimage3dtest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vtkviewimage3dtest ${TESTING_DATA_PATH}/Circle3D.mhd 1 ) ADD_TEST( imageviewcollectionTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/imageviewcollection ${TESTING_DATA_PATH}/Circle3D.mhd 1 ) ADD_TEST( SeedWidgetTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/SeedWidget ${TESTING_DATA_PATH}/Circle3D.mhd 1 ) GoFigure2-v0.9.0/Examples/ExternalCode/MegaVTK/SeedWidget.cxx0000644000175000017500000001355411667757442023545 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkMetaImageReader.h" #include "vtkImageActor.h" #include "vtkRenderWindowInteractor.h" #include "vtkViewImage2D.h" #include "vtkViewImage3D.h" #include "vtkViewImage2DCollection.h" #include "vtkConstrainedPointHandleRepresentation.h" #include "vtkSeedWidget.h" #include "vtkSeedRepresentation.h" #include "vtkProperty.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cout << "Usage: imageview3d(.exe)" << std::endl; std::cout << "1- filename (.mha or .mhd)" << std::endl; std::cout << "2- Test (boolean)" << std::endl; return EXIT_FAILURE; } vtkMetaImageReader *reader = vtkMetaImageReader::New(); reader->SetFileName(argv[1]); reader->Update(); vtkImageData *image = reader->GetOutput(); vtkViewImage2DCollection *pool = vtkViewImage2DCollection::New(); vtkViewImage3D * view3d = vtkViewImage3D::New(); vtkRenderWindowInteractor *iren3d = vtkRenderWindowInteractor::New(); view3d->SetupInteractor(iren3d); vtkViewImage2D * view = vtkViewImage2D::New(); vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); view->SetupInteractor(iren); view->SetInput (image); view->SetViewOrientation (vtkViewImage2D::VIEW_ORIENTATION_AXIAL); view3d->Add2DPhantom( 0, view->GetImageActor(), view->GetSlicePlane() ); pool->AddItem(view); vtkViewImage2D * view2 = vtkViewImage2D::New(); vtkRenderWindowInteractor *iren2 = vtkRenderWindowInteractor::New(); view2->SetupInteractor(iren2); view2->SetInput (image); view2->SetViewOrientation (vtkViewImage2D::VIEW_ORIENTATION_CORONAL); view3d->Add2DPhantom( 1, view2->GetImageActor(), view2->GetSlicePlane() ); pool->AddItem(view2); vtkViewImage2D * view3 = vtkViewImage2D::New(); vtkRenderWindowInteractor *iren3 = vtkRenderWindowInteractor::New(); view3->SetupInteractor(iren3); view3->SetInput (image); view3->SetViewOrientation (vtkViewImage2D::VIEW_ORIENTATION_SAGITTAL); view3d->Add2DPhantom( 2, view3->GetImageActor(), view3->GetSlicePlane() ); pool->AddItem(view3); view3d->SetTriPlanarRenderingOn(); view3d->SetInput(image); pool->SetExtraRenderWindow( view3d->GetRenderWindow() ); pool->InitializeAllObservers(); pool->Initialize(); pool->SyncSetBackground( pool->GetItem(0)->GetBackground() ); pool->SyncSetShowAnnotations(true); int size[2] = { 400, 400 }; pool->SyncSetSize(size); pool->SyncPan(); pool->SyncRender(); pool->SyncReset(); std::vector< vtkSeedWidget * > SeedWidget; std::vector< vtkConstrainedPointHandleRepresentation * > Handle; std::vector< vtkSeedRepresentation * > SeedRep; // Enable seed interaction Handle.resize( pool->GetNumberOfItems() ); SeedRep.resize( pool->GetNumberOfItems() ); SeedWidget.resize( pool->GetNumberOfItems() ); for ( int i = 0; i < pool->GetNumberOfItems(); i++ ) { Handle[i] = vtkConstrainedPointHandleRepresentation::New(); Handle[i]->GetProperty()->SetColor(1, 0, 0); SeedRep[i] = vtkSeedRepresentation::New(); SeedRep[i]->SetHandleRepresentation(Handle[i]); SeedWidget[i] = vtkSeedWidget::New(); SeedWidget[i]->SetPriority(10.0); SeedWidget[i]->SetRepresentation(SeedRep[i]); } Handle[0]->SetProjectionNormal(vtkViewImage2D::VIEW_ORIENTATION_AXIAL); Handle[1]->SetProjectionNormal(vtkViewImage2D::VIEW_ORIENTATION_CORONAL); Handle[2]->SetProjectionNormal(vtkViewImage2D::VIEW_ORIENTATION_SAGITTAL); SeedWidget[0]->SetInteractor(iren); SeedWidget[1]->SetInteractor(iren2); SeedWidget[2]->SetInteractor(iren3); for ( int i = 0; i < pool->GetNumberOfItems(); i++ ) { SeedWidget[i]->On(); } if ( atoi(argv[2]) == 1 ) { iren3d->CreateOneShotTimer(1); } else { iren3d->Start(); } for ( int i = 0; i < pool->GetNumberOfItems(); i++ ) { Handle[i]->Delete(); SeedRep[i]->Delete(); SeedWidget[i]->Delete(); } iren->Delete(); view->Delete(); iren2->Delete(); view2->Delete(); iren3->Delete(); view3->Delete(); pool->Delete(); iren3d->Delete(); view3d->Delete(); reader->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/ExternalCode/MegaVTK/imageview3d.cxx0000644000175000017500000000754511667757442023730 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkMetaImageReader.h" #include "vtkImageActor.h" #include "vtkRenderWindowInteractor.h" #include "vtkViewImage2D.h" #include "vtkViewImage3D.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cout << "Usage: imageview3d(.exe)" << std::endl; std::cout << "1- filename (.mha or .mhd)" << std::endl; std::cout << "2- Test (boolean)" << std::endl; return EXIT_FAILURE; } vtkMetaImageReader *reader = vtkMetaImageReader::New(); reader->SetFileName(argv[1]); reader->Update(); vtkImageData *image = reader->GetOutput(); vtkViewImage2D * view = vtkViewImage2D::New(); vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); view->SetupInteractor(iren); view->SetInput (image); view->SetViewOrientation (vtkViewImage2D::VIEW_ORIENTATION_AXIAL); view->Render(); vtkViewImage2D * view2 = vtkViewImage2D::New(); vtkRenderWindowInteractor *iren2 = vtkRenderWindowInteractor::New(); view2->SetupInteractor(iren2); view2->SetInput (image); view2->SetViewOrientation (vtkViewImage2D::VIEW_ORIENTATION_CORONAL); view2->Render(); vtkViewImage2D * view3 = vtkViewImage2D::New(); vtkRenderWindowInteractor *iren3 = vtkRenderWindowInteractor::New(); view3->SetupInteractor(iren3); view3->SetInput (image); view3->SetViewOrientation (vtkViewImage2D::VIEW_ORIENTATION_SAGITTAL); view3->Render(); vtkViewImage3D * view3d = vtkViewImage3D::New(); vtkRenderWindowInteractor *iren3d = vtkRenderWindowInteractor::New(); view3d->SetupInteractor(iren3d); view3d->Add2DPhantom( 0, view->GetImageActor() ); view3d->Add2DPhantom( 1, view2->GetImageActor() ); view3d->Add2DPhantom( 2, view3->GetImageActor() ); view3d->SetTriPlanarRenderingOn(); view3d->SetInput(image); view3d->Render(); if ( atoi(argv[2]) == 1 ) { iren3d->CreateOneShotTimer(1); } else { iren3d->Start(); } iren3->Delete(); iren2->Delete(); iren->Delete(); iren3d->Delete(); view3->Delete(); view2->Delete(); view->Delete(); view3d->Delete(); reader->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/ExternalCode/MegaVTK/imageviewcollection.cxx0000644000175000017500000001057611667757442025553 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkMetaImageReader.h" #include "vtkImageActor.h" #include "vtkRenderWindowInteractor.h" #include "vtkViewImage2D.h" #include "vtkViewImage3D.h" #include "vtkViewImage2DCollection.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cout << "Usage: imageview3d(.exe)" << std::endl; std::cout << "1- filename (.mha or .mhd)" << std::endl; std::cout << "2- Test (boolean)" << std::endl; return EXIT_FAILURE; } vtkMetaImageReader *reader = vtkMetaImageReader::New(); reader->SetFileName(argv[1]); reader->Update(); vtkImageData *image = reader->GetOutput(); vtkViewImage2DCollection *pool = vtkViewImage2DCollection::New(); vtkViewImage3D * view3d = vtkViewImage3D::New(); vtkRenderWindowInteractor *iren3d = vtkRenderWindowInteractor::New(); view3d->SetupInteractor(iren3d); vtkViewImage2D * view = vtkViewImage2D::New(); vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); view->SetupInteractor(iren); view->SetInput (image); view->SetViewOrientation (vtkViewImage2D::VIEW_ORIENTATION_AXIAL); view3d->Add2DPhantom( 0, view->GetImageActor(), view->GetSlicePlane() ); pool->AddItem(view); vtkViewImage2D * view2 = vtkViewImage2D::New(); vtkRenderWindowInteractor *iren2 = vtkRenderWindowInteractor::New(); view2->SetupInteractor(iren2); view2->SetInput (image); view2->SetViewOrientation (vtkViewImage2D::VIEW_ORIENTATION_CORONAL); view3d->Add2DPhantom( 1, view2->GetImageActor(), view2->GetSlicePlane() ); pool->AddItem(view2); vtkViewImage2D * view3 = vtkViewImage2D::New(); vtkRenderWindowInteractor *iren3 = vtkRenderWindowInteractor::New(); view3->SetupInteractor(iren3); view3->SetInput (image); view3->SetViewOrientation (vtkViewImage2D::VIEW_ORIENTATION_SAGITTAL); view3d->Add2DPhantom( 2, view3->GetImageActor(), view3->GetSlicePlane() ); pool->AddItem(view3); view3d->SetTriPlanarRenderingOn(); view3d->SetInput(image); pool->SetExtraRenderWindow( view3d->GetRenderWindow() ); pool->InitializeAllObservers(); pool->Initialize(); pool->SyncSetBackground( pool->GetItem(0)->GetBackground() ); pool->SyncSetShowAnnotations(true); int size[2] = { 400, 400 }; pool->SyncSetSize(size); pool->SyncPan(); pool->SyncRender(); pool->SyncReset(); if ( atoi(argv[2]) == 1 ) { iren3d->CreateOneShotTimer(1); } else { iren3d->Start(); } iren->Delete(); view->Delete(); iren2->Delete(); view2->Delete(); iren3->Delete(); view3->Delete(); pool->Delete(); iren3d->Delete(); view3d->Delete(); reader->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/ExternalCode/MegaVTK/imageview2d.cxx0000644000175000017500000000717011667757442023721 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "vtkPNGReader.h" #include "vtkImageData.h" #include "vtkViewImage2D.h" #include "vtkRenderWindowInteractor.h" #include "vtkInteractorStyleImage2D.h" int main(int argc, char **argv) { if ( argc != 3 ) { std::cout << "Usage: imageview2d(.exe)" << std::endl; std::cout << "1- file.png" << std::endl; std::cout << "2- Test (boolean)" << std::endl; return EXIT_FAILURE; } vtkPNGReader *reader = vtkPNGReader::New(); reader->SetFileName(argv[1]); reader->Update(); vtkViewImage2D *view = vtkViewImage2D::New(); vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); view->SetupInteractor(iren); vtkInteractorStyleImage2D *interactorStyle = vtkInteractorStyleImage2D::New(); iren->SetInteractorStyle(interactorStyle); // Studpid tests with interactor style interactorStyle->OnMouseMove(); interactorStyle->OnLeftButtonDown(); interactorStyle->OnLeftButtonUp(); interactorStyle->OnMiddleButtonDown(); interactorStyle->OnMiddleButtonUp(); interactorStyle->OnRightButtonDown(); interactorStyle->OnRightButtonUp(); interactorStyle->OnMouseWheelForward(); interactorStyle->OnMouseWheelBackward(); //interactorStyle->OnChar(); //interactorStyle->OnKeyUp(); interactorStyle->SliceMove(); interactorStyle->OnKeyPress(); interactorStyle->OnKeyRelease(); interactorStyle->StartSliceMove(); interactorStyle->EndSliceMove(); interactorStyle->SliceMove(); interactorStyle->GetCurrentProp(); // Generates error on Mac //interactorStyle->HighlightCurrentActor(); view->SetInput( reader->GetOutput() ); view->SetViewOrientation (vtkViewImage2D::VIEW_ORIENTATION_AXIAL); view->Render(); if ( atoi(argv[2]) == 1 ) { iren->CreateOneShotTimer(1); } else { iren->Start(); } interactorStyle->Delete(); view->Delete(); iren->Delete(); reader->Delete(); return EXIT_SUCCESS; }GoFigure2-v0.9.0/Examples/ExternalCode/CMakeLists.txt0000644000175000017500000000006311667757442022266 0ustar mathieumathieuADD_SUBDIRECTORY( MegaVTK ) ADD_SUBDIRECTORY( ctk )GoFigure2-v0.9.0/Examples/ExternalCode/ctk/0000755000175000017500000000000011667757442020310 5ustar mathieumathieuGoFigure2-v0.9.0/Examples/ExternalCode/ctk/ctkCollapsibleGroupBoxTest.cxx0000644000175000017500000000517611667757442026326 0ustar mathieumathieu/*========================================================================= Library: CTK Copyright (c) Kitware Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.commontk.org/LICENSE Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =========================================================================*/ // Qt includes #include #include #include #include // CTK includes #include "ctkCollapsibleGroupBox.h" // STD includes #include #include //----------------------------------------------------------------------------- int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget topLevel; ctkCollapsibleGroupBox *groupBox = new ctkCollapsibleGroupBox( QObject::tr("GroupBox") ); QRadioButton * radio1 = new QRadioButton( QObject::tr("&Radio button 1") ); QRadioButton * radio2 = new QRadioButton( QObject::tr("R&adio button 2") ); QRadioButton * radio3 = new QRadioButton( QObject::tr("Ra&dio button 3") ); radio1->setChecked(true); QHBoxLayout *vbox = new QHBoxLayout; vbox->addWidget(radio1); vbox->addWidget(radio2); vbox->addWidget(radio3); groupBox->setLayout(vbox); QHBoxLayout *topLevelVBox = new QHBoxLayout; topLevelVBox->addWidget(groupBox); topLevelVBox->setSizeConstraint(QLayout::SetFixedSize); topLevel.setLayout(topLevelVBox); topLevel.show(); if ( groupBox->collapsed() ) { std::cerr << "Wrong default collapse state." << std::endl; return EXIT_FAILURE; } groupBox->setCollapsed(true); if ( groupBox->collapsed() != true ) { std::cerr << "ctkCollapsibleGroupBox::setCollapsed failed." << std::endl; return EXIT_FAILURE; } if ( radio1->isVisible() ) { std::cerr << "ctkCollapsibleGroupBox::setChecked failed. " << "Children are visible" << std::endl; return EXIT_FAILURE; } groupBox->setChecked(true); if ( groupBox->collapsed() != false ) { std::cerr << "ctkCollapsibleGroupBox::setChecked failed." << std::endl; return EXIT_FAILURE; } if ( argc < 2 || QString(argv[1]) == "1" ) { QTimer::singleShot( 200, &app, SLOT( quit() ) ); } return app.exec(); }GoFigure2-v0.9.0/Examples/ExternalCode/ctk/CMakeLists.txt0000644000175000017500000000064311667757442023053 0ustar mathieumathieuSET( CTK_EXAMPLE_SRC ctkDoubleSlider ctkCollapsibleGroupBoxTest ) FOREACH( var ${CTK_EXAMPLE_SRC} ) ADD_EXECUTABLE( ${var} ${var}.cxx ) TARGET_LINK_LIBRARIES( ${var} ctk ) ENDFOREACH( var ${CTK_EXAMPLE_SRC} ) ADD_TEST( ctkDoubleSliderTest1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ctkDoubleSlider 1 ) ADD_TEST( ctkCollapsibleGroupBoxTest1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ctkCollapsibleGroupBoxTest 1 ) GoFigure2-v0.9.0/Examples/ExternalCode/ctk/ctkDoubleSlider.cxx0000644000175000017500000000525511667757442024122 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009 Copyright (c) 2009, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include "ctkDoubleRangeSlider.h" int main(int argc, char *argv[]) { if ( argc != 2 ) { std::cout << "Usage : ./ctkDoubleSliderTest " << std::endl; std::cout << "1-test (boolean)" << std::endl; return EXIT_FAILURE; } QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); ctkDoubleRangeSlider *rangeSlider = new ctkDoubleRangeSlider(NULL); rangeSlider->show(); QTimer *timer = new QTimer; timer->setSingleShot(true); QObject::connect( timer, SIGNAL( timeout() ), rangeSlider, SLOT( close() ) ); if ( atoi(argv[1]) == 1 ) { timer->start(1000); } rangeSlider->show(); app.processEvents(); int output = app.exec(); app.closeAllWindows(); delete rangeSlider; delete timer; return output; }GoFigure2-v0.9.0/Main/0000755000175000017500000000000011667757442014260 5ustar mathieumathieuGoFigure2-v0.9.0/Main/QGoSynchronizedViewMainWindow.h0000644000175000017500000001314411667757442022352 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoSynchronizedViewMainWindow_h #define __QGoSynchronizedViewMainWindow_h #include #include #include "itkImage.h" #include "itkSmartPointer.h" #include "QGoSynchronizedViewManager.h" class QGoSynchronizedView; class QGoSynchronizedView3D; class vtkImageData; QT_BEGIN_NAMESPACE class QAction; class QMenu; class QMdiArea; class QMdiSubWindow; class QSignalMapper; QT_END_NAMESPACE /** * \class QGoSynchronizedViewMainWindow * \brief This object is intended to demonstrate the use of the * comparer classes package : * QGoSynchronizedViewManager * QGoSynchronizedView * QGoSynchronizedView2D * QGoSynchronizedView3D * QGoSynchronizedView3DCallbacks * QGoSynchronizedView2DCallbacks * It is not documented. * It is used by the example program : qgosynchronizedviewguitest.cxx */ // \example GUI/lib/qgosynchronizedviewguitest.cxx class QGoSynchronizedViewMainWindow:public QMainWindow { // QT macro Q_OBJECT public: QGoSynchronizedViewMainWindow(); ~QGoSynchronizedViewMainWindow(); QGoSynchronizedViewManager * GetSynchronizedViewManager(); void Update(); QGoSynchronizedView * newSynchronizedView( QString iSynchronizedViewName, vtkImageData *iImage); template< typename TPixel > QGoSynchronizedView * newSynchronizedView( QString iSynchronizedViewName, typename itk::Image< TPixel, 3 >::Pointer iImage) { QGoSynchronizedView *synchronizedView; synchronizedView = m_SynchronizedViewManager->newSynchronizedView< TPixel >( iSynchronizedViewName, iImage); mdiArea->addSubWindow(synchronizedView, Qt::SubWindow); synchronizedView->parentWidget() ->resize(300, 300); synchronizedView->show(); tileAct->trigger(); return synchronizedView; } template< typename TPixel > QGoSynchronizedView * newSynchronizedView( QString iSynchronizedViewName, typename itk::Image< TPixel, 2 >::Pointer iImage) { QGoSynchronizedView *synchronizedView; synchronizedView = m_SynchronizedViewManager->newSynchronizedView< TPixel >( iSynchronizedViewName, iImage); mdiArea->addSubWindow(synchronizedView, Qt::SubWindow); synchronizedView->parentWidget() ->resize(300, 300); synchronizedView->show(); tileAct->trigger(); return synchronizedView; } void OpenSynchronizedViewForFile(QString & iFile); void deleteSynchronizedView2D(const int & iId); void deleteSynchronizedView3D(const int & iId); protected: void closeEvent(QCloseEvent *event); private slots: void openfile(); void snapshotAs(); void about(); void aboutGF2(); void updateMenus(); void updateWindowMenu(); void setActiveSubWindow(QWidget *window); void synchronize(); void FullscreenXY(); void FullscreenXZ(); void FullscreenYZ(); void FullscreenXYZ(); void Quadscreen(); private: void SaveSnapshotInFile(QString & iFile, QGoSynchronizedView *SynchronizedView); void createActions(); void createMenus(); void createToolBars(); void createStatusBar(); void readSettings(); void writeSettings(); void imageinfo(); QGoSynchronizedView * activeSynchronizedView(); QMdiSubWindow * findSynchronizedView(const QString & iSynchronizedViewName); QMdiArea * mdiArea; QSignalMapper *windowMapper; QMenu *fileMenu; QMenu *editMenu; QMenu *windowMenu; QMenu *helpMenu; QToolBar *ToolBar; QToolBar *View3DToolBar; QAction * syncAct; QAction * openfileAct; // QAction * openmemAct; QAction *snapshotAsAct; QAction *exitAct; QAction *closeAct; QAction *closeAllAct; QAction *tileAct; QAction *cascadeAct; QAction *aboutAct; QAction *aboutQtAct; QAction *aboutGF2Act; QAction *XYviewAct; QAction *XZviewAct; QAction *YZviewAct; QAction *XYZviewAct; QAction *QuadviewAct; QGoSynchronizedViewManager *m_SynchronizedViewManager; }; #endif // QGOSYNCHRONIZEDVIEWMAINWINDOW_H GoFigure2-v0.9.0/Main/QGoPluginManager.h0000644000175000017500000000504511667757442017575 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoPluginManager_h #define __QGoPluginManager_h class QGoMainWindow; class QMenu; class QGoPlugin; #include /** \class QGoPluginManager \brief */ class QGoPluginManager:public QObject { Q_OBJECT public: QGoPluginManager(/*QGoMainWindow**/); virtual ~QGoPluginManager(); bool IsPluginAlreadyLoaded(const QString & iName); void LoadPlugin(const QString &); void LoadPlugins(); void ApplySettings(); /** \brief Returns list of menus */ std::list< QMenu * > GetMenus(); public slots: virtual void NotifyTabActivated(const int &); virtual void NotifyTabClosed(const int &); virtual void NotifyTabMoved(const int &, const int &); protected: std::list< QGoPlugin * > m_PluginList; private: Q_DISABLE_COPY(QGoPluginManager); }; #endif GoFigure2-v0.9.0/Main/QGoMainWindow.h0000644000175000017500000002220411667757442017114 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoMainWindow_h #define __QGoMainWindow_h #include #include // #include "itkImage.h" // #include "itkImageToVTKImageFilter.h" #include "itkQtProgressBar.h" #include "itkQtAdaptor.h" #include "GoFigureFileInfoMultiIndexContainerHelper.h" #include "GoFigureGlobalDefinition.h" #include "QGoAboutWidget.h" #include "QGoDBInitializationWizard.h" #include "QGoTabImageView3DwT.h" class vtkImageData; class vtkLSMReader; class QGoWizardDB; class QGoTabManager; class QGoTabImageView3D; class QGoTabImageView2D; class QGoTabElementBase; class QGoNetworkUtilities; #include "ui_go.h" /** * \class QGoMainWindow * \brief GoFigure2's main window * \image html QGoMainWindow.png * */ class QGoMainWindow:public QMainWindow, private Ui::go_mainwindow { Q_OBJECT public: friend class QGoTabManager; // typedef itk::Image< unsigned char, 3 > ImageType; // typedef itk::ImageToVTKImageFilter< ImageType > VTKConvertImageType; // typedef VTKConvertImageType::Pointer VTKConvertImagePointer; // typedef itk::MultiFileReader::FILETYPE FILETYPE; explicit QGoMainWindow(QWidget *iParent = 0, Qt::WindowFlags iFlags = 0); ~QGoMainWindow(); void SetSingleFileName(const QString & iFileName); void SetMaxNumberOfTraces( unsigned int iN ); private slots: void on_actionOpen_Single_File_triggered(); void openRecentSingleFile(); // void on_actionOpen_Multiple_Files_triggered( ); void on_actionOpen_MegaCapture_Files_triggered(); void openRecentMultipleFile(); void openRecentDatabaseFile(); void openRecentFilesfromDB(); void on_actionGoFigure2_Website_triggered(); void on_actionReport_a_bug_triggered(); void on_actionUser_mailing_list_triggered(); void on_actionDeveloper_mailing_list_triggered(); void on_actionUse_DataBase_triggered(); void openFilesfromDB(); /** * \brief Open dialog window to set the file output path and format */ void on_actionExport_LSM_to_MegaFile_triggered(); void on_actionClose_triggered(); void on_actionClose_all_triggered(); void on_actionQuit_triggered(); void on_actionAbout_triggered(); void on_actionAbout_Qt_triggered(); void SetUpDatabase(); void on_actionCheck_For_Updates_triggered(); void DisplayUpdateResults(QString result, bool noerror); void ApplyImageFilter(); void tobedone(std::vector< vtkImageData * > ); /** \brief remove the action 'Set up Database' from the Database menu. */ void RemoveSetUpDatabaseMenu(); /** \brief add the action 'Set up Database' to the Database menu if it doesn't have been already added. */ void AddSetUpDatabaseMenu(); private: std::map< GoFigure::TabDimensionType, std::list< QAction * > > m_TabDimPluginActionMap; /** \brief */ void openRecentFile(const bool & IsSerie); void DisplayFilesfromDB(std::string iFirst_Filename); /** \brief */ void SetCurrentSingleFile(const QString & fileName); void SetCurrentMultiFile(const QString & fileName); void SetCurrentDatabaseFile(const QString & fileName); /** \brief */ enum { MaxRecentFiles = 5 }; QAction *recentSingleFileActions[MaxRecentFiles]; QAction *recentMultipleFileActions[MaxRecentFiles]; QAction *recentDatabaseFileActions[MaxRecentFiles]; void UpdateRecentFileActions(QStringList list, QMenu * menu, QAction * recentFileActions[MaxRecentFiles]); /** * \brief Create a new tab in the TabWidget for a 3DwT image from one megacapture * (from the database, or from the filesystem directly). * \param[in] iFileList Megacapture files Container * \param[in] iFileType Type of images * \param[in] iHeader Megacapture header (*.meg) * \param[in] iTimePoint Time point to show * \param[in] iUseDatabase Use the database */ QGoTabImageView3DwT * CreateNewTabFor3DwtImage( const GoFigureFileInfoHelperMultiIndexContainer & iFileList, const GoFigure::FileType & iFileType, const std::string & iHeader, const int & iTimePoint, const bool & iUseDatabase); /** * \brief Create a new tab in the TabWidget for a 3DwT LSM file. * \param[in] iReader the vtkLSMReader to be duplicated * \param[in] iFile filename */ QGoTabImageView3DwT * CreateNewTabFor3DwtImage( vtkLSMReader *iReader, const QString & iFile); QGoTabImageView3D * CreateNewTabFor3DImage(vtkImageData *, const QString &); QGoTabImageView2D * CreateNewTabFor2DImage(vtkImageData *, const QString &); /* \brief Open Image with given iFileName \param[in] iFileName */ // void OpenImageWithITK( const QString& iFileName ); /** \brief Open LSM image * \param[in] iFile filename * \param[in] iTimePoint time point * */ void OpenLSMImage(const QString & iFile, const int & iTimePoint); void SetupPluginsAndDockWidgetFromTab(QGoTabElementBase *iT); void SetUpGeneralMenusToolBars(QGoTabElementBase *iT); void SetUpMenusToolBarsFor3dwtImage(QGoTabImageView3DwT* iT); /** \brief get the file container and the header filename for one file * part of a megacapture imaging session * \param[in,out] ioHeader_Filename detected *.meg file * \param[in] iFirstFileName one file part of a megacapture imaging session * \return multi index container with all file names * */ GoFigureFileInfoHelperMultiIndexContainer GetFileContainerForMultiFiles( std::string & ioHeader_Filename, std::string iFirstFileName); /** * */ void LoadAllTracesFromDatabaseManager(const int & iT); /** * */ //void LoadAllTracesFromDatabase(const int & iT, const std::string & iTrace); void LoadContoursFromDatabase(const int & iT ); void LoadMeshesFromDatabase(const int & iT); void LoadTracksFromDatabase(const int & iT); /** * \brief Compute GoFigure file type from a given filename * \param[in] iFileName filename * \param[out] oFileType file type * \return true if (png, jpeg or tiff) * \return false else */ bool ComputeFileType(const QString & iFileName, GoFigure::FileType & oFileType); void LoadPlugins(); void PopulateMenus(QObject *plugin); void AddToMenu(QObject *, const QStringList &, QMenu *, const char *, QActionGroup *); QMenu * m_FilteringMenu; QDir m_PluginsDir; QStringList m_PluginFileNames; QGoTabManager * m_TabManager; QToolBar * m_ViewToolBar; QToolBar * m_ModeToolBar; QToolBar * m_TracesToolBar; QToolBar * m_TraceSettingsToolBar; std::list< vtkLSMReader * > m_LSMReader; QGoWizardDB * m_DBWizard; QGoAboutWidget * m_AboutWidget; QGoDBInitializationWizard * m_DBInitializationWizard; QGoNetworkUtilities *m_NetworkUtilities; bool m_ManualUpdate; /** \brief */ void ReadSettings(); /** \brief */ void WriteSettings(); void CreateSignalSlotsConnection(); /** \brief */ itk::QtSignalAdaptor m_SignalAdaptor; itk::QtProgressBar m_Bar; /** \brief list of recent files */ QStringList m_RecentSingleFiles; QStringList m_RecentMultipleFiles; QStringList m_RecentDatabaseFiles; bool m_DatabaseSetUp; QAction * actionSet_Up_Database; /** \brief current file name */ QString m_CurrentFile; /** \brief Remove path from a given FileName*/ QString strippedName(const QString & fullFileName); private: unsigned int m_MaxNumberOfTraces; Q_DISABLE_COPY(QGoMainWindow); }; #endif GoFigure2-v0.9.0/Main/gofigure.cxx.in0000644000175000017500000001565211667757442017231 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include #include #include #include #include #include "boost/program_options.hpp" #include "QGoMainWindow.h" int main(int argc, char **argv) { QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain( "http://gofigure2.sourceforge.net"); QCoreApplication::setApplicationName("GoFigure2"); boost::program_options::options_description general_options( "Generic Options" ); general_options.add_options() ("help,h", "Display this information") ("version,v", "Display GoFigure2 version information" ) ("shortcuts", "Display all shortcuts"); boost::program_options::options_description config_options( "Configuration" ); config_options.add_options() ("input,i", boost::program_options::value< std::vector< std::string > >(), "input file (single file)" ) ("max-meshes", boost::program_options::value< unsigned int >(), "Maximum number of meshes to load in memory (default 5000)" ); boost::program_options::options_description all_options( "Usage:\n gofigure [options]" ); all_options.add( general_options ).add( config_options ); boost::program_options::variables_map vm; boost::program_options::store( boost::program_options::parse_command_line( argc, argv, all_options ), vm ); boost::program_options::notify( vm ); if( vm.count( "help" ) ) { std::cout << all_options << "\n"; return EXIT_SUCCESS; } if( vm.count( "version" ) ) { std::cout << "GoFigure2-v@GOFIGURE2_VERSION@" << std::endl; return EXIT_SUCCESS; } if( vm.count( "shortcuts" ) ) { std::cout << std::endl; // ----------------------------------------------------- std::cout << "GoFigure2 Shortcuts" << std::endl; std::cout << "*******************" << std::endl; std::cout << "CTRL+O : Open one image" << std::endl; std::cout << "CTRL+W : Close active tab" << std::endl; std::cout << "CTRL+Q : Quit" << std::endl; std::cout << std::endl; // ----------------------------------------------------- std::cout << "Navigation" <show(); app.processEvents(); splash->showMessage("Application loading... please wait"); QGoMainWindow *form = new QGoMainWindow; QString inputfilename; if( vm.count( "input" ) ) { std::vector< std::string > temp_filename =vm["input"].as< std::vector< std::string > >(); for( std::vector< std::string >::const_iterator it = temp_filename.begin(); it != temp_filename.end(); ++it ) { inputfilename = QString::fromStdString( *it ); if ( ( !inputfilename.isEmpty() ) && ( !inputfilename.isNull() ) ) { form->SetSingleFileName(inputfilename); } } } if( vm.count( "max-meshes" ) ) { unsigned int max_number_of_meshes = vm["max-meshes"].as< unsigned int >(); form->SetMaxNumberOfTraces( max_number_of_meshes ); } form->show(); splash->showMessage("Application ready"); app.processEvents(); splash->finish(form); int output; try { output = app.exec(); } catch( const std::bad_alloc & ) { // clean up here, e.g. save the session // and close all config files. // exit output = 0; } delete splash; delete form; return output; } GoFigure2-v0.9.0/Main/QGoPluginManager.cxx0000644000175000017500000001412511667757442020147 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoPluginManager.h" #include #include #include #include #include #include #include #include #include #include "QGoPlugin.h" #include "QGoPluginHelper.h" // #include "QGoMainWindow.h" // class QGoPluginManager::Interior // { // public: // Interior() {} // ~Interior() {} // // /** \todo check later on if it is already loaded. */ // bool AddPlugin( QGoPlugin* plugin ) // { // if( plugin ) // { // m_Plugins.push_back( plugin ); // return true; // } // else // { // return false; // } // } // // std::list< QGoPlugin* > m_Plugins; // }; QGoPluginManager::QGoPluginManager() : QObject() { // m_InternalManager = new Interior(); } QGoPluginManager::~QGoPluginManager() { // delete m_InternalManager; } //-------------------------------------------------------------------------- // Tab events to be handled by plugins //-------------------------------------------------------------------------- void QGoPluginManager::NotifyTabActivated(const int & iId) { for ( std::list< QGoPlugin * >::iterator it = m_PluginList.begin(); it != m_PluginList.end(); ++it ) { if ( ( *it ) ) { ( *it )->OnTabActivated(iId); } } } void QGoPluginManager::NotifyTabClosed(const int & iId) { for ( std::list< QGoPlugin * >::iterator it = m_PluginList.begin(); it != m_PluginList.end(); ++it ) { if ( ( *it ) ) { ( *it )->OnTabClosed(iId); } } } void QGoPluginManager::NotifyTabMoved(const int & from, const int & to) { for ( std::list< QGoPlugin * >::iterator it = m_PluginList.begin(); it != m_PluginList.end(); ++it ) { if ( ( *it ) ) { ( *it )->OnTabMoved(from, to); } } } //-------------------------------------------------------------------------- bool QGoPluginManager::IsPluginAlreadyLoaded(const QString & iName) { for ( std::list< QGoPlugin * >::iterator it = m_PluginList.begin(); it != m_PluginList.end(); ++it ) { if ( ( *it ) ) { if ( ( *it )->Name() == iName ) { return true; } } } return false; } void QGoPluginManager::LoadPlugin(const QString & path) { QPluginLoader loader(path); if ( !loader.load() ) { std::cout << "Plugin was not loaded" << std::endl; return; } QObject *obj = loader.instance(); if ( obj ) { QGoPlugin *plugin = qobject_cast< QGoPlugin * >(obj); if ( plugin ) { // Check if plugin with the same name was already loaded. // If is was then exit. if ( IsPluginAlreadyLoaded( plugin->Name() ) ) { return; } if ( plugin ) { m_PluginList.push_back(plugin); std::cout << "Plugin LOADED" << std::endl; } else { //note that for now this case can never happen! loader.unload(); } } else { std::cout << "Error while casting" << std::endl; } } else { std::cout << "Null plugin" << std::endl; } } void QGoPluginManager::LoadPlugins() { // global plugins QDir gPluginDir = FindPluginDirectory("plugins"); foreach ( QString fileName, gPluginDir.entryList(QDir::Files) ) { QString path = gPluginDir.absoluteFilePath(fileName); LoadPlugin(path); } // std::list< QDockWidget* >::iterator it // = m_InternalManager->m_Docks.begin(); // std::list< QDockWidget* >::iterator end // = m_InternalManager->m_Docks.end(); // // for( ; it != end; ++it ) // { // m_InternalManager->m_MainWindow->AddDockWidget( *it ); // } } void QGoPluginManager::ApplySettings() { std::list< QGoPlugin * >::iterator it = m_PluginList.begin(); std::list< QGoPlugin * >::iterator end = m_PluginList.end(); for (; it != end; ++it ) { ( *it )->ReadSettings(); } } std::list< QMenu * > QGoPluginManager::GetMenus() { std::list< QMenu * > oMenuList; std::list< QGoPlugin * >::iterator it = m_PluginList.begin(); std::list< QGoPlugin * >::iterator end = m_PluginList.end(); for (; it != end; ++it ) { if ( ( *it )->Menu() ) { oMenuList.push_back( ( *it )->Menu() ); } } return oMenuList; }GoFigure2-v0.9.0/Main/QGoTabManager.cxx0000644000175000017500000002767211667757442017432 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoTabManager.h" #include #include "QGoMainWindow.h" #include "QGoTabElementBase.h" //-------------------------------------------------------------------------- QGoTabManager::QGoTabManager(QGoMainWindow *iMW, QTabWidget *iTW) : m_MainWindow(iMW), m_TabWidget(iTW), m_PreviousTabIndex(-1) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoTabManager::~QGoTabManager() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabManager::SetMainWindow(QGoMainWindow *iMW) { m_MainWindow = iMW; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabManager::SetTabWidget(QTabWidget *iTW) { m_TabWidget = iTW; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabManager::ClearTabElement(QGoTabElementBase *iE) { if ( iE ) { // First remove all toolbar related to the previous tab m_MainWindow->m_ViewToolBar->clear(); //m_MainWindow->m_ModeToolBar->clear(); std::list ListToolBars = iE->GetToolBarsStatus(); std::list::iterator iter =ListToolBars .begin(); while (iter != ListToolBars.end()) { QGoToolBarStatus* ToolBar= *iter; ToolBar->ClearToolBar(); ++iter; } //this->m_MainWindow->m_TraceSettingsToolBar->toggleViewAction()->disconnect( // this->m_MainWindow->m_TraceSettingsToolBar->findChild("TraceSettingsWidget") ); //m_MainWindow->m_TraceSettingsToolBar->clear(); // Then remove all actions related to the previous tab from menuView m_MainWindow->menuView->clear(); // Then remove all actions from the segmentation menu m_MainWindow->menuSegmentation->clear(); // Then remove all actions from the tools menu m_MainWindow->menuTools->clear(); // Then remove all actions from the bookmark menu m_MainWindow->menuBookmarks->clear(); //then remove all actions from the mode menu: m_MainWindow->menuMode->clear(); std::list< QGoTabElementBase::QGoDockWidgetStatusPair > & dock_list = iE->DockWidget(); for ( std::list< QGoTabElementBase::QGoDockWidgetStatusPair >::iterator dck_it = dock_list.begin(); dck_it != dock_list.end(); ++dck_it ) { this->GetMainWindow(*dck_it)->removeDockWidget(dck_it->first->m_DockWidget); } GoFigure::TabDimensionType dim = iE->GetTabDimensionType(); std::map< GoFigure::TabDimensionType, std::list< QAction * > >::iterator map_it = m_MainWindow->m_TabDimPluginActionMap.find(dim); if ( map_it != m_MainWindow->m_TabDimPluginActionMap.end() ) { for ( std::list< QAction * >::iterator list_it = ( map_it->second ).begin(); list_it != ( map_it->second ).end(); ++list_it ) { ( *list_it )->setDisabled(true); } } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabManager::SetUpTabElement(QGoTabElementBase *iE) { if ( iE ) { // Then add all actions related to the new tab from menuView std::vector< QAction * > action_vector2 = iE->ViewActions(); for ( std::vector< QAction * >::iterator it = action_vector2.begin(); it != action_vector2.end(); ++it ) { m_MainWindow->menuView->addAction(*it); m_MainWindow->m_ViewToolBar->addAction(*it); } this->UpdateViewMenu(iE->ViewNoToolBarActions() ); /*action_vector2 = iE->ModeActions(); for ( std::vector< QAction * >::iterator it = action_vector2.begin(); it != action_vector2.end(); ++it ) { m_MainWindow->menuMode->addAction(*it); m_MainWindow->m_ModeToolBar->addAction(*it); }*/ action_vector2 = iE->SegmentationActions(); for ( std::vector< QAction * >::iterator it = action_vector2.begin(); it != action_vector2.end(); ++it ) { m_MainWindow->menuSegmentation->addAction(*it); } action_vector2 = iE->ToolsActions(); for ( std::vector< QAction * >::iterator it = action_vector2.begin(); it != action_vector2.end(); ++it ) { m_MainWindow->menuTools->addAction(*it); } action_vector2 = iE->BookmarkActions(); for ( std::vector< QAction * >::iterator it = action_vector2.begin(); it != action_vector2.end(); ++it ) { m_MainWindow->menuBookmarks->addAction(*it); } std::list ToolBarList = iE->GetToolBarsStatus(); std::list::iterator iter = ToolBarList.begin(); while (iter != ToolBarList.end() ) { QGoToolBarStatus* ToolBar = *iter; ToolBar->SetUpToolBar(); ++iter; } /*QAction* TraceSettingsAction = m_MainWindow->m_TraceSettingsToolBar->addWidget(iE->TraceSettingsWidget() ); TraceSettingsAction->setVisible(true); iE->SetTraceSettingsToolBar(m_MainWindow->m_TraceSettingsToolBar); m_MainWindow->m_TraceSettingsToolBar->setVisible( iE->TraceSettingsWidget()->GetIsToolBarVisible()); QObject::connect(this->m_MainWindow->m_TraceSettingsToolBar->toggleViewAction(), SIGNAL( toggled (bool) ), this->m_MainWindow->m_TraceSettingsToolBar->findChild("TraceSettingsWidget"), SLOT(SetVisibilityStatus(bool) ) );*/ std::list< QGoTabElementBase::QGoDockWidgetStatusPair > dock_list = iE->DockWidget(); for ( std::list< QGoTabElementBase::QGoDockWidgetStatusPair >::iterator dck_it = dock_list.begin(); dck_it != dock_list.end(); ++dck_it ) { if ( dck_it->first->m_Attached ) { if ( dck_it->first->m_Area == Qt::NoDockWidgetArea ) { dck_it->first->m_Area = dck_it->first->m_DefaultArea; } this->GetMainWindow(*dck_it)->addDockWidget(dck_it->first->m_Area, dck_it->second); } dck_it->second->setVisible(dck_it->first->m_Visibility); } GoFigure::TabDimensionType dim = iE->GetTabDimensionType(); if ( dim == GoFigure::THREE_D_WITH_T ) { ///\todo: Check if there is a connection with database to update // import/export in menu //std::cout << "Check if there is a connection with database to update // import/export in menu" << std::endl; } std::map< GoFigure::TabDimensionType, std::list< QAction * > >::iterator map_it = m_MainWindow->m_TabDimPluginActionMap.find(dim); if ( map_it != m_MainWindow->m_TabDimPluginActionMap.end() ) { for ( std::list< QAction * >::iterator list_it = ( map_it->second ).begin(); list_it != ( map_it->second ).end(); ++list_it ) { ( *list_it )->setEnabled(true); } } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabManager::ChangeCurrentTab(int iIdx) { if ( m_PreviousTabIndex != -1 ) { QGoTabElementBase *w = dynamic_cast< QGoTabElementBase * >( m_TabWidget->widget(m_PreviousTabIndex) ); ClearTabElement(w); } if ( iIdx != -1 ) { QGoTabElementBase *w2 = dynamic_cast< QGoTabElementBase * >( m_TabWidget->widget(iIdx) ); SetUpTabElement(w2); } m_PreviousTabIndex = iIdx; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabManager::UpdateBookmarkMenu(std::vector< QAction * > iBookmarkActions) { m_MainWindow->menuBookmarks->clear(); for ( std::vector< QAction * >::iterator it = iBookmarkActions.begin(); it != iBookmarkActions.end(); ++it ) { m_MainWindow->menuBookmarks->addAction(*it); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabManager::UpdateViewMenu(std::vector< QAction* > iViewNoToolBarActions) { for ( std::vector< QAction * >::iterator it = iViewNoToolBarActions.begin(); it != iViewNoToolBarActions.end(); ++it ) { m_MainWindow->menuView->addAction(*it); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabManager::CloseTab(int idx) { if ( idx >= 0 ) { QGoTabElementBase *w = dynamic_cast< QGoTabElementBase * >( m_TabWidget->widget(idx) ); if ( w ) { w->WriteSettings(); ClearTabElement(w); delete w; w = 0; } // m_TabWidget->removeTab( idx ); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoTabManager::CloseAllTabs() { int NumberOfTabs = m_TabWidget->count(); for ( int i = 0; i < NumberOfTabs; i++ ) { int k = NumberOfTabs - 1 - i; QGoTabElementBase *w = dynamic_cast< QGoTabElementBase * >( m_TabWidget->widget(k) ); if ( w ) { ClearTabElement(w); w->WriteSettings(); delete w; } } m_MainWindow->m_ViewToolBar->clear(); m_MainWindow->m_ModeToolBar->clear(); m_TabWidget->clear(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QMainWindow* QGoTabManager::GetMainWindow( QGoTabManager::QGoDockWidgetStatusPair iDockStatus) { if (iDockStatus.first->m_MainWindow != 0) { return iDockStatus.first->m_MainWindow; } else { return m_MainWindow; } }GoFigure2-v0.9.0/Main/CMakeLists.txt0000644000175000017500000002120711667757442017022 0ustar mathieumathieuCONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/gofigure.cxx.in ${CMAKE_CURRENT_BINARY_DIR}/gofigure.cxx @ONLY IMMEDIATE ) SET( QGoMainWindow_UI go.ui ) SET( QGoGUISRC_HDRS QGoTabManager.h QGoMainWindow.h QGoPluginManager.h ${QGoGUIINTERFACES_HDRS} ) SET( GOFIGURE_MAIN ${CMAKE_CURRENT_BINARY_DIR}/gofigure.cxx ) SET( GOFIGURE_APPLICATION_SOURCE_LIST QGoTabManager.cxx QGoMainWindow.cxx QGoPluginManager.cxx ) IF( BUILD_COMPARETOOL ) SET( QGoGUISRC_HDRS ${QGoGUISRC_HDRS} QGoSynchronizedViewMainWindow.h ) SET( GOFIGURE_APPLICATION_SOURCE_LIST ${GOFIGURE_APPLICATION_SOURCE_LIST} ${QGoSynchronizedViewMainWindow.cxx} ) ENDIF( BUILD_COMPARETOOL ) INCLUDE_DIRECTORIES( ${GOFIGURE2_BINARY_DIR}/Main/ ) QT4_WRAP_UI( QGoMainWindow_UI_H ${QGoMainWindow_UI} ) QT4_WRAP_CPP( QGoGUISRC_MOC ${QGoGUISRC_HDRS} ) SET_SOURCE_FILES_PROPERTIES( ${GOFIGURE_APPLICATION_SOURCE_LIST} PROPERTIES OBJECT_DEPENDS "${QGoMainWindow_UI_H}" ) SET_SOURCE_FILES_PROPERTIES( ${QGoGUISRC_MOC} PROPERTIES OBJECT_DEPENDS "${QGoMainWindow_UI_H}" ) QT4_ADD_RESOURCES( QGoMainWindow_QRC ${QGoResourceFile} ) SET( QGoGUISRC_SRC ${QGoGUISRC_CXX} ${QGoGUISRC_MOC} ) set( qt_menu_nib_sources ) IF( APPLE ) IF( QT_MAC_USE_COCOA ) GET_FILENAME_COMPONENT( qt_menu_nib "@QT_QTGUI_LIBRARY_RELEASE@/Resources/qt_menu.nib" REALPATH ) set( qt_menu_nib_sources "${qt_menu_nib}/classes.nib" "${qt_menu_nib}/info.nib" "${qt_menu_nib}/keyedobjects.nib" ) SET_SOURCE_FILES_PROPERTIES( ${qt_menu_nib_sources} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/qt_menu.nib ) ENDIF( QT_MAC_USE_COCOA ) SET( MACOSX_BUNDLE_ICON_FILE ${GOFIGURE2_SOURCE_DIR}/Resources/myapp.icns ) SET_SOURCE_FILES_PROPERTIES( ${MACOSX_BUNDLE_ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) SET( GOFIGURE_APPLICATION_SOURCE_LIST ${GOFIGURE_APPLICATION_SOURCE_LIST} ${MACOSX_BUNDLE_ICON_FILE} ) SET( MACOSX_BUNDLE_SHORT_VERSION_STRING ${GOFIGURE2_VERSION} ) SET( MACOSX_BUNDLE_VERSION ${GOFIGURE2_VERSION} ) SET( MACOSX_BUNDLE_LONG_VERSION_STRING Version ${GOFIGURE2_VERSION} ) SET( GOFIGURE2_INSTALL_LICENSE_DIR ${plugin_dest_dir}/Licenses ) SET( GOFIGURE2_INSTALL_RESOURCE_DIR ${plugin_dest_dir}/Resources ) ENDIF( APPLE ) IF( WIN32 ) IF( MINGW ) ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/myapp.o COMMAND windres.exe -I${CMAKE_CURRENT_SOURCE_DIR} -i ${GOFIGURE2_SOURCE_DIR}/Resources/myapp.rc -o ${CMAKE_CURRENT_BINARY_DIR}/myapp.o ) SET( ${GOFIGURE_APPLICATION_SOURCE_LIST} ${GOFIGURE_APPLICATION_SOURCE_LIST} ${CMAKE_CURRENT_BINARY_DIR}/myapp.o ) ELSE( MINGW ) SET( GOFIGURE_APPLICATION_SOURCE_LIST ${GOFIGURE_APPLICATION_SOURCE_LIST} ${GOFIGURE2_SOURCE_DIR}/Resources/myapp.rc ) ENDIF( MINGW ) #------------------------------------------------------------------------- # This sets the windows build that will need the special winmain@16 call. # Qt provides this for us in the qtmain.lib file. Using this cmake code # will ensure we have it linked into our build. Not needed on # Unix/OS X/Linux which is why we have the IF(WIN32) conditional. SET( QT_USE_QTMAIN TRUE ) ENDIF( WIN32 ) # -------- # gofigure ADD_EXECUTABLE( gofigure MACOSX_BUNDLE ${GOFIGURE_MAIN} ${GOFIGURE_APPLICATION_SOURCE_LIST} ${QGoGUIINTERFACES_SRC} ${QGoGUISRC_MOC} ${QGoMainWindow_QRC} ${qt_menu_nib_sources} ) TARGET_LINK_LIBRARIES( gofigure QGoGui QGoIO itkQt ${Boost_LIBRARIES} ) IF( BUILD_COMPARETOOL ) # comparegui ADD_EXECUTABLE( comparegui comparegui.cxx ${GOFIGURE_APPLICATION_SOURCE_LIST} ${QGoGUIINTERFACES_SRC} ${QGoGUISRC_MOC} ${QGoMainWindow_QRC} ${qt_menu_nib_sources} ) TARGET_LINK_LIBRARIES( comparegui QGoGui QGoIO itkQt ) ENDIF( BUILD_COMPARETOOL ) #--------------------------------------------------------------------------- # Now the installation stuff below #--------------------------------------------------------------------------- SET( plugin_dest_dir ${GOFIGURE2_INSTALL_BIN_DIR} ) SET( qtconf_dest_dir ${GOFIGURE2_INSTALL_BIN_DIR} ) IF( APPLE ) SET( plugin_dest_dir gofigure.app/Contents/MacOS ) SET( qtconf_dest_dir gofigure.app/Contents/Resources ) SET( APPS "\${CMAKE_INSTALL_PREFIX}/gofigure.app" ) # "\${CMAKE_INSTALL_PREFIX}/${GOFIGURE2_INSTALL_BUNDLE_DIR}/gofigure.app" ) ENDIF( APPLE ) IF( WIN32 ) SET( APPS "\${CMAKE_INSTALL_PREFIX}/${GOFIGURE2_INSTALL_BIN_DIR}/gofigure.exe" ) ENDIF(WIN32) IF( UNIX AND NOT APPLE ) SET( APPS "\${CMAKE_INSTALL_PREFIX}/${GOFIGURE2_INSTALL_BIN_DIR}/gofigure" ) IF( NOT DESKTOP_ENTRY ) SET( DESKTOP_ENTRY gofigure2.desktop ) ENDIF( NOT DESKTOP_ENTRY ) CONFIGURE_FILE( ${GOFIGURE2_SOURCE_DIR}/Main/gf2-desktop.sh.in ${GOFIGURE2_BINARY_DIR}/Main/gf2-desktop.sh @ONLY IMMEDIATE ) ADD_CUSTOM_COMMAND( OUTPUT ${DESKTOP_ENTRY} COMMAND touch ${DESKTOP_ENTRY} COMMAND sh ${GOFIGURE2_BINARY_DIR}/Main/gf2-desktop.sh ${CMAKE_INSTALL_PREFIX} >${DESKTOP_ENTRY} DEPENDS ${GOFIGURE2_BINARY_DIR}/Main/gf2-desktop.sh COMMENT "Generating desktop entry file" ) ADD_CUSTOM_TARGET( DESKTOP_ENTRY_FILE ALL DEPENDS ${DESKTOP_ENTRY} ) SET( GOFIGURE2_ICON ${GOFIGURE2_SOURCE_DIR}/Resources/fig/Myapp2.png ) INSTALL( FILES ${GOFIGURE2_ICON} DESTINATION share/gofigure2/icons COMPONENT Runtime ) ENDIF( UNIX AND NOT APPLE ) # MESSAGE( ${APPS} ) #--------------------------------------------------------------------------- # Install gofigure, on Apple, the bundle is at the root of the # install tree, and on other platforms it'll go into the bin directory. INSTALL( TARGETS gofigure ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime BUNDLE DESTINATION ${GOFIGURE2_INSTALL_BUNDLE_DIR} COMPONENT Runtime ) #--------------------------------------------------------------------------- IF( WIN32 OR APPLE ) SET( USE_BUNDLE_UTILITIES TRUE ) ELSE() OPTION( INSTALLED_3RD_PART "Are Qt, VTK, ITK... installed?" TRUE ) SET( USE_BUNDLE_UTILITIES FALSE ) ENDIF() IF( USE_BUNDLE_UTILITIES ) #--------------------------------------------------------------------------- # Use BundleUtilities to get all other dependencies for the application to # work. It takes a bundle or executable along with possible plugins and # inspects it for dependencies. If they are not system dependencies, # they are copied. # directories to look for dependencies SET( DIRS # ${QT_LIBRARY_DIR} # ${QT_PLUGINS_DIR} # ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} # ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} # ${ITK_LIBRARY_DIRS} # ${VTK_LIBRARY_DIRS} # ${FFMPEG_LIBRARY_DIRS} " " ) # Now the work of copying dependencies into the bundle/package # The quotes are escaped and variables to use at install time have their $ i# escaped # An alternative is the do a configure_file() on a script and use # install(SCRIPT ...). # Note that the image plugins depend on QtSvg and QtXml, and it got those # copied over. INSTALL( CODE " file( GLOB_RECURSE QTPLUGINS \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/plugins/*${CMAKE_SHARED_LIBRARY_SUFFIX}\" ) include( BundleUtilities ) fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\") " COMPONENT Runtime ) ENDIF( USE_BUNDLE_UTILITIES ) IF( APPLE ) #--------------------------------------------------------------------------- # install a qt.conf file # this inserts some cmake code into the install script to write the file INSTALL( CODE " file( WRITE \"\${CMAKE_INSTALL_PREFIX}/${GOFIGURE2_INSTALL_BUNDLE_DIR}/${qtconf_dest_dir}/qt.conf\" \"\") " COMPONENT Runtime ) ENDIF( APPLE ) #----------------------------------------------------- # Here Let's take care of License and Resoources files FILE( GLOB GOFIGURE2_LICENSE_FILES "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Licenses/*.txt" ) FILE( GLOB GOFIGURE2_RESOURCES_FILE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Resources/*.txt" ) # licence files INSTALL( FILES ${GOFIGURE2_LICENSE_FILES} DESTINATION ${GOFIGURE2_INSTALL_LICENSE_DIR} COMPONENT Runtime ) # resources files INSTALL( FILES ${GOFIGURE2_RESOURCES_FILE} DESTINATION ${GOFIGURE2_INSTALL_RESOURCE_DIR} COMPONENT Runtime ) FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) INSTALL( FILES ${__source_file_h} ${QGoMainWindow_UI_H} DESTINATION ${GOFIGURE2_INSTALL_HEADER_DIR} COMPONENT Development ) GoFigure2-v0.9.0/Main/QGoTabManager.h0000644000175000017500000000602611667757442017045 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef __QGoTabManager_h #define __QGoTabManager_h #include #include #include #include "QGoTabElementBase.h" class QTabWidget; class QGoMainWindow; //class QGoTabElementBase; /** \class QGoTabManager \brief */ class QGoTabManager:public QObject { Q_OBJECT public: explicit QGoTabManager(QGoMainWindow *iMW = 0, QTabWidget *iTW = 0); ~QGoTabManager(); typedef QGoTabElementBase::QGoDockWidgetStatusPair QGoDockWidgetStatusPair; /** \brief Set the MainWindow if it has not been set by calling the constructor.*/ void SetMainWindow(QGoMainWindow *iMW); /** \brief Set the TabWidget if it has not been set by calling the constructor.*/ void SetTabWidget(QTabWidget *iTW); public slots: void ChangeCurrentTab(int iIdx); void CloseTab(int idx); void CloseAllTabs(); void UpdateBookmarkMenu(std::vector< QAction * > iBookmarkActions); private: QGoMainWindow *m_MainWindow; QTabWidget * m_TabWidget; int m_PreviousTabIndex; void ClearTabElement(QGoTabElementBase *iE); void SetUpTabElement(QGoTabElementBase *iE); void UpdateViewMenu(std::vector< QAction* > iViewNoToolBarActions); QMainWindow* GetMainWindow(QGoDockWidgetStatusPair iDockStatus); Q_DISABLE_COPY(QGoTabManager); }; #endif GoFigure2-v0.9.0/Main/QGoSynchronizedViewMainWindow.cxx0000644000175000017500000004671011667757442022732 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoSynchronizedViewMainWindow.h" #include #include #include "qinputdialog.h" #include "QGoSynchronizedView.h" #include "QGoSynchronizedView3D.h" #include "QGoSynchronizedViewManager.h" #include "itkImageFileReader.h" #include "vtkImageReader2Factory.h" #include "vtkImageReader2.h" #include "vtkImageData.h" QGoSynchronizedViewMainWindow::QGoSynchronizedViewMainWindow() { m_SynchronizedViewManager = new QGoSynchronizedViewManager(this); mdiArea = new QMdiArea; setCentralWidget(mdiArea); connect( mdiArea, SIGNAL( subWindowActivated(QMdiSubWindow *) ), this, SLOT( updateMenus() ) ); windowMapper = new QSignalMapper(this); connect( windowMapper, SIGNAL( mapped(QWidget *) ), this, SLOT( setActiveSubWindow(QWidget *) ) ); createActions(); createMenus(); createToolBars(); createStatusBar(); updateMenus(); setWindowTitle( tr("QGoSynchronizedViewMainWindow") ); setUnifiedTitleAndToolBarOnMac(true); //mdiArea->setViewMode(QMdiArea::TabbedView); } QGoSynchronizedViewMainWindow:: ~QGoSynchronizedViewMainWindow() { } QGoSynchronizedViewManager * QGoSynchronizedViewMainWindow::GetSynchronizedViewManager() { return m_SynchronizedViewManager; } void QGoSynchronizedViewMainWindow::Update() { m_SynchronizedViewManager->Update(); m_SynchronizedViewManager->show(); } QGoSynchronizedView * QGoSynchronizedViewMainWindow::newSynchronizedView(QString iSynchronizedViewName, vtkImageData *iImage) { QGoSynchronizedView *synchronizedView; synchronizedView = dynamic_cast< QGoSynchronizedView * >( m_SynchronizedViewManager->newSynchronizedView(iSynchronizedViewName, iImage) ); mdiArea->addSubWindow(synchronizedView, Qt::SubWindow); synchronizedView->parentWidget() ->resize(300, 300); synchronizedView->show(); tileAct->trigger(); return synchronizedView; } ///* //QGoSynchronizedView3D* // QGoSynchronizedViewMainWindow::newSynchronizedView3D(QString // iSynchronizedViewName, QString iImagePath) //{ // QGoSynchronizedView3D *synchronizedView = // m_SynchronizedViewManager->newSynchronizedView3D( iSynchronizedViewName, // iImage); // // mdiArea->addSubWindow(synchronizedView); // // return synchronizedView; //} //*/ void QGoSynchronizedViewMainWindow::deleteSynchronizedView2D(const int & iId) { m_SynchronizedViewManager->deleteSynchronizedView2D(iId); } void QGoSynchronizedViewMainWindow::deleteSynchronizedView3D(const int & iId) { m_SynchronizedViewManager->deleteSynchronizedView3D(iId); } void QGoSynchronizedViewMainWindow::closeEvent(QCloseEvent *iEvent) { if ( m_SynchronizedViewManager != NULL ) { delete m_SynchronizedViewManager; } mdiArea->closeAllSubWindows(); QMainWindow::closeEvent(iEvent); iEvent->accept(); } void QGoSynchronizedViewMainWindow::openfile() { QString filename = QFileDialog::getOpenFileName( this, tr("Select Image"), "", tr("Images (*.png *.bmp *.jpg *.jpeg *.tiff *.mha *.mhd *.img *.lsm)") ); if ( !filename.isEmpty() ) { this->OpenSynchronizedViewForFile(filename); } } void QGoSynchronizedViewMainWindow::OpenSynchronizedViewForFile(QString & iFile) { if ( QFile::exists(iFile) ) { // parse extension QString ext = QFileInfo(iFile).suffix(); //if( ext.compare( "lsm", Qt::CaseInsensitive ) == 0 ) // { // this->OpenLSMImage( m_CurrentFile, 0 ); // } //else { vtkImageReader2Factory *r_factory = vtkImageReader2Factory::New(); vtkImageReader2 * reader = r_factory->CreateImageReader2( iFile.toAscii().data() ); reader->SetFileName( iFile.toAscii().data() ); reader->Update(); vtkImageData *image = reader->GetOutput(); newSynchronizedView(iFile, image); reader->Delete(); r_factory->Delete(); } } } void QGoSynchronizedViewMainWindow::snapshotAs() { QGoSynchronizedView *ScreenshotSynchronizedView = activeSynchronizedView(); QString filename = QFileDialog::getSaveFileName( this, tr("Select Image"), "", tr("Images (*.png *.bmp *.jpg *.jpeg *.tiff)") ); if ( !filename.isEmpty() ) { this->SaveSnapshotInFile(filename, ScreenshotSynchronizedView); } } void QGoSynchronizedViewMainWindow::SaveSnapshotInFile(QString & iFile, QGoSynchronizedView *SynchronizedView) { QGoSynchronizedView3D *temp3DSynchronizedView = NULL; QGoSynchronizedView2D *temp2DSynchronizedView = NULL; GoFigure::FileType iType; QString extension = iFile.section('.', -1); QString nameOfScreenshot = iFile.section('/', -1); if ( extension.isEmpty() || nameOfScreenshot.isEmpty() ) { std::cerr << "QGoSynchronizedViewMainWindow::SaveSnapshotInFile incorrect name of file" << std::endl; return; } std::cout << iFile.toStdString() << std::endl; std::cout << extension.toStdString() << std::endl; std::cout << nameOfScreenshot.toStdString() << std::endl; // file extension parsing if ( ( extension.contains("jpg", Qt::CaseInsensitive) ) || ( extension.contains("jpeg", Qt::CaseInsensitive) ) ) { iType = GoFigure::JPEG; } else { if ( extension.contains("bmp", Qt::CaseInsensitive) ) { iType = GoFigure::BMP; } else { if ( extension.contains("png", Qt::CaseInsensitive) ) { iType = GoFigure::PNG; } else { if ( extension.contains("eps", Qt::CaseInsensitive) ) { iType = GoFigure::EPS; } else { if ( extension.contains("tiff", Qt::CaseInsensitive) ) { iType = GoFigure::TIFF; } else { std::cerr << "QGoSynchronizedViewMainWindow::SaveSnapshotInFile couldn't find appropriate extension" << std::endl; return; } } } } } if ( SynchronizedView != 0 ) { // if we take a snapshot of a 3D synchronizedView if ( SynchronizedView->GetSynchronizedViewType() == 3 ) { temp3DSynchronizedView = static_cast< QGoSynchronizedView3D * >( SynchronizedView ); temp3DSynchronizedView->GetFullScreenView(); switch ( temp3DSynchronizedView->GetFullScreenView() ) { case 0: temp3DSynchronizedView->SnapshotViewXYZ(iType, iFile); break; case 1: temp3DSynchronizedView->SnapshotViewXY(iType, iFile); break; case 2: temp3DSynchronizedView->SnapshotViewXZ(iType, iFile); break; case 3: temp3DSynchronizedView->SnapshotViewYZ(iType, iFile); break; case 4: temp3DSynchronizedView->SnapshotViewXYZ(iType, iFile); break; default: std::cerr << "QGoSynchronizedViewMainWindow::SaveSnapshotInFile can't access fullscreen view" << std::endl; return; break; // facultative } } else // if we take a snapshot of a 2D synchronizedView { temp2DSynchronizedView = static_cast< QGoSynchronizedView2D * >( SynchronizedView ); temp2DSynchronizedView->SnapshotViewXY(iType, iFile); } } else { std::cerr << "QGoSynchronizedViewMainWindow::SaveSnapshotInFile synchronizedView pointer error" << std::endl; return; } } void QGoSynchronizedViewMainWindow::imageinfo() { std::stringstream timageinfo; if ( activeSynchronizedView() ) { activeSynchronizedView()->PrintOs(timageinfo); QMessageBox::about( this, tr("Image Informations"), QString::fromStdString( timageinfo.str() ) ); } } void QGoSynchronizedViewMainWindow::synchronize() { if ( m_SynchronizedViewManager->isSynchronizing() ) { m_SynchronizedViewManager->unSynchronizeOpenSynchronizedViews(); syncAct->setText( tr("&Synchronize images") ); syncAct->setStatusTip( tr("Synchronize open images for point-to-point comparison") ); } else { m_SynchronizedViewManager->synchronizeOpenSynchronizedViews(); syncAct->setText( tr("De&Synchronize images") ); syncAct->setStatusTip( tr("Synchronize open images for point-to-point comparison") ); } } void QGoSynchronizedViewMainWindow::FullscreenXY() { if ( activeSynchronizedView() != 0 ) { if ( activeSynchronizedView()->GetSynchronizedViewType() == 3 ) { static_cast< QGoSynchronizedView3D * >( activeSynchronizedView() )->SetFullXYScreenView(); } } } void QGoSynchronizedViewMainWindow::FullscreenXZ() { if ( activeSynchronizedView() != 0 ) { if ( activeSynchronizedView()->GetSynchronizedViewType() == 3 ) { static_cast< QGoSynchronizedView3D * >( activeSynchronizedView() )->SetFullXZScreenView(); } } } void QGoSynchronizedViewMainWindow::FullscreenYZ() { if ( activeSynchronizedView() != 0 ) { if ( activeSynchronizedView()->GetSynchronizedViewType() == 3 ) { static_cast< QGoSynchronizedView3D * >( activeSynchronizedView() )->SetFullYZScreenView(); } } } void QGoSynchronizedViewMainWindow::FullscreenXYZ() { if ( activeSynchronizedView() != 0 ) { if ( activeSynchronizedView()->GetSynchronizedViewType() == 3 ) { static_cast< QGoSynchronizedView3D * >( activeSynchronizedView() )->SetFullXYZScreenView(); } } } void QGoSynchronizedViewMainWindow::Quadscreen() { if ( activeSynchronizedView() != 0 ) { if ( activeSynchronizedView()->GetSynchronizedViewType() == 3 ) { static_cast< QGoSynchronizedView3D * >( activeSynchronizedView() )->SetQuadView(); } } } void QGoSynchronizedViewMainWindow::about() { QMessageBox::about( this, tr("About QGoCompare"), tr("QGoCompare lets you open multiple" " VTK/ITK images from a" " VTK or ITK pipeline and compare them." " This program uses" " Qt, VTK, ITK and GoFigure2 libraries") ); } void QGoSynchronizedViewMainWindow::aboutGF2() { QMessageBox::about( this, tr("About GoFigure2"), tr("GoFigure2 is a cross-platform," " free open source software (FOSS), for" " visualizing, processing and analysing of bioimages" " http://gofigure2.sourceforge.net/") ); } void QGoSynchronizedViewMainWindow::updateMenus() { bool hasSynchronizedView = ( activeSynchronizedView() != 0 ); syncAct->setEnabled(hasSynchronizedView); closeAct->setEnabled(hasSynchronizedView); closeAllAct->setEnabled(hasSynchronizedView); tileAct->setEnabled(hasSynchronizedView); cascadeAct->setEnabled(hasSynchronizedView); // if it is a 3D view, we activate the change view actions bool has3DSynchronizedView = ( ( hasSynchronizedView ) && ( activeSynchronizedView()->GetSynchronizedViewType() == 3 ) ); XYviewAct->setEnabled(has3DSynchronizedView); XZviewAct->setEnabled(has3DSynchronizedView); YZviewAct->setEnabled(has3DSynchronizedView); XYZviewAct->setEnabled(has3DSynchronizedView); QuadviewAct->setEnabled(has3DSynchronizedView); View3DToolBar->setVisible(has3DSynchronizedView); } void QGoSynchronizedViewMainWindow::updateWindowMenu() { windowMenu->clear(); windowMenu->addAction(closeAct); windowMenu->addAction(closeAllAct); windowMenu->addSeparator(); windowMenu->addAction(tileAct); windowMenu->addAction(cascadeAct); } void QGoSynchronizedViewMainWindow::createActions() { openfileAct = new QAction( /*QIcon( ":/images/open.png" ),*/ tr("&Open an image file"), this); openfileAct->setShortcuts(QKeySequence::Open); openfileAct->setStatusTip( tr("Open an image from file") ); connect( openfileAct, SIGNAL( triggered() ), this, SLOT( openfile() ) ); /* openmemAct = new QAction( tr("Open from &memory"), this); // openmemAct->setShortcuts(QKeySequence::Open); openmemAct->setStatusTip(tr("Open an image from memory")); connect(openmemAct, SIGNAL(triggered()), this, SLOT(openfile())); */ syncAct = new QAction(tr("&Synchronize images"), this); // syncAct->setShortcuts(QKeySequence::SaveAs); syncAct->setStatusTip( tr("Synchronize open images for point-to-point comparison") ); connect( syncAct, SIGNAL( triggered() ), this, SLOT( synchronize() ) ); snapshotAsAct = new QAction(tr("Sna&pshot..."), this); snapshotAsAct->setShortcuts(QKeySequence::SaveAs); snapshotAsAct->setStatusTip( tr("Save a Snapshot as..") ); connect( snapshotAsAct, SIGNAL( triggered() ), this, SLOT( snapshotAs() ) ); //! [0] exitAct = new QAction(tr("E&xit"), this); #if ( ( QT_MAJOR_VERSION == 4 ) && ( QT_MINOR_VERSION >= 6 ) ) exitAct->setShortcuts(QKeySequence::Quit); #endif exitAct->setStatusTip( tr("Exit the application") ); connect( exitAct, SIGNAL( triggered() ), qApp, SLOT( closeAllWindows() ) ); //! [0] closeAct = new QAction(tr("Cl&ose"), this); closeAct->setStatusTip( tr("Close the active image") ); connect( closeAct, SIGNAL( triggered() ), mdiArea, SLOT( closeActiveSubWindow() ) ); closeAllAct = new QAction(tr("Close &All"), this); closeAllAct->setStatusTip( tr("Close all images") ); connect( closeAllAct, SIGNAL( triggered() ), mdiArea, SLOT( closeAllSubWindows() ) ); tileAct = new QAction(tr("&Tile"), this); tileAct->setStatusTip( tr("Tile the images") ); connect( tileAct, SIGNAL( triggered() ), mdiArea, SLOT( tileSubWindows() ) ); cascadeAct = new QAction(tr("&Cascade"), this); cascadeAct->setStatusTip( tr("Cascade the images") ); connect( cascadeAct, SIGNAL( triggered() ), mdiArea, SLOT( cascadeSubWindows() ) ); aboutAct = new QAction(tr("&About"), this); aboutAct->setStatusTip( tr("Show the application's About box") ); connect( aboutAct, SIGNAL( triggered() ), this, SLOT( about() ) ); aboutGF2Act = new QAction(tr("About &GoFigure2"), this); aboutGF2Act->setStatusTip( tr("Show the Gofigure2 About box") ); connect( aboutGF2Act, SIGNAL( triggered() ), this, SLOT( aboutGF2() ) ); aboutQtAct = new QAction(tr("About &Qt"), this); aboutQtAct->setStatusTip( tr("Show the Qt library's About box") ); connect( aboutQtAct, SIGNAL( triggered() ), qApp, SLOT( aboutQt() ) ); XYviewAct = new QAction(tr("XY view"), this); aboutQtAct->setStatusTip( tr("Shows XY view") ); connect( XYviewAct, SIGNAL( triggered() ), this, SLOT( FullscreenXY() ) ); XZviewAct = new QAction(tr("XZ view"), this); aboutQtAct->setStatusTip( tr("Shows XZ view") ); connect( XZviewAct, SIGNAL( triggered() ), this, SLOT( FullscreenXZ() ) ); YZviewAct = new QAction(tr("YZ view"), this); aboutQtAct->setStatusTip( tr("Shows YZ view") ); connect( YZviewAct, SIGNAL( triggered() ), this, SLOT( FullscreenYZ() ) ); XYZviewAct = new QAction(tr("3D view"), this); aboutQtAct->setStatusTip( tr("Show 3D view") ); connect( XYZviewAct, SIGNAL( triggered() ), this, SLOT( FullscreenXYZ() ) ); QuadviewAct = new QAction(tr("Quad-view"), this); aboutQtAct->setStatusTip( tr("Show 3D view and XY,XZ,YZ projections") ); connect( QuadviewAct, SIGNAL( triggered() ), this, SLOT( Quadscreen() ) ); } void QGoSynchronizedViewMainWindow::createMenus() { fileMenu = menuBar()->addMenu( tr("&File") ); fileMenu->addAction(openfileAct); // fileMenu->addAction(openmemAct); fileMenu->addAction(snapshotAsAct); fileMenu->addSeparator(); windowMenu = menuBar()->addMenu( tr("&Window") ); updateWindowMenu(); connect( windowMenu, SIGNAL( aboutToShow() ), this, SLOT( updateWindowMenu() ) ); menuBar()->addSeparator(); helpMenu = menuBar()->addMenu( tr("&Help") ); helpMenu->addAction(aboutAct); helpMenu->addAction(aboutQtAct); helpMenu->addAction(aboutGF2Act); } void QGoSynchronizedViewMainWindow::createToolBars() { ToolBar = addToolBar( tr("ImageActions") ); // ToolBar->addAction(openmemAct); ToolBar->addAction(openfileAct); ToolBar->addAction(snapshotAsAct); ToolBar->addAction(syncAct); View3DToolBar = addToolBar( tr("Image 3D View selection") ); View3DToolBar->addAction(XYviewAct); View3DToolBar->addAction(XZviewAct); View3DToolBar->addAction(YZviewAct); View3DToolBar->addAction(XYZviewAct); View3DToolBar->addAction(QuadviewAct); } void QGoSynchronizedViewMainWindow::createStatusBar() { statusBar()->showMessage( tr("Ready") ); } QGoSynchronizedView * QGoSynchronizedViewMainWindow::activeSynchronizedView() { if ( QMdiSubWindow * activeSubWindow = mdiArea->activeSubWindow() ) { return static_cast< QGoSynchronizedView * >( activeSubWindow->widget() ); } else { return 0; } } QMdiSubWindow * QGoSynchronizedViewMainWindow::findSynchronizedView(const QString & iSynchronizedViewName) { foreach ( QMdiSubWindow * twindow, mdiArea->subWindowList() ) { QGoSynchronizedView *SynchronizedView = qobject_cast< QGoSynchronizedView * >( twindow->widget() ); if ( SynchronizedView->GetName() == iSynchronizedViewName ) { return twindow; } } return NULL; } void QGoSynchronizedViewMainWindow::setActiveSubWindow(QWidget *twindow) { if ( !twindow ) { return; } else { mdiArea->setActiveSubWindow( qobject_cast< QMdiSubWindow * >(twindow) ); } }GoFigure2-v0.9.0/Main/gf2-desktop.sh.in0000644000175000017500000000051011667757442017342 0ustar mathieumathieu#!/bin/sh cat < go_mainwindow Qt::NonModal 0 0 1434 826 GoFigure :/fig/Myapp2.png:/fig/Myapp2.png true QTabWidget::North QTabWidget::Rounded 1 Qt::ElideLeft Tab 1 Page 0 0 1434 25 File true Open Recent Files false Single Files false Multiple Files Database Files Help false View false Filtering false Segmentation false Tools false Bookmarks false Mode Settings Database false Open Files 24 24 TopToolBarArea false false false :/fig/document-open.png:/fig/document-open.png Open Single File Ctrl+O true Open MegaCapture Files false Save Multiple Files true :/fig/system-quit.png:/fig/system-quit.png Quit Ctrl+Q true Close Tab Ctrl+W About About Qt QAction::AboutQtRole Close all false Open Mesh / Contour :/fig/UseDatabase.png:/fig/UseDatabase.png Use DataBase GoFigure2 website Report a bug... User mailing list Developer mailing list QuadView XYT FullScreen XY Full screen XZ Full screen YZ Full screen XYZ XYT View QuadView XYZ Full screen XY Full screen XT Full screen YT Full screen XYT Full screen XY Side-bar false Add Bookmark false Manage Bookmarks false false Load Segmentation Results Export LSM to MegaCapture Contour Contours Mesh Track Lineage Contours Mesh Track Lineage Set Up Database Check For Updates GoFigure2-v0.9.0/Main/comparegui.cxx0000644000175000017500000000442711667757442017146 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include #include "QGoSynchronizedViewMainWindow.h" int main(int argc, char **argv) { QApplication app(argc, argv); QCoreApplication::setOrganizationName("MegasonLab"); QCoreApplication::setOrganizationDomain("http://gofigure2.sourceforge.net"); QGoSynchronizedViewMainWindow *SynchronizedViewMainWindow = new QGoSynchronizedViewMainWindow(); SynchronizedViewMainWindow->Update(); SynchronizedViewMainWindow->show(); app.processEvents(); int output = app.exec(); return output; }GoFigure2-v0.9.0/Main/QGoMainWindow.cxx0000644000175000017500000013452411667757442017500 0ustar mathieumathieu/*========================================================================= Authors: The GoFigure Dev. Team. at Megason Lab, Systems biology, Harvard Medical school, 2009-11 Copyright (c) 2009-11, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #include "QGoMainWindow.h" #include "QGoTabElementBase.h" #include "QGoTabImageView2D.h" #include "QGoTabImageView3D.h" #include "QGoTabImageView3DwT.h" #include "QGoPrintDatabase.h" #include "QGoNetworkUtilities.h" #include "ContourMeshContainer.h" // Plugin stuff #include "QGoPluginHelper.h" #include "QGoImageFilterPluginBase.h" #include #include // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include // Qt Dialog Box #include "QGoLsmToMegaExportDialog.h" // itk includes #include "itkImageFileReader.h" #include "itkMegaCaptureImport.h" // vtk includes #include "vtkLSMReader.h" #include "vtkPLYReader.h" #include "vtkImageData.h" #include "vtkImageReader2Factory.h" #include "vtkImageReader2.h" #include "vtkSmartPointer.h" #include "QGoTabManager.h" #include "QGoWizardDB.h" #include //-------------------------------------------------------------------------- QGoMainWindow::QGoMainWindow(QWidget *iParent, Qt::WindowFlags iFlags) : QMainWindow(iParent, iFlags), m_ViewToolBar(NULL), m_ModeToolBar(NULL), m_TracesToolBar(NULL), m_TraceSettingsToolBar(NULL), m_MaxNumberOfTraces(5000) { QString title("<*)0|00|0>< ~~ <*)0|00|0>< GoFigure ><0|00|0(*> ~~ ><0|00|0(*>"); this->setupUi(this); setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); QRect screen = QApplication::desktop()->availableGeometry(this); int numberOfScreens = QApplication::desktop()->numScreens(); QSize MaximumSize = screen.size() * numberOfScreens; this->setMaximumSize(MaximumSize); // QSize IconSize = this->iconSize(); QSize SizeIcon(22, 22); this->setIconSize(SizeIcon); //QSize IconSize = this->iconSize(); this->setCentralWidget(this->CentralTabWidget); this->setWindowTitle(title); this->statusbar->showMessage( tr("No data") ); this->CentralTabWidget->clear(); this->CentralTabWidget->setTabsClosable(true); this->CentralTabWidget->setMovable(true); this->statusbar->addPermanentWidget(&m_Bar); m_TabManager = new QGoTabManager(this, this->CentralTabWidget); /*this->m_ViewToolBar = new QToolBar(tr("View"), this); this->m_ViewToolBar->setObjectName( tr("View") ); this->addToolBar(Qt::TopToolBarArea, this->m_ViewToolBar); this->m_ModeToolBar = new QToolBar(tr("Mode"), this); this->m_ModeToolBar->setObjectName( tr("Mode") ); this->addToolBar(Qt::TopToolBarArea, this->m_ModeToolBar); this->m_TracesToolBar = new QToolBar(tr("Tools For Traces"), this); this->m_TracesToolBar->setObjectName( tr("Traces") ); this->addToolBar(Qt::TopToolBarArea, this->m_TracesToolBar); this->m_TraceSettingsToolBar = new QToolBar(tr("Settings For the Trace"), this); this->m_TraceSettingsToolBar->setObjectName(tr("TraceSettingsToolBar")); this->addToolBar(Qt::TopToolBarArea, this->m_TraceSettingsToolBar);*/ // m_LSMReader = vtkLSMReader::New(); m_DBWizard = new QGoWizardDB(this); m_DBWizard->hide(); m_AboutWidget = new QGoAboutWidget; this->m_AboutWidget->hide(); m_Bar.hide(); QString temp; SetCurrentSingleFile(temp); SetCurrentMultiFile(temp); SetCurrentDatabaseFile(temp); //temp: this->actionExportMesh->setVisible(false); this->actionExportLineage->setVisible(false); this->actionExportTrack->setVisible(false); this->actionImportMesh->setVisible(false); this->actionImportTrack->setVisible(false); this->actionImportLineage->setVisible(false); m_NetworkUtilities = new QGoNetworkUtilities(this); CreateSignalSlotsConnection(); ReadSettings(); // Updates ------------------------------- QObject::connect( m_NetworkUtilities, SIGNAL( CheckForUpdatesDone(QString, bool) ), this, SLOT( DisplayUpdateResults(QString, bool) ) ); m_ManualUpdate = false; m_NetworkUtilities->CheckForUpdates(); // --------------------------------------- if ( !this->m_DatabaseSetUp ) { this->AddSetUpDatabaseMenu(); } else { QObject::connect( this->m_DBWizard, SIGNAL ( NoGofigureDatabase () ), this, SLOT( AddSetUpDatabaseMenu() ) ); } // LoadPlugins(); } //-------------------------------------------------------------------------- QGoMainWindow::~QGoMainWindow() { // clear will call destructor on all of the element in the list // what is the point of the list? if(this->m_LSMReader.back()) { this->m_LSMReader.back()->Delete(); } this->WriteSettings(); delete m_TabManager; delete m_DBWizard; delete m_AboutWidget; } //-------------------------------------------------------------------------- void QGoMainWindow::SetMaxNumberOfTraces( unsigned int iN ) { if( iN != 0 ) { this->m_MaxNumberOfTraces = iN; } else { this->m_MaxNumberOfTraces = std::numeric_limits< unsigned int >::max(); } } //-------------------------------------------------------------------------- void QGoMainWindow::CreateSignalSlotsConnection() { //QObject::connect( this->actionOpen, SIGNAL( triggered( ) ), //this, SLOT( showprogressloading() ) ); QObject::connect( this->CentralTabWidget, SIGNAL( tabCloseRequested(int) ), m_TabManager, SLOT( CloseTab(int) ) ); QObject::connect( this->CentralTabWidget, SIGNAL( currentChanged(int) ), m_TabManager, SLOT( ChangeCurrentTab(int) ) ); QObject::connect( &m_SignalAdaptor, SIGNAL( Signal() ), &( this->m_Bar ), SLOT( hide() ) ); for ( int i = 0; i < MaxRecentFiles; ++i ) { recentSingleFileActions[i] = new QAction(this); recentSingleFileActions[i]->setVisible(false); QObject::connect( this->recentSingleFileActions[i], SIGNAL( triggered() ), this, SLOT( openRecentSingleFile() ) ); recentMultipleFileActions[i] = new QAction(this); recentMultipleFileActions[i]->setVisible(false); QObject::connect( this->recentMultipleFileActions[i], SIGNAL( triggered() ), this, SLOT( openRecentMultipleFile() ) ); recentDatabaseFileActions[i] = new QAction(this); recentDatabaseFileActions[i]->setVisible(false); QObject::connect( recentDatabaseFileActions[i], SIGNAL( triggered() ), this, SLOT( openRecentDatabaseFile() ) ); } QObject::connect( m_DBWizard, SIGNAL( accepted() ), this, SLOT( openFilesfromDB() ) ); } //-------------------------------------------------------------------------- void QGoMainWindow::on_actionOpen_Single_File_triggered() { QString filename = QFileDialog::getOpenFileName( this, tr("Select Image"), "", tr("Images (*.png *.bmp *.jpg *.jpeg *.tiff *.tif *.mha *.mhd *.img *.lsm)") ); if ( !filename.isEmpty() ) { this->SetSingleFileName(filename); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::on_actionOpen_MegaCapture_Files_triggered() { QString filename = QFileDialog::getOpenFileName( this, tr("Select One Image from the Dataset"), "", tr("Images (*.png *.tif *.tiff *.jpg *.jpeg)") ); if ( !filename.isEmpty() ) { if ( QFile::exists(filename) ) { itk::MegaCaptureImport::Pointer importer = itk::MegaCaptureImport::New(); importer->SetFileName( filename.toStdString() ); try { importer->Update(); } catch ( ... ) { QMessageBox::critical( NULL, tr("Error"), tr("Error while trying to read this Megacatpure") ); return; } GoFigure::FileType filetype; if ( !ComputeFileType(filename, filetype) ) { return; } int TimePoint = importer->GetOutput().get< m_TCoord >().begin()->m_TCoord; CreateNewTabFor3DwtImage(importer->GetOutput(), filetype, importer->GetHeaderFilename(), TimePoint, false); // do not use the database } } } //-------------------------------------------------------------------------- void QGoMainWindow::on_actionUse_DataBase_triggered() { if ( !m_DBWizard->isVisible() ) { m_DBWizard->SetIsAnOpenRecentFile(false); m_DBWizard->show(); m_DBWizard->restart(); } } //-------------------------------------------------------------------------- bool QGoMainWindow::ComputeFileType(const QString & iFileName, GoFigure::FileType & oFileType) { QString extension = QFileInfo(iFileName).suffix(); if ( extension.compare("png", Qt::CaseInsensitive) == 0 ) { oFileType = GoFigure::PNG; return true; } else { if ( ( extension.compare("tif", Qt::CaseInsensitive) == 0 ) || ( extension.compare("tiff", Qt::CaseInsensitive) == 0 ) ) { oFileType = GoFigure::TIFF; return true; } else { if ( ( extension.compare("jpg", Qt::CaseInsensitive) == 0 ) || ( extension.compare("jpeg", Qt::CaseInsensitive) == 0 ) ) { oFileType = GoFigure::JPEG; return true; } else { std::cerr << "file not supported for megacapture!!!" << std::endl; return false; } } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::openFilesfromDB() { if ( this->m_DBWizard->GetIsAnOpenRecentFile() ) { this->openRecentFilesfromDB(); } else { std::string temp = ""; this->DisplayFilesfromDB(temp); this->SetCurrentDatabaseFile( this->m_DBWizard->GetImagingSessionName() ); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::DisplayFilesfromDB(std::string iFirst_Filename) { std::string Header_FileName; GoFigureFileInfoHelperMultiIndexContainer file_container = this->GetFileContainerForMultiFiles( Header_FileName, iFirst_Filename); if ( file_container.size() == 0 ) { std::cout << "GoFigureFileInfoHelperMultiIndexContainer empty "; std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; return; } GoFigureFileInfoHelperMultiIndexContainer::iterator temp_it = file_container.begin(); QString temp_filename = QString::fromStdString(temp_it->m_Filename); GoFigure::FileType filetype; if ( !ComputeFileType(temp_filename, filetype) ) { return; } // note: do not need to call w3t->Update(); since it is internally called // when using CreateNewTabFor3DwtImage int TimePoint = file_container.get< m_TCoord >().begin()->m_TCoord; QGoTabImageView3DwT *w3t = CreateNewTabFor3DwtImage(file_container, filetype, Header_FileName, TimePoint, true); // Use the database QObject::connect( w3t, SIGNAL( UpdateBookmarkOpenActions(std::vector< QAction * > ) ), this->m_TabManager, SLOT( UpdateBookmarkMenu(std::vector< QAction * > ) ) ); // Load all traces LoadAllTracesFromDatabaseManager(TimePoint); // Show contour/mesh for given T point w3t->ShowTraces(TimePoint); this->menuBookmarks->setEnabled(true); //this->addToolBar(w3t->GetTraceSettingsToolBar() ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::LoadAllTracesFromDatabaseManager(const int & iT) { QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); #ifdef HAS_OPENMP #pragma omp sections nowait #endif { #ifdef HAS_OPENMP #pragma omp section #endif { // Loads contours LoadContoursFromDatabase(iT); } #ifdef HAS_OPENMP #pragma omp section #endif { // Loads meshes LoadMeshesFromDatabase(iT); } #ifdef HAS_OPENMP #pragma omp section #endif { // Loads tracks LoadTracksFromDatabase(iT); } } QApplication::restoreOverrideCursor(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::LoadContoursFromDatabase(const int & iT) { QGoTabImageView3DwT *w3t = dynamic_cast< QGoTabImageView3DwT * >( this->CentralTabWidget->currentWidget() ); if ( w3t ) { w3t->CreateContoursActorsFromVisuContainer(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::LoadMeshesFromDatabase(const int & iT) { QGoTabImageView3DwT *w3t = dynamic_cast< QGoTabImageView3DwT * >( this->CentralTabWidget->currentWidget() ); if ( w3t ) { w3t->CreateMeshesActorsFromVisuContainer(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::LoadTracksFromDatabase(const int & iT) { /// \note let's keep for the time being iT parameter in the case where /// we would only load traces for a given time point (that could be usefule /// somehow). (void)iT; QGoTabImageView3DwT *w3t = dynamic_cast< QGoTabImageView3DwT * >( this->CentralTabWidget->currentWidget() ); if ( w3t ) { TrackContainer *temp = w3t->GetTrackContainer(); temp->setTimeInterval( w3t->GetTimeInterval() ); if ( temp ) { // let's iterate on the container with increasing TraceID typedef TrackContainer::MultiIndexContainerType::index< TraceID >::type::iterator TrackContainerIterator; TrackContainerIterator track_list_it = temp->m_Container.get< TraceID >().begin(); TrackContainerIterator track_list_end = temp->m_Container.get< TraceID >().end(); size_t nb_tracks = temp->m_Container.get< TraceID >().size(); QProgressDialog progress( "Loading Tracks...", QString(), 0, nb_tracks ); size_t i = 0; // we don't need here to save this track in the database, // since they have just been extracted from it! while ( track_list_it != track_list_end ) { if ( track_list_it->Nodes ) { TrackStructure Track = *track_list_it; GoFigureTrackAttributes attributes = Track.ComputeAttributes(); //track_list_it->ComputeAttributes(); w3t->m_DataBaseTables->PrintCalculatedValuesForTrack(&attributes, track_list_it->TraceID); } w3t->AddTrackFromNodes< TraceID >(track_list_it); progress.setValue( i ); ++i; ++track_list_it; } progress.setValue( nb_tracks ); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- GoFigureFileInfoHelperMultiIndexContainer QGoMainWindow::GetFileContainerForMultiFiles(std::string & ioHeader_Filename, std::string iFirst_FileName) { GoFigureFileInfoHelperMultiIndexContainer ofile_container; if ( iFirst_FileName.empty() ) { std::string ImgSessionName = this->m_DBWizard->GetImagingSessionName().toStdString(); //this->m_DBWizard->setImgSessionName(ImgSessionName); ofile_container = this->m_DBWizard->GetMultiIndexFileContainer(); } iFirst_FileName = this->m_DBWizard->GetFirstFileName(); // if the size is diiferent than 0, the imagingsession has // just been created and the wizard has already filled the // GoFigureFileInfoHelperMultiIndexContainer using MegcaptureImport if ( ofile_container.size() == 0 || !iFirst_FileName.empty() ) { itk::MegaCaptureImport::Pointer importer = itk::MegaCaptureImport::New(); importer->SetFileName(iFirst_FileName); try { importer->Update(); } catch ( ... ) { QMessageBox::critical( NULL, tr("Error"), tr("Error while trying to read this Megacatpure") ); return ofile_container; } ofile_container = importer->GetOutput(); ioHeader_Filename = importer->GetHeaderFilename(); } else { ioHeader_Filename = m_DBWizard->GetMegaCaptureHeaderFilename(); } return ofile_container; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::on_actionExport_LSM_to_MegaFile_triggered() { //Open the dialog window QGoLsmToMegaExportDialog *dlg = new QGoLsmToMegaExportDialog(this); dlg->show(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::on_actionClose_all_triggered() { m_TabManager->CloseAllTabs(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::on_actionClose_triggered() { int idx = this->CentralTabWidget->currentIndex(); m_TabManager->CloseTab(idx); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::on_actionQuit_triggered() { this->close(); this->WriteSettings(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::SetSingleFileName(const QString & iFile) { if ( QFile::exists(iFile) ) { this->SetCurrentSingleFile(iFile); // parse extension QString ext = QFileInfo(iFile).suffix(); if ( ext.compare("lsm", Qt::CaseInsensitive) == 0 ) { this->OpenLSMImage(m_CurrentFile, 0); } else { vtkImageReader2Factory *r_factory = vtkImageReader2Factory::New(); vtkImageReader2 * reader = r_factory->CreateImageReader2( iFile.toAscii().data() ); reader->SetFileName( iFile.toAscii().data() ); try { reader->Update(); } catch ( ... ) { QMessageBox::critical( NULL, tr("Error"), tr("Error while trying to read this file") ); return; } vtkImageData *image = reader->GetOutput(); int dim[3]; image->GetDimensions(dim); if ( ( dim[0] != 1 ) && ( dim[1] != 1 ) && ( dim[2] != 1 ) ) { CreateNewTabFor3DImage(image, iFile); } else { CreateNewTabFor2DImage(image, iFile); } reader->Delete(); r_factory->Delete(); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::OpenLSMImage(const QString & iFile, const int & iTimePoint) { m_LSMReader.push_back( vtkLSMReader::New() ); m_LSMReader.back()->SetFileName( iFile.toAscii().data() ); m_LSMReader.back()->SetUpdateTimePoint(iTimePoint); try { m_LSMReader.back()->Update(); } catch ( ... ) { QMessageBox::critical( NULL, tr("Error"), QString("Error while trying to read %1 at time %2").arg(iFile).arg(iTimePoint) ); return; } int dim[5]; m_LSMReader.back()->GetDimensions(dim); int ImageDimensionality = 4; // bool Color = ( dim[4] > 1 ); if ( dim[3] == 1 ) // only one time point { if ( dim[2] == 1 ) // only one z slice { ImageDimensionality = 2; } else { ImageDimensionality = 4; } } else { ImageDimensionality = 4; } switch ( ImageDimensionality ) { case 2: { CreateNewTabFor2DImage(m_LSMReader.back()->GetOutput(), iFile); break; } case 3: { CreateNewTabFor3DImage(m_LSMReader.back()->GetOutput(), iFile); break; } default: case 4: { CreateNewTabFor3DwtImage(m_LSMReader.back(), iFile); break; } } } //-------------------------------------------------------------------------- QGoTabImageView3DwT * QGoMainWindow::CreateNewTabFor3DwtImage( const GoFigureFileInfoHelperMultiIndexContainer & iFileList, const GoFigure::FileType & iFileType, const std::string & iHeader, const int & iTimePoint, const bool & iUseDatabase) { // note: do not need to call w3t->Update() since it is internally called in // w3t->SetMegaCaptureFile QGoTabImageView3DwT *w3t = new QGoTabImageView3DwT; w3t->SetStatusBarPointer( this->statusBar() ); w3t->SetMegaCaptureFile(iFileList, iFileType, iHeader, iTimePoint); if ( iUseDatabase ) { // ********************** // Database information //get the content of the tables fron the database to fill the table widget: std::string ImgSessionName = m_DBWizard->GetImagingSessionName().toStdString(); //in case the files are opened from the open recent files, the // imgsessionname //can no more be gotten from the wizard: if ( this->m_DBWizard->GetIsAnOpenRecentFile() ) { ImgSessionName = this->m_CurrentFile.toStdString(); this->m_DBWizard->SetIsAnOpenRecentFile(false); } w3t->m_DataBaseTables->SetDatabaseVariables("gofiguredatabase", m_DBWizard->GetServer().toStdString(), m_DBWizard->GetLogin().toStdString(), m_DBWizard->GetPassword().toStdString(), m_DBWizard->GetImagingSessionID(), ImgSessionName); w3t->m_DataBaseTables->FillTableFromDatabase(this->m_MaxNumberOfTraces); w3t->setWindowTitle( QString::fromStdString(ImgSessionName) ); // ********************** } else { w3t->setWindowTitle( QFileInfo( QString::fromStdString(iHeader) ).fileName() ); } //w3t->InitializeToolBarsAndMenus(this->menuTools, this->m_TracesToolBar); //SetupMenusFromTab(w3t); this->SetUpGeneralMenusToolBars(w3t); this->SetUpMenusToolBarsFor3dwtImage(w3t); this->SetupPluginsAndDockWidgetFromTab(w3t); return w3t; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::SetupPluginsAndDockWidgetFromTab(QGoTabElementBase *iT) { for ( std::list< QAction * >::iterator list_it = m_TabDimPluginActionMap[iT->GetTabDimensionType()].begin(); list_it != m_TabDimPluginActionMap[iT->GetTabDimensionType()].end(); ++list_it ) { ( *list_it )->setEnabled(true); } //iT->CreateModeToolBar(this->menuMode, this->m_ModeToolBar); iT->SetPluginActions(m_TabDimPluginActionMap[iT->GetTabDimensionType()]); std::list< QGoTabElementBase::QGoDockWidgetStatusPair > dock_list = iT->DockWidget(); for ( std::list< QGoTabElementBase::QGoDockWidgetStatusPair >::iterator dck_it = dock_list.begin(); dck_it != dock_list.end(); ++dck_it ) { if ( dck_it->first->m_Attached ) { this->addDockWidget(dck_it->first->m_Area, dck_it->second); } dck_it->second->setVisible(dck_it->first->m_Visibility); } int idx = this->CentralTabWidget->addTab( iT, iT->windowTitle() ); /*this->menuView->setEnabled(true); this->menuFiltering->setEnabled(true); this->menuSegmentation->setEnabled(true); this->menuTools->setEnabled(true); this->menuMode->setEnabled(true);*/ this->CentralTabWidget->setCurrentIndex(idx); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::SetUpGeneralMenusToolBars(QGoTabElementBase *iT) { if (!this->m_ViewToolBar) { this->m_ViewToolBar = new QToolBar(tr("View"), this); this->m_ViewToolBar->setObjectName( tr("View") ); this->addToolBar(Qt::TopToolBarArea, this->m_ViewToolBar); } if(!this->m_ModeToolBar) { this->m_ModeToolBar = new QToolBar(tr("Mode"), this); this->m_ModeToolBar->setObjectName( tr("Mode") ); this->addToolBar(Qt::TopToolBarArea, this->m_ModeToolBar); } iT->CreateModeToolBar(this->menuMode, this->m_ModeToolBar); this->menuView->setEnabled(true); this->menuFiltering->setEnabled(true); this->menuSegmentation->setEnabled(true); this->menuTools->setEnabled(true); this->menuMode->setEnabled(true); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::SetUpMenusToolBarsFor3dwtImage(QGoTabImageView3DwT* iT) { //this->SetupMenusFromTab(iT); if (!this->m_TracesToolBar) { this->m_TracesToolBar = new QToolBar(tr("Tools For Traces"), this); this->m_TracesToolBar->setObjectName( tr("Traces") ); this->addToolBar(Qt::TopToolBarArea, this->m_TracesToolBar); this->addToolBarBreak(Qt::TopToolBarArea); } if (!this->m_TraceSettingsToolBar) { this->m_TraceSettingsToolBar = new QToolBar(tr("Settings For the Trace"), this); m_TraceSettingsToolBar->setObjectName(tr("TraceSettingsToolBar")); this->addToolBar(Qt::TopToolBarArea, m_TraceSettingsToolBar); } //iT->InitializeModeToolBar(this->menuMode, this->m_ModeToolBar); iT->InitializeToolsForTracesToolBar(this->menuTools, this->m_TracesToolBar); iT->InitializeTraceSettingsToolBar(this->m_TraceSettingsToolBar); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoTabImageView3DwT * QGoMainWindow::CreateNewTabFor3DwtImage(vtkLSMReader *iReader, const QString & iFile) { QGoTabImageView3DwT *w3t = new QGoTabImageView3DwT; w3t->setWindowTitle( QFileInfo(iFile).fileName() ); w3t->SetLSMReader(iReader, 0); //SetupMenusFromTab(w3t); this->SetUpGeneralMenusToolBars(w3t); this->SetUpMenusToolBarsFor3dwtImage(w3t); this->SetupPluginsAndDockWidgetFromTab(w3t); // w3t->m_DataBaseTables->hide(); w3t->SetStatusBarPointer( this->statusBar() ); return w3t; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoTabImageView3D * QGoMainWindow::CreateNewTabFor3DImage(vtkImageData *iInput, const QString & iFile) { QGoTabImageView3D *w3 = new QGoTabImageView3D; w3->SetImage(iInput); w3->setWindowTitle( QFileInfo(iFile).fileName() ); w3->Update(); //SetupMenusFromTab(w3); this->SetUpGeneralMenusToolBars(w3); this->SetupPluginsAndDockWidgetFromTab(w3); return w3; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoTabImageView2D * QGoMainWindow::CreateNewTabFor2DImage(vtkImageData *iInput, const QString & iFile) { QGoTabImageView2D *w2 = new QGoTabImageView2D; w2->SetImage(iInput); w2->setWindowTitle( QFileInfo(iFile).fileName() ); w2->Update(); //SetupMenusFromTab(w2); this->SetUpGeneralMenusToolBars(w2); this->SetupPluginsAndDockWidgetFromTab(w2); return w2; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------------- void QGoMainWindow::on_actionAbout_triggered() { this->m_AboutWidget->show(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::on_actionAbout_Qt_triggered() { QMessageBox::aboutQt( this, tr("About Qt") ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::on_actionGoFigure2_Website_triggered() { QDesktopServices::openUrl( QUrl("http://gofigure2.sourceforge.net") ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::on_actionUser_mailing_list_triggered() { QDesktopServices::openUrl( QUrl("mailto:gofigure2-users@lists.sourceforge.net?subject=About GoFigure2") ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::on_actionReport_a_bug_triggered() { QString url( "mailto:gofigure2-developers@lists.sourceforge.net?subject=Bug Report&body=" ); QString app_dir = QCoreApplication::applicationDirPath(); QDir temp = QDir(app_dir); temp.cdUp(); QString app_up_dir = temp.path(); temp.cdUp(); temp.cdUp(); QString app_up_up_up_dir = temp.path(); // linux without install QStringList search_dir(app_dir + "/Resources"); // on windows without install search_dir << app_up_dir + "/Resources"; // linux with install search_dir << app_up_dir + "/share/doc/gofigure2/Resources"; // on mac without install search_dir << app_up_up_up_dir + "/Resources"; QDir::setSearchPaths("BugEntryPath", search_dir); QFile file("BugEntryPath:BugEntry.txt"); file.open(QIODevice::ReadOnly); QTextStream textStream( & file); QString text = textStream.readAll(); url.append( text ); QDesktopServices::openUrl( QUrl( url ) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::on_actionDeveloper_mailing_list_triggered() { QDesktopServices::openUrl( QUrl("mailto:gofigure2-developers@lists.sourceforge.net?subject=About GoFigure2") ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::SetUpDatabase() { this->m_DBInitializationWizard->show(); this->m_DBInitializationWizard->exec(); if ( !this->m_RecentDatabaseFiles.empty() ) { this->m_RecentDatabaseFiles.clear(); UpdateRecentFileActions(this->m_RecentDatabaseFiles, menuDatabase_Files, recentDatabaseFileActions); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::SetCurrentSingleFile(const QString & fileName) { m_CurrentFile = fileName; this->setWindowModified(false); QString shownName = "Untitled"; if ( !m_CurrentFile.isEmpty() ) { shownName = strippedName(m_CurrentFile); m_RecentSingleFiles.removeAll(m_CurrentFile); m_RecentSingleFiles.prepend(m_CurrentFile); UpdateRecentFileActions(m_RecentSingleFiles, menuSingle_Files, recentSingleFileActions); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::LoadPlugins() { foreach( QObject * plugin, QPluginLoader::staticInstances() ) { this->PopulateMenus(plugin); } m_PluginsDir = FindPluginDirectory("plugins"); foreach( QString fileName, m_PluginsDir.entryList(QDir::Files) ) { QPluginLoader loader( m_PluginsDir.absoluteFilePath(fileName) ); QObject * plugin = loader.instance(); if ( plugin ) { this->PopulateMenus(plugin); m_PluginFileNames += fileName; } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::PopulateMenus(QObject *plugin) { QGoImageFilterPluginBase *filter = qobject_cast< QGoImageFilterPluginBase * >(plugin); if ( filter ) { this->AddToMenu(plugin, QStringList( filter->Name() ), this->menuFiltering, SLOT( ApplyImageFilter() ), 0); } else { std::cout << "This is not QGoImageFilterPlugin" << std::endl; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::AddToMenu( QObject *plugin, const QStringList & texts, QMenu *menu, const char *member, QActionGroup *actionGroup) { std::list< GoFigure::TabDimensionType > dim_list; QGoPlugin *temp = dynamic_cast< QGoPlugin * >( plugin ); if ( temp ) { dim_list = temp->TabElementCompatibility(); } foreach(QString text, texts) { QAction *taction = new QAction(text, plugin); taction->setDisabled(true); QObject::connect(taction, SIGNAL( triggered() ), this, member); // QObject::connect( plugin, SIGNAL( Done( std::vector< vtkImageData* > ) ), // this, SLOT( tobedone( std::vector< vtkImageData* > ) ) ); menu->addAction(taction); for ( std::list< GoFigure::TabDimensionType >::iterator it = dim_list.begin(); it != dim_list.end(); ++it ) { m_TabDimPluginActionMap[*it].push_back(taction); } if ( actionGroup ) { taction->setCheckable(true); actionGroup->addAction(taction); } } } //-------------------------------------------------------------------------- void QGoMainWindow::tobedone(std::vector< vtkImageData * > iImages) { QWidget *w = this->CentralTabWidget->currentWidget(); QGoTabImageViewNDBase *WnD = dynamic_cast< QGoTabImageViewNDBase * >( w ); if ( WnD ) { WnD->SetImage(iImages[0]); } } //-------------------------------------------------------------------------- void QGoMainWindow::ApplyImageFilter() { QAction * taction = qobject_cast< QAction * >( sender() ); QGoImageFilterPluginBase *filter = qobject_cast< QGoImageFilterPluginBase * >( taction->parent() ); QWidget *w = this->CentralTabWidget->currentWidget(); QGoTabImageViewNDBase *WnD = dynamic_cast< QGoTabImageViewNDBase * >( w ); if ( WnD ) { filter->SetInput( WnD->GetImage() ); filter->Update(); // WnD->SetImage( filter->GetOutput()[0] ); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::SetCurrentMultiFile(const QString & fileName) { m_CurrentFile = fileName; this->setWindowModified(false); QString shownName = "Untitled"; if ( !m_CurrentFile.isEmpty() ) { shownName = strippedName(m_CurrentFile); m_RecentMultipleFiles.removeAll(m_CurrentFile); m_RecentMultipleFiles.prepend(m_CurrentFile); UpdateRecentFileActions(m_RecentMultipleFiles, menuMultiple_Files, recentMultipleFileActions); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::SetCurrentDatabaseFile(const QString & fileName) { m_CurrentFile = fileName; this->setWindowModified(false); if ( !m_CurrentFile.isEmpty() ) { this->m_RecentDatabaseFiles.removeAll(m_CurrentFile); this->m_RecentDatabaseFiles.prepend(m_CurrentFile); UpdateRecentFileActions(this->m_RecentDatabaseFiles, menuDatabase_Files, recentDatabaseFileActions); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QString QGoMainWindow::strippedName(const QString & fullFileName) { return QFileInfo(fullFileName).fileName(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::UpdateRecentFileActions(QStringList list, QMenu *menu, QAction *recentFileActions[MaxRecentFiles]) { //if the items in the list are imagingsession names,from // the menuDatabase_Files, they don't corresponds to real //files, the test bellow will then remove //them from the list if ( menu != this->menuDatabase_Files ) { QMutableStringListIterator i(list); while ( i.hasNext() ) { if ( !QFile::exists( i.next() ) ) { i.remove(); } } } if ( !list.isEmpty() ) { menu->setEnabled(true); } for ( int j = 0; j < MaxRecentFiles; ++j ) { if ( j < list.count() ) { QString text = tr("&%1 %2 ") .arg(j + 1) .arg( strippedName(list[j]) ); recentFileActions[j]->setText(text); recentFileActions[j]->setData(list[j]); recentFileActions[j]->setVisible(true); menu->addAction(recentFileActions[j]); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void QGoMainWindow::openRecentSingleFile() { QAction *taction = qobject_cast< QAction * >( sender() ); if ( action ) { this->SetSingleFileName( taction->data().toString() ); } } //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- void QGoMainWindow::openRecentMultipleFile() { QAction *taction = qobject_cast< QAction * >( sender() ); if ( taction ) { // this->SetMultiFileName( taction->data().toString() ); } } //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- void QGoMainWindow::openRecentDatabaseFile() { QAction *taction = qobject_cast< QAction * >( sender() ); if ( taction ) { std::string ImgSessionName = taction->data().toString().toStdString(); this->SetCurrentDatabaseFile( ImgSessionName.c_str() ); this->m_DBWizard->setImgSessionName(ImgSessionName); this->m_DBWizard->restart(); this->m_DBWizard->show(); } } //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- void QGoMainWindow::openRecentFilesfromDB() { this->DisplayFilesfromDB( this->m_CurrentFile.toStdString() ); } //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- void QGoMainWindow::RemoveSetUpDatabaseMenu() { this->menuDatabase->removeAction(this->actionSet_Up_Database); this->m_DatabaseSetUp = true; } //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- void QGoMainWindow::AddSetUpDatabaseMenu() { //enter number of actions in the Database menu here: unsigned int NumberOfActionsIfSetUpDB = 1; unsigned int NumberOfCurrentActions = this->menuDatabase->actions().size(); if ( NumberOfCurrentActions != NumberOfActionsIfSetUpDB ) { actionSet_Up_Database = new QAction( tr("Set Up Database"), this->menuDatabase); this->m_DatabaseSetUp = false; this->menuDatabase->addAction(actionSet_Up_Database); this->actionSet_Up_Database->setEnabled(true); m_DBInitializationWizard = new QGoDBInitializationWizard(this); this->m_DBInitializationWizard->hide(); QObject::connect( this->actionSet_Up_Database, SIGNAL( triggered() ), SLOT( SetUpDatabase() ) ); QObject::connect( this->m_DBInitializationWizard, SIGNAL( DatabaseAndUserCreated() ), this, SLOT( RemoveSetUpDatabaseMenu() ) ); QObject::connect( this->m_DBWizard, SIGNAL( GofigureDatabaseExists() ), this, SLOT( RemoveSetUpDatabaseMenu() ) ); } } //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- void QGoMainWindow::ReadSettings() { QSettings settings; m_RecentSingleFiles = settings.value("RecentSingleFiles").toStringList(); m_RecentMultipleFiles = settings.value("RecentMultipleFiles").toStringList(); m_RecentDatabaseFiles = settings.value("RecentDatabaseFiles").toStringList(); m_DatabaseSetUp = settings.value("DatabaseSetUp").toBool(); this->UpdateRecentFileActions(m_RecentSingleFiles, this->menuSingle_Files, this->recentSingleFileActions); this->UpdateRecentFileActions(m_RecentMultipleFiles, this->menuMultiple_Files, this->recentMultipleFileActions); this->UpdateRecentFileActions(this->m_RecentDatabaseFiles, this->menuDatabase_Files, this->recentDatabaseFileActions); settings.beginGroup("MainWindow"); QSize tsize = settings.value("size").toSize(); if ( tsize.isValid() ) { this->resize(tsize); this->move( settings.value("pos").toPoint() ); } else { this->resize(1450, 750); } //QByteArray state = settings.value("state", QByteArray()).toByteArray(); //this->restoreState(state); // settings.setValue("vsplitterSizes", vSplitter->saveState()); settings.endGroup(); settings.beginGroup("MemoryManagement"); unsigned int maxNumberOfTraces = settings.value("MaxNumberOfTraces").toUInt(); if(maxNumberOfTraces) { this->m_MaxNumberOfTraces = maxNumberOfTraces; } settings.endGroup(); } //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- void QGoMainWindow::WriteSettings() { QSettings settings; settings.setValue("RecentSingleFiles", m_RecentSingleFiles); settings.setValue("RecentMultipleFiles", m_RecentMultipleFiles); settings.setValue("RecentDatabaseFiles", m_RecentDatabaseFiles); settings.beginGroup("MainWindow"); settings.setValue( "size", size() ); settings.setValue( "pos", pos() ); settings.setValue( "state", saveState() ); settings.endGroup(); settings.setValue("DatabaseSetUp", this->m_DatabaseSetUp); settings.beginGroup("MemoryManagement"); settings.setValue("MaxNumberOfTraces", this->m_MaxNumberOfTraces); settings.endGroup(); } //------------------------------------------------------------------------- void QGoMainWindow::on_actionCheck_For_Updates_triggered() { m_ManualUpdate = true; m_NetworkUtilities->CheckForUpdates(); } //------------------------------------------------------------------------- void QGoMainWindow::DisplayUpdateResults(QString result, bool noerror) { if ( !noerror ) // error during the connection to the server { if ( m_ManualUpdate ) { QMessageBox::warning( this, tr("GoFigure2 Updates"), tr("There was an error while trying to GoFigure2's update website!\n " \ "Check your internet connection and try again later!") ); } } else { // no new version! if ( result.compare(tr("no-update\n"), Qt::CaseInsensitive) == 0 ) { if ( m_ManualUpdate ) { QMessageBox::information( this, tr("GoFigure2 Updates"), tr("You have the lastest version!") ); } } else { // there is one new version! if ( result.compare(tr("update\n"), Qt::CaseInsensitive) == 0 ) { QMessageBox msgBox( QMessageBox::Information, tr("GoFigure2 Updates"), tr("There is a new version of GoFigure2 available for download!") ); QPushButton *goButton = msgBox.addButton(tr("Go to GoFigure2's website!"), QMessageBox::ActionRole); QPushButton *notnowButton = msgBox.addButton(tr("Not Now!"), QMessageBox::ActionRole); msgBox.exec(); if ( msgBox.clickedButton() == goButton ) { QUrl address("http://sourceforge.net/projects/gofigure2/files/"); QDesktopServices::openUrl(address); } else { if ( msgBox.clickedButton() == notnowButton ) { msgBox.close(); } } } } } } GoFigure2-v0.9.0/Licenses/0000755000175000017500000000000011667757442015141 5ustar mathieumathieuGoFigure2-v0.9.0/Licenses/Copyright.txt0000644000175000017500000000420011667757442017646 0ustar mathieumathieuDeveloped by Arnaud Gelas, Lydie Souhait, Nicolas Rannou, Kishore Mosaliganti, Evan Schwab, Antonin Perrot-Audet, Alexandre Gouaillard, and Sean Megason. The Megason Lab, Department of Systems Biology, Harvard Medical School. Developed with support from NIH (NHGRI P50HG004071). This software is open source under a "New BSD" style license which allows for free redistribution and modification in both source and binary forms with or without consent from the developers for both non-commercial and commercial uses. The entirety of this license is below. Please click I agree to indicate your acceptance. Copyright (c) 2011, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the President and Fellows of Harvard College nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. GoFigure2-v0.9.0/Licenses/FFmpegCopyright.txt0000755000175000017500000000136611667757442020750 0ustar mathieumathieuFFmpeg http://ffmpeg.org Copyright (c) 2000-2010 Fabrice Bellard, et al. FFmpeg is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. FFmpeg is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with FFmpeg; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA GoFigure2-v0.9.0/Licenses/BioimageXDCopyright.txt0000755000175000017500000000322111667757442021544 0ustar mathieumathieu Program: BioImageXD Module: $RCSfile: vtkLSMReader.h,v $ Language: C++ Date: $Date: 2003/08/22 14:46:02 $ Version: $Revision: 1.39 $ This is an open-source copyright as follows: Copyright (c) 2004-2008 BioImageXD Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. GoFigure2-v0.9.0/Licenses/ITKCopyright.txt0000755000175000017500000000307711667757442020234 0ustar mathieumathieuITK Copyright Notice: Copyright (c) 1999-2003 Insight Software Consortium All rights reserved. License: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Insight Software Consortium nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. GoFigure2-v0.9.0/Licenses/PoissonreconstructionCopyright.txt0000644000175000017500000000671511667757442024240 0ustar mathieumathieu Authors: Michael Kazhdan and Matthew Bolitho at Johns Hopkins University, 2006-10 Copyright (c) 2006-10, Michael Kazhdan and Matthew Bolitho, Johns Hopkins University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- This code has been modified and wrapped to VTK. Here is the corresponding license: Authors: David Doria at Rensselaer Polytechnic Institute and Arnaud Gelas at Harvard Medical School Copyright (c) 2010, David Doria at Rensselaer Polytechnic Institute and Arnaud Gelas at Harvard Medical School, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Rensselaer Polytechnic Institute and of Harvard Medical School nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. GoFigure2-v0.9.0/Licenses/vtkINRIA3DCopyright.txt0000755000175000017500000000366711667757442021370 0ustar mathieumathieuThe vtkINRIA3D copyright is as follows: /*======================================================================== Copyright (c) 2006-2010 INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ See also the vtkINRIA3D web site: http://www-sop.inria.fr/asclepios/software/vtkINRIA3D/ for more information. GoFigure2-v0.9.0/Licenses/CopyrightOxygen.txt0000755000175000017500000004545211667757442021061 0ustar mathieumathieu The copyright of the following icon belongs to the Oxygen Project: (http://www.oxygen-icons.org/) *GoFigure2\Resources\video.png corresponds to mixer-video.png It can be found following this link: http://www.icon-king.com/projects/oxygen/ The Oxygen icons are licensed under the LGPL 2.1: 0.This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of thosefunctions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: 1. The modified work must itself be a software library. 2. You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. 3. You must cause the whole of the work to be licensed at no charge to all thirdparties under the terms of this License. 4. If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. ( For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. ( If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: 1. Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) . 2. Use a suitable shared library mechanism for linking with the Library.A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. 3. Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. 4. If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. 5. Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: 1.Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. 2.Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. No Warranty 15. Because the library is licensed free of charge, there is no warranty for the library, to the extent permitted by applicable law. Except when otherwise stated in writing the copyright holders and/or other parties provide the library "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the library is with you. Should the library prove defective, you assume the cost of all necessary servicing, repair or correction. 16. In no event unless required by applicable law or agreed to in writing will any copyright holder, or any other party who may modify and/or redistribute the library as permitted above, be liable to you for damages, including any general, special, incidental or consequential damages arising out of the use or inability to use the library (including but not limited to loss of data or data being rendered inaccurate or losses sustained by you or third parties or a failure of the library to operate with any other software), even if such holder or other party has been advised of the possibility of such damages.GoFigure2-v0.9.0/Licenses/CopyrightNuvola.txt0000755000175000017500000004571711667757442021060 0ustar mathieumathieu The copyright of the following icons belongs to Mr David Vignoni: *GoFigure2\Resources\ContourEditing.png : pen taken from kedit.png *GoFigure2\Resources\MeshEditing.png : pen taken from kedit.png *GoFigure2\Resources\document-open corresponds to folder-blue.png *GoFigure2\Resources\zoom.png corresponds to viewmag.png They can be found following this link: http://www.icon-king.com/projects/nuvola/ The Nuvola icons are licensed under the LGPL 2.1: 0.This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of thosefunctions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: 1. The modified work must itself be a software library. 2. You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. 3. You must cause the whole of the work to be licensed at no charge to all thirdparties under the terms of this License. 4. If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. ( For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. ( If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: 1. Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) . 2. Use a suitable shared library mechanism for linking with the Library.A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. 3. Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. 4. If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. 5. Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: 1.Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. 2.Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. No Warranty 15. Because the library is licensed free of charge, there is no warranty for the library, to the extent permitted by applicable law. Except when otherwise stated in writing the copyright holders and/or other parties provide the library "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the library is with you. Should the library prove defective, you assume the cost of all necessary servicing, repair or correction. 16. In no event unless required by applicable law or agreed to in writing will any copyright holder, or any other party who may modify and/or redistribute the library as permitted above, be liable to you for damages, including any general, special, incidental or consequential damages arising out of the use or inability to use the library (including but not limited to loss of data or data being rendered inaccurate or losses sustained by you or third parties or a failure of the library to operate with any other software), even if such holder or other party has been advised of the possibility of such damages.GoFigure2-v0.9.0/Licenses/VTKCopyright.txt0000755000175000017500000000301111667757442020235 0ustar mathieumathieuCopyright (c) 1993-2008 Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. GoFigure2-v0.9.0/Licenses/CopyrightCrystal.txt0000755000175000017500000004620211667757442021223 0ustar mathieumathieuThe copyright for the following icons belongs to the Crystal Project: *GoFigure2\Resources\figsystem-quit.png corresponds to Crystal_Clear_action_exit.png in Crystal Project *GoFigure2\Resources\UseDatabase.png: part taken from kexi.png in Crystal project *GoFigure2\Resources\navigation.png corresponds to map-compass.png in Crystal project *GoFigure2\Resources\EyeIcon.png corresponds to layer-novisible-3.png in Crystal project *GoFigure2\Resources\TrackView.png: eye is taken from layer-novisible-3.png in Crystal project They can be found following this link: http://everaldo.com/crystal/ The Crystal Project is released under LGPL: 0.This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of thosefunctions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: 1. The modified work must itself be a software library. 2. You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. 3. You must cause the whole of the work to be licensed at no charge to all thirdparties under the terms of this License. 4. If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. ( For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. ( If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: 1. Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) . 2. Use a suitable shared library mechanism for linking with the Library.A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. 3. Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. 4. If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. 5. Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: 1.Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. 2.Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. No Warranty 15. Because the library is licensed free of charge, there is no warranty for the library, to the extent permitted by applicable law. Except when otherwise stated in writing the copyright holders and/or other parties provide the library "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the library is with you. Should the library prove defective, you assume the cost of all necessary servicing, repair or correction. 16. In no event unless required by applicable law or agreed to in writing will any copyright holder, or any other party who may modify and/or redistribute the library as permitted above, be liable to you for damages, including any general, special, incidental or consequential damages arising out of the use or inability to use the library (including but not limited to loss of data or data being rendered inaccurate or losses sustained by you or third parties or a failure of the library to operate with any other software), even if such holder or other party has been advised of the possibility of such damages. GoFigure2-v0.9.0/Dashboard/0000755000175000017500000000000011667757442015263 5ustar mathieumathieuGoFigure2-v0.9.0/Testing/0000755000175000017500000000000011671141013014761 5ustar mathieumathieuGoFigure2-v0.9.0/Testing/testsGofigure-template.xlsx0000755000175000017500000057211411667757442022411 0ustar mathieumathieuPK!§•ù™„Ý[Content_Types].xml ¢Ù( ÌTÉnÂ0½Wê?D¾VÄ@¥ªª8t9¶HÐ0ñ@,Ûò þ¾“PP©ÒH4zI”Åo›g'ãmYDhœMÅ î‹læ´±ËT¼Ï^z÷"BRV«ÂYHÅPŒG×WÉlç#^m19‘³J…±ó`ùËÂ…R?†¥ô*[©%Èa¿'3g ,õ¨Â£ä j]Pô¼å×{%scEô¸ÿ¯¢J…ò¾0™"*7Vÿ é¹ÅÂd ]¶.:F@į,b 3†)±1r”¼±é`4DèU•Ì ·…$vûë fDÔ`7Êï„H»°3Õ©ß=è¹!Þžgík€1¯¬g€¹ñØÂО]{&.¬æÎ­.JÕ†¸TÆt7•€+4 ΣäÂuU£5èžgHdà˜Y7°ò^×e}vÖpZ#~[ :nÿ‰Žî»òoy`®è)ñI²¼øvýŽÝ6—c73àüöpµº¡‘²>ÓGŸÿÿPK!µU0#õL Î_rels/.rels ¢Ê( Œ’ÏNÃ0 ÆïH¼CäûênH¡¥»LH»!TÀ$îµ£$@÷ö„‚JcÛÑöçÏ?[ÞîæiTb/Nú(A±3b{×jx­ŸV b"giÇŽaWÝÞl_x¤”›b×û¨²‹‹º”ü#b4O ñìr¥‘0QÊahÑ“¨eÜ”å=†¿P-<ÕÁj{ª>ú<ù²·4Mox/æ}b—NŒ@ž;ËvåCf ©ÏÛ¨šBËIƒóœÓÉû"cž&Ú\Oôÿ¶8q"K‰ÐHàó<ߊs@ëë.Ÿh©ø½Î<â§„áMdøaÁÅT_ÿÿPK!Þ ý(Ôxl/_rels/workbook.xml.rels ¢( ¼“ÏjÃ0 Æïƒ½ƒÑ}q’ne”:½ŒA¯[÷&QâÐÄ6–ö'o?“Cº@É.¡ƒ$ü}?Чýá§ïÄjU%)´¥«ZÛ(ø8½><ƒ Ö¶Ò³¨`@‚Cq·ÃNsüD¦õ$¢Š%†Ù襤Ò`¯)qmœÔ.ôšcéuyÖ Ê–ž¤ð Råg§9%ÛÜoËÆc2LÓ $9àbŸxÇ» ®2\U8op‚Œ;“x±7" ŸÐˆØ£ñå;DÐxߣGQ]$BIh’Ô ‚åÇÑ»ÌçµÒíðùZ*vÁ=áÂ&*®îvÒѧF á?Ò2¦Ù¯ÁÅ`4\üý3O³yrÐÍ9ˆ°-rU¸°pD'X~ÊÐYÜ»å Ó8h{w†ýK’ ÇcÌxLÚÞœHïÚÖûï]Å›*$A°>–›¸í…J%›•ŠôaËËACMÒÛʈ÷¼ÆJꟉ&Mœ;žÖ4BÎe— tˆYÛ>c~4$”‡– &Ú^Õü¼ÊÖÕ ÞL1µbma]ßüÒué‚ñtÍðÁ(gZë×[WvrúÀÔ2®×ëu{µœž`ßM­,EšõþF­“Ñ,€ìã2ínµQ­»øýõ%™[N§ÑJe±D È>Ö—ðÕf}{ÍÁÅ7–ðõÎv·ÛtðdñÍ%|ÿJ«Ywñ2O—ÐÚ¡ý~J=‡L8Û-…o|£šÂ(ˆ†<º4‹ ÕªX‹ð}.úÐ@†‘š'd‚}ˆâ.ŽF‚bÍo\˜±C¾\Ò¼ôMTÛû0Á z¯žÿêùSôêù“ã‡ÏŽþtüèÑñÃ--gá.Žƒâ—ß~öç×£?ž~óòñåxYÄÿúÃ'¿üüy92h!Ñ‹/ŸüöìÉ‹¯>ýý»Ç%ðmGEøFD¢[äðt3†q%'#q¾ÃSgv éž à­9fe¸qwW@ñ(^ŸÝwd„b¦h çaä÷8g.J pCó*Xx8‹ƒræbVÄ`|XÆ»‹cǵ½YU3 JÇöÝ8bî3+˜(¤çø”íîQêØuú‚K>QèELKM2¤#'‹vi~™—é ®vl³wu8+Óz‡ºHHÌJ„æ˜ñ:ž)•‘∠~«°LÈÁ\øE\O*ðt@G½1‘²lÍmúœ~C½*uû›G.R(:-£ys^Dîði7ÄQR†Ð8,b?SQŒö¹*ƒïq7Cô;øÇ+Ý}—Çݧ‚;4pDZˆž™ íK(ÔNýhüwŘQ¨Æ6Þã¶· [SYJìž(Á«pÿÁ»ƒgñ>X_ÞxÞÕÝwu×{ëëîª\>kµ]X¨½ºy°}±é’£•Mò„26PsFnJÓ'KØ,Æ}ÔëÌ‘䇦$„Ç´¸;¸@`³ ®>¢*„8»æi"LI%\ÂÙÎ —ÒÖxèÓ•=6ô™ÁÖ‰ÕÛáu=œ r2fË Ìù3c´® œ•Ùú•”(¨ý:ÌjZ¨3s«ÑL©s¸å*ƒ—UƒÁܚЅ è]ÀÊM8¢kÖp6ÁŒŒµÝ휹Åxá"]$C<&©´ÞË>ª'e±b. vJ|¤Ïy§X­À­¥É¾·³8©È®¾‚]æ½7ñRÁ /é¼=‘Ž,.&'‹ÑQÛk5ÖòqÒö&p¬…Ç(¯KÝøaÀݯ„ ûS“Ùdù›­L17 jpSaí¾¤°S!Õ–¡ 3•†‹5'+ÿZÌzQ ØH )Ö7 þ5)ÀŽ®kÉdB|UtvaDÛ”σp|„Fl&0¸_‡*è3¦n'LEÐ/p•¦­m¦Üâœ&]ñËàì8fIˆÓr«S4Ëd 7yœË`Þ ân¥²åίŠIù R¥Æÿ3Uô~×ëcínrF:_Û*äP…’ú}ƒ©-p ÓTpŸlþ r¨ÿÛœ³4LZéOÐ û‘ !ûP–LôB¬–î]–$K ™ˆ*ˆ++öˆ6Ô5°©÷v…ꦚ¤eÀàNÆŸûžfÐ(ÐMN1ßœ’ï½6þéÎÇ&3(åÖaÓÐdöÏE,ÙUíz³<Û{‹Šè‰E›Uϲ˜¶‚Všö¯)Â9·Z[±–4^kd—5†Á¼!JàÒé?°ÿQá3ûqBo¨C~µÁ·M ¢ú’m<.vp“´Á¤IYÓ¦­“¶Z¶Y_p§›ó=al-ÙYü}NcçÍ™ËÎÉÅ‹4vjaÇÖvl¥©Á³'S†&ÙAÆ8Æ|Õ*~xâ£ûàè¸âŸ1%M0Ág%¡õ˜<€ä·ÍÒ­¿ÿÿPK!;m2KÁB#xl/worksheets/_rels/sheet1.xml.rels„ÁŠÂ0E÷þCx{“Ö… CS7"¸UçbúÚÛ—÷ý{³eÀååpÏå6›û<©f‘,Ôº…äch°ð{Ú-¿A±8êÜ -æÙI‰y0Éù‹Ьªjmò_´/Nµï,ä}Wƒ:=RYþìŽ}¢H9ÈEíò€bAëwöžk}¦mÌËóö ÿÿPK!ò/ ¼Xxl/worksheets/sheet2.xml”WMÛ6½èt¯%JþÒÂr°²wÑP4i÷¬È´MD‰»›ä×gHÊ$‡– 7‡x=oæÍpæ,n>|»ÔÁízÆ›<$³8 hSñkNyøÏççßÖaЋ²9”5oh~§}øaûë/›wÞ}íÏ”Šš>ÏB´QÔWgz)ûoiÈ‘w—RÀ×îõmG˃ ºÔQÇËèR²&Ô Ý=üxdÝóêõB¡I:Z—êïϬíÃíæÀ“ :zÌÃÇôáñãŸé2Œ¶•ü_Fß{çï@žå ç_%ðÇ!céÝø>«³üÕz,_kñ7ÿ²ÓY@ã2¤â5ðÂÿÁ…Én†Á¥ü¦>ßÙAœó0ÉfëÕBvô{ Íœ‡AõÚ ~yÑ0Htx2„Ãç5<™‘äÞðt‡Ï!|Þ•êR…ÃçJâÙ½yÁOÃç5øÞÐåJâäÿ¤ŽtßÕ¼ö¥(·›Ž¿ 'yÞ¶”â$)£’ÆGiÍÃe¦š--…¶¬@û0J© ·íj¾‰Þ@Õµ|`¦Öga|"ÈhÒBí#i¥5W0MK°4ª´Bû¤Èg…}vOª4ꦕ]¾=­´ª´RŸê´Ú‚“¬½$CÔmÑHiõÏ–aÊBû ´„`ŸÝÀ½6=ZÇÆ5y5Zˆ´B!Ð#Kà%)8¢ñ¹)dðzŒÏ:/$-¬&rn#õ\pZîhUˆO@ª#cf“umÕ©³bÔJ3ƒÀǘ]ݯ=IÄEoz9…â¼ ù±¼î*¬=•ÄE¼˜Ynîí^$2_¬d–«8Âìª/³ò¦à¢“ÌrÿF˜]Íf¾®á7ÈN’Y®Ø³«ôÌ×+qÑIfw#—æiKÀl4™yb/:Åœ¸š´ÌÒl˜}I"0³k¤w £Þ¢ì1jEÅ>aÔËûŒQ+X$ÉÄ»s WΙ/IdŽKbOW;öıÿoøiÆu»«dêÞ%î*Áo7~ í=Ø“À“ÛQáÔî®9©Ñ6Å7“ÄðÍ(1lg‰S»ËhRï勘3;êA&¶ÓÄÜî::Üxá¼Y?%S0æ]È}â.$qvn¨{ ÆÜòZp}Œ8uƒÙö„X% àÔýõ2ÁÒl‚'f‘Ž? ¤Ù„âI¬ð`+1ý4ÀplWWí*pažo)ÒñXx°§ÀÛS«Êöìk̃'4–ºú5…Òl{–xÛa˜ØÊpS\ý:ÜH ‰íèÐp[TSë‹—~‘oËýXv'ÖôAMPo<[Åø¶Ó·°QLðÞÿgdžºð0ýÂ\½Æ±3\T)\ €q²É—™#çb „·lYó'*^Û -[Ú}b?àªÚ>2ñ™¿è›ÞõëõþßyÇàF«.²yØòNt%apû@½o™âÛº`•ý^ñ–QxëU·V]ø³ª0(kvj^˜8-|"swßþÿÿPK!y+ §xl/worksheets/sheet3.xmlŒR]OÜ0|¯Ôÿ`ù½ù¸rP.‡N§  Ï&Ù$+¯eïõ€_ÏÆ -*5IÖ³žÙÙÝõéÃ`ÕoÉUºÌ ­ÀÕÔ ë*ýëz÷å›V‘kŒ%•~„¨O7Ÿ?­îcÀJ\¬tÏìWyë3òài) †% ]}Ó¤KƒÍEqœžVá8¨m±†-ÕûO$¬a©?öè£Þ¬l4¤´•>+Wgç¥Î7ë¤}ƒpˆ¯þÕhåŽè~~4•.ÆÔü]î.Y¹ ªÖì-ÿ¤ÃwÀ®géÛr¼R“^y«Çfj5˜ù‹#­Øp?Ùrì裕fÊq½LÃí &á‰&Éo !ö¦ƒ :tQYhE°ÈNŠ·Ï‰Va*æCŒÉ‹xV}}}q¡Õ±ð1Ö˸@Æ"ŒË7j¥xk‰ø_à\óðÞ+o<„+|ò]-ò5Í~_—6JLe®iœ•ö8d­z9"ìÖcâ‘e¬ÿÆ5yYÃ4¼©ð]ªP‹»EîçÎ9ùŸ Þ<ÿÿPK!áÉô3Ÿ±'xl/worksheets/sheet1.xmlœ_³7’ÝßáïÀ໥Û}ÿrBÒÆÔ½ýÇ뇽¶Ÿ¹5bŒ$Ê"gf÷ÛïAåIy"i¿èЉ ê‡pºººê»ú·_yõ÷÷|úðñ·ï_¾¹yýêýoï>þøá·¿|ÿúýËù¿<½~õéóÛß~|ûËÇßÞÿúßßzýO?üçÿôÝ?>þñ×O?¿ÿùZøíÓ÷¯þüù÷?}ûí§w?¿ÿõí§o>þþþ7”üôñ_ß~Æ?ÿøË·Ÿ~ÿãýÛ÷J¿þòíñææáÛ_ß~øíµµð§?¾¦?ýôáÝû—ïþöëûß>[#¼ÿåígÿ§Ÿ?üþéõßýøeå„^ýñþ§ï_ÿùð§?ÿ·¾{:¼þö‡ïöÞÿ÷‡÷ÿøÔýÿ«Ïoÿõ¾ÿåý»Ïï„ׯ>üýŸßÿôùùý/¿ þÝãÃëWå|ÿõãÇ¿–ºÿªtôi¯S:zûî󇿿7ýõîéÐþïÞùþôûmí¸ÿ?ˆóNé¿ÿñêÇ÷?½ýÛ/ŸÿÇÇ\ßøËÏŸq4÷å°ß}üZü÷Õ¯Ê8½~õëÛÛÿþãßþþ5ŽðÓçÿ#ôæñõ«wûôùã¯ÿÇŠöó®U¬Š¿¬z¼ûæ¾ÖFˋʷ¬Œ¿¬|¸ûæØÕ¾Y×—ý¸ñ×;Ó×G|Ñ;úÙkã/kß¾yzlݯ«Ñ^½ &ÉÜtg¾® ¨{eüõÊß¼óôÈ¿µ”ÙÓîåíç·?|÷ÇǼÂÃ}úým™±‡?ápJŽHæw¥ð¥”~ÿdžp™KÿáðtÿÝ·GÖ¾£ædLÓ«æ[ôS;éig‡ûoÊ}þùû¿nK†—çÁ(rpwÇ]o„꬈ ðÈþ\ªc`„Û¡½¹©‡¶Ÿâf¢r~Š¢x‡ØÆË¨8FÅiTÜFÅÙý±ÞEÅelC†â:*ja 0Z ö¶,a;’?—Rp{²¯-/+DâW^m°wų) æ)¶òÂ.:Å›¨8y+ä #söVÊ’XòõÂJ¶Æ•ÈÕ"Èìz¸‡»/@)+‡fÛ}…RJ+ÞÍ ý+Jn0FõP” 58æ*9HW'jð§i4—j; #ûa¤?œÃ±uÒY©dºt)¥•ŒÊf…K2”,ÉPÈÈü8QÈÈ 9×v*F:2ŒÜV’~¡”V rl›.1P²Ä@MÀвyŸ'jIÆsm§b"WFF ˜L ¥´bü›.1P²Ä@MÀ séDÍCm§b`¤ËFF ؉v2_CKiÅ C´Yá%K Ô ºŒRÓc8ê2ZÛ©é00–‹/-¤|lP4·7Ã>ï¨vye%©º±ô€t¬ žhž]sÓ£„xqΤ6t”üDÑgPEÉâsk©ózÝÎ㪧a9LLWÏç_>þ^|Påc‹û±œÖ¶7Ó¶Ú{¨9Ü„4h‹ý¾p¼xK=DM'×ô Û²‹îênsñP—Q )ulûGXzË\Ñ”ºk³m/®)$½±t9ß\&\·Q9 ŒMhØ¡½©À¨×ÞÒÙE=#6Þ3b(2j›Kd•2ê¶éC)®ŒtÐ6¯!Y‡UR;fÛ¥¼»i˜hµ¥6Ñê!14.ÑeœVDJq#"kÁ¶×Æ`c êZ0¬<ÖDF„*ü©-dS8ywˆôwvQŸ6l¼'ÂЄZ_)ň¬®>ìé¿$BM’#T"²´¼;h¶Hm©åC=†&DŠÝÛßÏsƒþaH¦ñv Y\¡&!BUO¤[ 9k(ê‰ejý˜úa½žC"Åù ‘ÎÙ”¸Ëé}cñzÖÐ[&D¨ê‰dm?ywˆõDØxO„!,'-ݺ!ˆ‹mñ…©ßÃy-£îáf#=d¡Ût™8‚Úµ$ú³k‚Éw(¶´v9&J\Nm©M,Öë]U—S,ズs˜NHVÇí`Åk›c±9ÂúÅ[êÓjÈ*öÖg•î˜çÖPÄz}V1³ªTȪ2"ʬ³9{q[ž%C6/§žkâÔk‡c>ÇU=£Áç¸(@’òì¢nêy¨ƒä¡©å@„4µÏÕ.ãòe¿>ɦ²±x Éš]}€DU€$ËáÉ» ¤¥³‹zHl¼‡Äиb—Y¡iÓía{qKIöÅk"¥x¡$m¨ DÚ(ÚæÝ"’ÊgõDØxO„¡ ‘⠇ŧåH)®Dôñv´â5j"T"’’'ïnM¤¶TW¯×¡jB‡°"RŠõÂåˆ2þþÅ Ê5 ¶„?µ¥n“eŽPÔ|Ž÷×çëõDšAëJ¤ó9û·9ˆza¯‰”òYCUOdð9Þ] ¢>ÇE=6Þa©RGàplkR\l‹M&Ò¯åÍUr×qÝX\üXíZ¦þ³k¢Ïi‡ÇŠö»kmi¸šÃ¦ÊîREÃÕïïM»Záõ:ŸãªÑç‹mTB·‹o©Äøìõ[žÉ²±¸,ˆõdt®ñúŽ,¼/ÞRŸg²œ\ÒLº;»¨O3;PòÕéꪘfmí‹iVl¤@ì碹LO+I†íHºdDM\FTõŒŽí˜¹:Q ɳS‰õzH EH­­©XIt»]¯_‡úÇŽ£™Oç&g»±x½†Y²óKK/ÞRÏíp7€c[=¸Ûa£¨ÇPŽ¡®uÀÁ à:[½·(é¾±xIÉ5ëìrU¤$ý\ÕS:ܵœØ“ð쪓‡:Lw¿Ûâ&%™Þ´ï€÷âÆ¤Ý{ßX¼fb~õMGM6ô–è;±'ªû}ãð¤™ÓÚòEèâ÷e{?ô«‡@uA=ܵe7fNq˜¥/n·Eިɘm,^n®‰Û߀Í:*A»“rb[qÿ»ÓhÞc·zÅnt¬®Ç¶Gl˜–Š wç”L(7zp w}ø’u[ªV„º:l,¾íC&Ð35‡x„v¬÷’./”Ý…Ô»RÏŽçÉܵ%¤Ï­­–z¬xl[¢üN:Ã’ÐÜÖu» >ÒîÏéöÅÛR­Á’cßXÜÏš[Ñ=V‘î~guVn ]½¿ñÂÙn@t3Þ^}c$ƒ¸íÍ¡¸?æÃ½Ø¨gª7Ø+꩞d)}ñÆbU%©|rMȇ'Y¦Î®ê>§¡«‡0k‡7ícn!™p·_õñ —=zˆ’›ˆræÏT¥Ù×"5¢txöÃê!²b ]] >µE9B,öP&è’B?3„O¬5Í[r‘ÓOÔÛ?áÛhŽ©HƒzÓOEmëÅÛê'uwµÂ<²‹ú¤¾qvQ÷9 ]=´¯…‘X±¨Bìö¸ü uWª´)«þ™Å‡§>C&sÖZ‰²U§L컌W’ô3ÎÙUí²Ñe ]=4~œ/‰¤¨Ê¤ÉUó©è'¹movûißíÖ$öRc7õC≱²Ÿ·\|j+ËÞÚÙUíbÅe á×kûaÙÚºm“5¦ TÊàÎVwÅ0½tWê7&2‹øu ~žÄ^j¬mS'ÆÊŸî<$;Ï®ê]æˆ÷yuUp!Lî‘ʤ|ù?"_í•Ùh6—kLí¤†E‡ªC¹;¹Êo«_À†«ù.Â2ÖZ’Ô=»è±»Œ¡«‡ö±ŒÄ@çkˆùLº/ú©-þöÁ•Åáòá¸àP/ ެ«òá¡› ¶2³©0ý†•ÙEÝìCW†0û|Rqº2ù†ûû"oŒä7ãVÏkÂÈ9”Û¸«lddª²3W‘^ˆ=y‡}"éuØsùÔ»Œ¡«‡&‰„ÓQF_?õJåJLO`»·â8õ×DUœz‡ÇöbϘo¬Gvx”û䪞٘W<®~ò ¡«75a6qè3fuò‡®C¸Ý[qœ|#&SÅÉ7Ád²0ûâgOì2™~lªŸ~CèêG?™~*M­Åg½û"oÉ$‡¼±8N¿‘’5§ß„’ÉÂü;<ʇ¢“wÙ'ÓáQ÷æj3Íwû¡«&Ù„æÓc÷qO·»"o˜ä˜·{+ŽsnÜîL%sî^Ní…CW—©Ã½ìe'Wõ.[{<ûqõsއÚBWWM(+kyOIn,¾7×ËO"zb‹c2é1?S%ɤ½xc8Ž’x‡“«‚¹º—øìª–9—1tõfc×cÛ°â.81ÝÝ.¨ù<·övO¯‹õ²u=NCSÅüº—)ý¶$½ÄÑž\…&k:Tg?¬–K—1tõÐ$½Šƒ•ôê!iz™áõô’CÞîé‡H¦Šé5Bb[!»dwSR§œé÷¯»Ð•ªYê;:`ùâíòæ^¹0é•ðÅ1uFLÖHLãL6rg‚É+Ÿ:j†%§ÏÞVŸ=¬ØBWWM²gbÄ×øƒ×kÜ‹‹§­Ç¬ßvð™ªC¹‘º"À—ÌQöâ²ò‹Ë*;êÓNUÖ=êÏ"Ï.ãÓ]÷GNb×Ûwĸ s:Ì¼ÆÆ¼«³‘ÓÙÊ#m1Éã}#S¥l( w«õç»'öy(?”ëʰ]†Í´íŒ=t±kÕ7š•›=VlÌÆ:Y_·½vÎÆIÙP&l¤ÏûLÙ°µŽÃÅ«v±kMØ+ºÈ›R\72]T·G+–¼‘!|¦*ec„,ä'o-˶Öq¸xÕ.v­± ›âe… ®xVãcV×óFöҭ܇4Ω©R6” éóÄ>Ó¼ak‡‹Wíb×Ù”ì-ØìÅ-odÝXœä U— éóTeHŒÅz㲎Ãe»ÖØ„ÍÄ@wySv nN©9dqÆÆIÙP&l¤ÏûÌòÆe {èbת›°™çž¹MÎ)ý…çV äsŠª”5&ëþâðä­ÅõFñtvYÇá2‰]kl¦xÈ/¯7¸û¯Ë½…ocqi¿¦7îŒÆå™ª”õ¥lÄ-¼µÈfð7. lØC»VÝ„ÍÄ2÷y,²:—mÿ°‡l¬‘” eqNé=¤'ö™Î)¶Öq¸xÕ.v­± ›‰/îÙ_¬±•»”¿bN™*eC™°¿ybŸ)¶Öq¸xÕ.v­± ›bsÊœ¤¯7rœÛ“gsŠv4ùÌÀÆtN©÷«²°Oë ;í8\¼j»ÖØ„M± 6æ.çödÅZÔŒ e’7êýØgš7l­ãpñª]ìZc6Å>.ؘ»t6rœÛ“glL•Î)Ê„z?ö™²ak‡‹Wíb×›°)öqÁÆÜ¥³‘ãÜž¬8cC‹šå eÂfð~.ÃÉ×ÍqüÎC;t.“صÆF6å.ÿ›½¸úâî·)û·‹6Teyã2a£Þ¯Ê›a½qYÏf»ÖØ„M±Š_Λ7æ$=oä87glhG“¼ac²ëE¬S•6ƒ¿qY`3ñÅU7aSÌè‚yU²^bòÆŠ36¦J󆲘7Ã3YØg¶Þ¸,°a]ìZu6k_¼¿;§Î©îGsœSf436´£YÞP&lÔóR6l­ãpñª]ìZc6Å>.òÆÜ¥ççöÆŠ36´¨Ê„¸ìû6ãzÃÖ:¯ÚÅ®56aS죰ÁÐ~ý¦<˜¨}#ǹ±8cC‹š±¡L؈ß<±Oa3Ü×ﲎÃe»ÖØ„M± 6æ.=oä8·òN¥ü3UézC'+lÄS¼µøYsdÃÖ›1võæðXe\W×ÒË;ÓVlÌ]:õÅ{íô³&U)›©/ÖŸÙœ¼µŒÍÄ{Վ׵Æ&lŠ}\äM)nk±Œáf_“7¦JÙP&y£Þ}Êœ÷p¶Öq¸xÕ.v­± ›â2lÌ„¢ò"µ7ê‹ßX±¬7²b?S•²qËo†W"wòÖbÞŒlØZÇáâU»ØµÆF6‡›‰1îc+o™#£¸yy‚ÇeŸª‹É3ÜO×tHr TuŽË,xmÁ¤‰C‚E~£ùP^¸8®ËšC.Ë!Ñà $¹+/Íq]‰ºi ’gŠ{üò4ÛŸdÖÖ ðŽ—@‘Jf?%•dÿÇK…èR“­½ê„’P%¶—L¶ª‹”X¹ ‚’g”Š·JÝEÁýÙ*=%TP2sšR¢‡M)Q'”„:(¹.Ë%ê: ˜pc”<8£T\抒¹P®Ù>ä’ RJt³)%ê„’ø/Pr]F‰ºHi ‚’g”&F:äRpÒ>P2AJ‰.9¥DP'J®Ë(Q)APòàŒRq™«\2ZsI3Î)%ºÙ”uBI<(¹.£D]¤4AɃ3JŃ®(™G­”dPAÉ)%“å{uBIÜ(¹.£D]¤4AɃ3JèeI©”W·àÃŒ3AJÉd9%ê„’¸4Prþ.íu‘Ò%Î(_ºÊ%ó­5—dP‘K&H)Ñÿ¦3Ž:¡$6 ”\—Q¢.Rƒ äÁ ¥ýE„ J|Qa¥$ƒŠ7 ëž~¢uYšKlN®½êï]Nµ½Ì/y{Ò$x­-N>óï÷µ¯r‰¯+¬”dPAÉ,k–K”å”è€c.éoy@Éu!—Ĩœ«.Rr›Ýn®%Îr©8ÎU.™#uJúÎ$P2AJ‰Î6›qlNsI (±½˜KJÔEJc”<8£T犒9ÒJiðÞ|;bJ‰Î6¥Dä’Pr]–KÔEJc”<8£T犒9ÒJIR¹d‚”mJ‰:¡$”\)ÉŒG]¤4AɃ3JÅq®(™#­”$õAÉ)%:Û”uBI¶VPr]¤$› (Q)APòàŒRqœ+JæH+%I}P2AJ‰Î6¥DP’M”\—Q¢.Rƒ äÁ¥â8W”Ì‘VJ’ú d‚”mJ‰ºHIJ®Ë(Q)APòàŒzYR*åÍ{ë‹\AÉ)%“åN€:¡$›(¹›÷ÖŸ‹`ÆQ)APòàŒRqœ’Ký¥J¾±æ’, d–5¥Dg›æuBI–CPr] 4^Ðu]¤ÄÊ]”<8¡´¿ØpA‰/>¬”dyÄ««¿Î{S–æ’ë„’,‡'ï6ûÒ¤ê: —YðÚ‚3JÅq®(™#­”d%d¹DYN‰X(ÉrJ®KrÉu‘+wAPòàŒRqœ+JæHÒðVÃ_ª˜R¢³Ífœ¿£Q(‰%¶½÷8ã\×A.±r%Î(ǹ¢dŽ´R’e¹d¡$æóÙey.Ñ %YAÉuY.Q×¥1JœQ*ŽsEÉi¥$§J&H)ÑÙ¦¹DP’å”\—Q¢.Rƒ äÁ¥â8W”Ì‘VJ²Ù€’ RJt¶)%ê„’,‡ äºŒu‘Ò%Î(ǹ¢dŽ´R’Í”L ”&fmJ‰ºHIKJ®Ë(Q)APòàŒRqœB©ÿ¥mç*»÷qÚmlû%ޝ¸ Çvòu‰X(ÉrJ® ”ô窋”X¹ ‚’g”ÐË’R)oÞ[_'‡\2AšK&Ë)Q'”$7AÉuøÛ¼·þl”¨ë€`õƒ äÁ¥â8W¹dŽ´Î8Ùl@É)%:ÛtÆQ'”F¿ä:üí(‰c%ê"¥1JœPÚß}¸ ´—w¹$›Ív  £DYšK®J28'ïvÏ€Fi¸A²ê%ï¤ ^›rF©8Î%s¤5—d³%¤”èl³\bsû*ÑÎ^ï”%¶WæI§“Ã;W]ä2 ‚[ħ^½#ï±K(™#uJú#BP2AJ‰Î6¥D]Ì%½/”\(é=Ò D]¤4AɃ3JÅq®rÉi¥$› (™ ¥Dg›R¢N(‰™%×…uIï%ê"¥1JœQ*ŽsEÉi¥$‡ J&H)ÑÙ¦”¨JbÓ@Éu!—&ëu‘Ò%Î(ǹ¢dŽ´R’-”LR¢³M)Q'”†=ŽÝÊêýfØã\)±“.JœQ*ŽsEÉi¥$ƒ J&H)ÑÙ¦”¨Jãçº8ãd ÆŒ£®‚Õ{ ‚’g”Šã\Q2GZ)É ‚’ RJt¶)%ê„’ì]˜q®ëgÜ­ÞÐJÔEJc”<8£„^–”JyóKÝ“’ù ¥<Ïê+>¡P–û%k.:ÛÙ4@ÉuøÛœÀd]¢.Rƒ äÁ¥â8W¹dŽ´æ’¤>rÉi.™,§D]È¥[½Q”\×SºÕ[õKÔEJc”<8¡´¿QqA‰o\¬”dâoxžÔWåe)%× %YOÞíþ¹¢æÒí,çª ”¼“.xmÊ¥â8W”Ì‘VJ²@€’ ²\¢,§D,”dï%×Å\’T%ê: —Y”\9£T犒9R§¤?â%¤”èl³Õ›Íéº$) Jl/~B×%×EJ¬ÜAɃ3JÅq ¥þû¸òìØnõÖŸs‚’ RJt¶)%ê$—$…AÉu}.?Í®ºr‰•» (ypF©8Î%s¤5—ïÍ5¦”èlSJÔEJzÛ(¹.£D]”Æ (ypF©8Î%s¤•Òདx_ã(Ë×%:`¡48o/θñ›&×EJì¤ ‚’g”Šã\Q2GZ)Éfƒg‚4—èlÓ\¢N(I #—\—åuäÒ%Î(ǹ¢dŽ´R’­”LR¢³M)Q'”$…AÉup9Í d±ÇQ)APòàŒÆbI©”7ï}'[2(™ ¥d²|ÆQ'”dp@Éu%ê"¥1JœQ*Žs•KæHk.‰!%¤”L–S¢N(Éà€’ëðw™KÔEJc”<8¡TÞ[±¢´—w¹$Æe;PQ¢,¥ä:¡$ƒsònã•“ÛƒÞ¹ê%ï¤ ^›rF©8ÎE.ñm‹5—ĸ€’YÖ”m¶.±9q•Ãû̽[ù„¢7{€’;êvk÷e%WÎ(ǹ¢dŽÔ)éïgAÉ)%:Û”u’K28È%×…7¡D]—6 4AɃ3JÅq®(™#­”ĸ€’ RJt¶)%êRJ®Ë(Q)APòàŒRqœ¥/>üÀ.Vjbd@Í,lyj`]UÇ':»l¿BØéd'i:¬ŸUw;™tÎåû¢¦;Ê bºÃî^¸= ‚•¸;oøæiŸâ‚š¼lo-嶺ëÛ@ÍåõègÔè|Ëê;* P£.< ûvxvÓÁ+¶öFoîíánïú¼çZ¹ ‚{ÆÏ#µâHjõÑ/¾±æ–$(™¥•))øì²ýºj;« %:ä8#õì±n¹.¨µ§:äuqFŽAPòàlFGº¢d޵RûJ&H)™,§DP’Á%×e”¨‹”Æ (ypF©8Ò%s¬•’Ø?P2P’OÈ%“唨J28 ä:ü]æu‘Ò%Î(G*”úû›ø¶ÅJIì(™¥M)™,§DP’Á%×e”¨‹”Æ (ypB D–”öònõó»(È(Q–RrP’Á9y·Ñ›O®Òy{Ò$x­-Îî¶Ø_“¸È%¾F±æ’Ø?P2K›R¢óÍö86'Þü(ƒJl/»þäºH‰•» (yp–KÅ‘®(™cuJú[P2AJ‰Î7¥Dä’ (¹.™q®ë€\jå.JlqšKÅ‘®(™c­”ÄÆ’ RJ&Ëgu‘’Þ0J®Ë(Q×¥1JœåRq +JæP+%1B d‚”nšKÔ %Pr]F‰ºHi ‚’g”Šã\Q2GZ)ÉJ&H)ÑÙ¦”¨J28 äºŒu‘Ò%Î(ǹ¢dŽ´R{J&H)ÑÙ¦”¨J28 äºŒu‘Ò%Î(ǹ¢dŽ´R{J&H)ÑÙ¦”¨J28 äº@iü%½ë"%Vî‚ äÁ%ô²¤TÊ›_Ò·ê’ RJ&ËWoê„’ (¹›÷žP¢®‚Õ{ ‚’g”Šã\å’9ÒšKbï@É)%:Û4—¨Jƒ÷f·â*'”Ø^¤4AɃJû”øFÄJIìÝv  £DYšK®J28'ïV) ÍsÕJÞI¼6åŒRqœ+JæH+%±w d‚”m–KlN¼÷­ (±½è½õ’ D]ä2 ‚’+g”Šã\Q2Gê”ô'í d‚”mJ‰:É%Pr]\—„&(Q)APòàŒRqœ+JæH+%±w d‚”mJ‰ºHIo%×e”¨‹”Æ (ypF©8Î%s¤•’Ø;P2AJ‰Î6¥DP’Á%×Jãó\)±r%Î(Ç)”pw†?ÌïEEysbï@É)%:Û”uBI”\( ­®ºÖ%Vî‚ äÁ¥â8W”Ì‘Ö\{J&H)ÑÙ¦”¨J28 äºŒuPƒ äÁ¥â8W”Ì‘VJbï@É)%:Û”uBI”\—Q¢.Rƒ äÁ%ô²¤TÊ»'†”LR2Yî—¨J28 ä:ümÞ{üÅu‘+wAPòàŒRqœ«\2GZsIì(™@(É:ò천°P’Á%×e”¨ë€`ÆAPòà„Òþ¶Ä%¾M±RC²(È(ù[³ç:¡$ƒsònÅ{¹äíJ“൶8»V¹¿7qEÉi¥$ö”LR¢³M)Q'”dp@ÉuI.¹.Rbå.JœåRqœ+JæH’þð”L ”dOzvY:ãØœ|Bžµ_Û‹ŸP&¹äŽº¿sÇ;‰”\9£T§PÂ1Õ/ñ]‹•’Ø;P2ËšR¢³Ms‰º˜KzÃrÉuY.Q×¹ÔÊ]¹äÊ¥â8W”Ì‘VJ²,ƒ’ RJt¶)%ê„’ (¹.£D]”Æ (ypF©8Î%s¤•’L%P2AJ‰Î6¥DP’Á%×e”¨‹”Æ (ypF©8Î%s¤•’Ø;P2AJ‰Î6¥DP’Á%×e”¨‹”Æ (ypF©8Î%s¤•’Ø;P2AJ‰Î6¥DP’Á%×e”¨‹”Æ (ypF ½,)•ò潟ÄÞ’ RJ&Ë÷8ê„’ (¹WÞÛu‘+wAPòàŒRqœ«\2GZsIì(™ ¥Dg›æuBI”\—Q¢®‚Õ{ ‚’'”ö72.(ñ•’Ø»í@AFÉßü˜QrP’Á9y·©÷öö¥IðZ[œyïýÝŒ+JæH+¥Á{óåŽ)%:Û”uBI”\riüÅu‘+wAPòà,—Šã\Q2Gê”ô$È%¤”èlSJÔ %Pr]F‰ºÈ¥Vî‚ äÊ¥â8W”Ì‘VJbï@É)%:Û”u‘’ÞJ®Ë(Q×¥1JœQ*ŽsEÉi¥$ö”LR¢³M)Q'”dp@Éu‘’¬ò窋”X¹ ‚’g”Šã\Q2GZ)‰½%¤”èlSJÔJLJqõv]¤$ë(Q×A.APòàŒRqœ+JæH+%±w d‚”mJ‰:¡4®K®Ë(Q)APòàŒRqœ+JæH+%±w d‚”mJ‰ºHI¿,ÅŒs]F‰ºHi ‚’g”ÐË’R)oÞ[íJ&H)™,õÞlN®/éJl/^_¿s]¤ÄÊ]”<8£T§äRÿ}߉&ÊÛ.\ßPDAJ‰Î6Í%êB.Ý>ÈrJ®Ã¹­>¡¸®‚u‰•» (yp¤tLÞziå].Éò¸¹ ¡ä²,—ªN(Érxjº5¥ªë€\fÁk Î(Çùå\:òm5—d%³¬)%:Û$—¼9q²‚Û‹3n¸¢[u‘+wAPòàŒRqœ+JæHI Àeƿ.Ës‰XrI|(¹.Ë%ê: È¥1JœQ*ŽsEÉi¥$ö¹dÉ%1ŸÏ.Ë)Ñ %YAÉu%ê"¥1JœQ*ŽsEÉi¥$§J&H)ÑÙ¦3Ž:¡$Ë!(¹.£D]¤4AɃ3JÅq®(™#­”d³%¤”èlSJÔ %YAÉu%ê"¥1JœQ*ŽsEÉi¥$› (™@( LÌ8:Û”uÒQ¿%×e”¨‹”Æ (ypF©8N¡Ô}wäÛ +%Ùl@É,kJ‰Î6¥D] t;xoï6» Wu‘;é‚ äÁ%ŒÅ’R)¯~ À‡=Î)%“å«7uBI6 ä’ëðwá*«®‚=Ž•» (ypF©8ÎU.™#­¹$› rÉ)%:Û4—¨J²i€’ë2JÔu@@i ‚’'”öW@.(ñ‘•’l6Û‘‚Œ’¿j2£ä:¡$ëÜÉ»Mgœ·(M‚×Úâäº÷qÛ㊒9ÒJI6P2AJ‰Î6¥DP’M”\—ä’ë"%Vî‚ äÁY.ǹ¢dŽÔ)éÜ@É)%:Û”uBI6 Pr]F‰ºÈ¥Vî‚ äÊ¥â8W”Ì‘VJ²Œ‚’ RJt¶)%ê„’l äºŒuPƒ äÁ¥â8W”Ì‘VJ²Œ‚’ RJt¶)%ê„’l äºŒu‘Ò%Î(ǹ¢dŽ´R’e”LR¢³M)Q'”dÓ%×Jzµî\u‘+wAPòàŒRqœ+JæH+%YFAÉ)%:Û”uBI6 Pr]F‰ºfÜ%Î(ǹ¢dŽ´R’e”LR¢³M)Q)ŸPØ­8I.±½Hi ‚’g”0KJ¥¼yïá½—GØ‹"H)™,õÞlN®Â=ɦ\b{ñ*œþ3ŽºHi ‚’g”Šã\å’9ÒšK²Œ"—LR¢³Ms‰:É%Ù4@Éu8·ú e|þwÕEJ¬ÜAɃJû{&”øÊJI–ÑíHAF‰²4—\'”dÓ8y·òt½áùßU׹̂לQ*ŽsEÉi¥$Ë((™ ¥Dg›å’¿}R(ɦJl/̸ÛIõsÕEJ¬ÜAɃ3JÅq®(™#uJú?P2AJ‰Î6¥DP’M”\×ϸãðüïªë€ —X¹ ‚’g”ŠãJÝ÷qxVÊÛê­«Û\R¢³M)Q'”ïío© ¹4>Yȯ¼¹¹>n%öŒU\Ÿ wÜßö¸¢dŽ´æ’,£ d‚”mJ‰:¡$3 ¹äºKã7M®‹”X¹ ‚’g”Šã\Q2GZ)É2 J&H)ÑÙ¦”¨J²i€’ë2JÔu@0ãÆ (ypF©8Î%s¤•’,£ d‚”mJ‰:¡$›(¹.£D]¤4AɃ3JÅq®(™#­”d%¤”èlSJÔEJz£"(¹.£D]¤4AɃ3JèeI©”w«·,£ d‚”’Ér¿DP¼7»•O(“u‰íEJc”<8£Tç*—Ì‘Ö\’e”LR¢³Ms‰:¡$›rÉu8·ê½g{u‘Ò%N(í¯€\Pâ+"+%YF·#%ÕdFÉuBI6“wsi|þwÕJÞI¼6åŒRqœ+JæH+%YFAÉ)%:Û”uBI6 Pr]’K®ë€\jå.Jlqæ—ö·=®(™#uJú;P2AJ‰Î6¥D]JÉu%ê:  4AɃ³\*ŽsEÉi¥$Ë((™ ¥Dg›R¢.¥äºŒu‘Ò%Î(Ç9Púâó¿|;d¥&Ë*¨™…-¿ï¬«*~í¿~vÙþV·ªÃÕ‹¨{iºðüï7ã ¤s.ó¦¶w«¨Îµ=\'iŸXê+/[ÔØ"®R ŸXʳÞWÔäùßÇ]ߜ­à5³´åÖõèÇç»Lœ‚~¸5:äâ”k{·oÄÆaÝr¼bÕG§àºîQߘ‘¬ÜA̓ãó¿ûÛ ‡\«¿~¶òŽ’ 2(™¥•))ˆÜ¢ó3rB‰:™‘bã@ÉuÙŒ¤.ÎÈ1JœÍÈâHW”̱Ö(ƒ J&H)Ñù¦”¨Jbã@Éu%ê"¥1JœQB/KJ¥¼Ë%TP2P’‰‰\2Y>ã¨Jbã@Éuø»œqÔEJc”<8£T©äRßYsI”ÌÒ¦”è|Ó\¢N(ɪJ® ”žd¦c5§.Rƒ äÁ ¥ý‘ J|…d¥$ƒº)È(ù«(3J® ”îôÖá“w½ùñI–ÍsÕJÞI¼6åŒRq¤+JæX+%TP2AJÉdéŒó·S %±q Äöʧ³6ãôÇÙ D]ä2 ‚’+g”Š#]Q2Çê”ô1w d‚”ošKÔ %™I äº0ãÆë⮋”X¹ ‚’g”Š#]Q2ÇZ)É ‚’ RJ&Ës‰:¡$»(¹.Pz’TG.Q×A.APòàŒÒÄ›÷«7ßY)É ‚½8F¢fþÄ‹û['Ó\rGŒ}¹¶ww#ë (¹.Pz#ƒJÔEJc”<8£Tç*—Ì‘VJ2¨ d‚4—èlSJÔI.‰M%×…ué(Q)APòàŒRqœ+JæH+%TP2AJ‰Î6¥DP›J® ¹4Y—¨‹”Æ (ypF©8Î%s¤•’ *(™ ¥d²|]¢N(‰M%×Jú#Häu‘Ò%Î(¡—%¥RÞ¼÷ð^Ìã×½Óe9%ë/Þ“rw#6 ”\gœè@‰ºHi ‚’g”Šã\åR)ï(É "—Læ’ÉrJÔI.ÉÞJ®Ã¹ÕUþVÝ'(Q)APòà„ÒþŠÈ%¾B²Î8¬íHAFÉ_E™­K®‹”ôÖá“w+Þ{\—¼½@i¼ÖgW|÷·A®(™#­”dPAÉ)%:Û”uBIvxPr]Ì¥as]¤ÄÊ]”<8Ë¥â8W”Ì‘:%}Ì(™ ¥d²tÆùÛ)…’Ø4Pb{áÊíx“ë: —Z¹ ‚[œæRqœ+JæH+%TP2AJ‰Î6Í%ê„’ä(¹.æ’,›çªë€€+wAPòà,—Šã\Q2GZ)É ‚’ RJt¶)%ê„’Ø4Pr]O ß&Åëê D]”Æ (ypF©8N¡êϳ<òm•’ *(™eM)ÑÙ¦”¨JbÓ@ÉuÒðü懲”X¹ ‚’g”Šã\Q2GZ)É ‚’ RJt¶)%ê„Òà½ý-•ñ.° %¶×A.APòàŒRqœ+JæH+%TP2AJ‰Î6¥DP’õ¹äº,—¨‹”Æ (ypF ½,)•òæ*ïePAÉ)%“å{uBIl(¹««<Žß4¹.Rbå.JœQ*Žs•KæHk.É ‚’ „’,òÏ.Ë)Ñ %±i äºŒu̸1JœPµ¤%¥½¼Ë%ÔíHAF‰²”’ë"%ýÞîäÝŠ÷sÉÛ ”&Ákmqæ—ö·=.r‰oƒ¬¹$ƒ JfYSJt¶ÙºäoŸJ²ÃƒÛ‹«÷„’;êþ^¯Ü¡%WÎr©8Î%s¤NIsJ&Jbž]–ç°P’ J®Kfœë: —Z¹ ‚[œæRqœB YýßY)É ‚’YÖ”mšKÔ %¡J® ”Æïã\×%Vî‚ äÁY.ǹ¢dŽ´R’A%¤”èlSJÔ %±i äºHItçªë€€+wAPòàŒRqœ+JæH+%TP2AJ‰Î6¥DP›J®ÃÎÔœÀø}œë:  ÄÊ]”<8£T犒9ÒJI ”LR¢³M)Q'”Ħ’ëB.Ÿã\×%Vî‚ äÁ¥â8W”Ì‘VJ2¨ d‚”mJ‰:¡$6 ”\(ßǹ®J¬ÜAɃ3JèeI©”7¿¤?v%¤”L–ïqÔ %±i ä:üm3nü>ÎuPbå.JœQ*Žs•KæHk.É ‚’ RJ&Ë)Q'”Ħ’ëð·£$Ë&Voê:  4AɃJû+ ”øŠÈJIu;RQòWMf3Îu‘’Þ:|ònÅ{ë’·(M‚×ÚâÌ/ío{\Q2GZ)É ‚’ RJt¶)%ê„’Ø4Pr]œq²ÊŸ«.Rbå.JœåRqœ+JæH’>N ”LR¢³M)Q'”Ħ’ë⌓T%ê: —Y”\9£T犒9ÒJI”LR¢³M)Q'”d½%×õ¹4ù>Îu‘+wAPòàŒRqœ+JæH+%TP2AJ‰Î6¥DP›J®ë)M®{»®‚\bå.JœQ*ŽsEÉi¥$ƒ J&H)ÑÙ¦”¨JbÓ@Éu=¥Éó\×%Vî‚ äÁ¥â8W”Ì‘VJ2¨ d‚”mJ‰:¡$«2(¹®_—&ßǹ®J¬ÜAɃ3JÅq®(™#­”dPAÉ)%:Û”uBIl(¹.æ’è°zS×¥1JœQB/KJ¥¼yïGTP2AJÉd©«ô·O %Ù»@‰íÅ«p¿D]¤4AɃ3JÅqJ.õßÇñm5—d°@É,kJÉd9%ê„’Ø4PrέyïñZ¥ë"%Vî‚ äÁ ¥ý J|Ed¥$ƒºá±¥{²e”üU“ÙŒs]¤¤·Ÿ¼[ñÞ#%o¯r©•»àµg”Šã\Q2GZ)É ‚’ RJt¶)%ê„’Ø4Pr]’K®ë€€+wAPòàŒRqœ+JæH’>N ”LR¢³M)Q'”Ħ’ë2JÔu@@i ‚’g”Šã\Q2GZ)É ‚’ „’œÕ³ËÒuÉß>)”Ħr\½'3ŽºHi ‚’g”Šã\Q2GZ)É郒 RJt¶i.Q'”Ħ’ë²\¢.Rƒ äÁ¥â8W”Ì‘VJ2¨ d‚”mJ‰:¡$6 ”\—Q¢.Rƒ äÁ¥â8W”Ì‘VJ2¨ d¡$01ãèlSJÔ %±i äºŒu‘Ò%Î(Ç)”úïãø6ÈJI”̲¦”èlSJÔ %±i äº@iü>Îu‘+wAPòàŒzYR*åÍ{ëW9 d‚”’ÉòÕ›:¡$6 ”\‡¿ÍUŽ¿s]{+wAPòàŒRqœ«\2GZsI”LR¢³Ms‰:¡$6 ”\‡¿%™™çªë€€+wAPòà„Òþ È%¾"²R’AÝŽd”üU“%×EJzkðÉ»ï=~Žóö: —Z¹ ^[pF©8Î%s¤•’ *(™ ¥Dg›R¢N(‰M%×Å'‡w®º(±r%Î(ǹ¢dŽÔ)éã¤@É)%:Û”uBIl(¹.P¿s]”X¹ ‚’g”Šã\Q2GZ)É ‚’ RJt¶)%ê„’8 Pr]X—Æßǹ®J¬ÜAɃ3JÅq®(™#­”dPAÉ)%:Û”uBIl(¹.äÒd]¢®Jc”<8£T犒9Òÿ ìLwY’ìü*Â<ÀôÍʺÐÓ€qÏ}_ÿ A3 ´FÒëËÝÍaþ%=ù§ m÷0Xyâ‹ 1­ìDs)Tw©†.ÕÎvèRÕ%—R›æ.…næR¿º¹KõÅ“¢»ErIç1—JGÚ\J'Õ]*‚¡Kµ³ºTuÉ¥ô ï.…n~Å¥`¿{WÝÄg©/ºKQ$—Ôqs©t¤Í¥tRÝ¥"ºT;Û¡KU—\Jmš»º)K0 ÝÜ¥úâIÑ]Š"¹äïrÔ%ý÷Cï‘v—Š`èR‘ {ïz¸´kùkbÄ]ªÇ›ÿæîKU71ÄYê‹îRÉ%uœÇX*©BϽtÃçë0îR ]*²±KU—XJ}»:ÿÙZï ó¸ÐÍ]ª/žÝ¥(ö.9£G]*ÿ}ÂR:©‹ \ ÙÈ¥¦›»”ÿiðú óŸmâRº!lšnbÈ–Š»C‘\RÇù5Kçóç^ºá‰¥ ]ªí྇KWÜo©Ms—êñfW\ŸÿÝts—¢Í>ü#pw)Šä’:Îc.•Ž´^qnxçR ]ªíÐ¥ªK,¥6Í] ÝôŠëÿ@ÓÍ]ª/žÝ¥(’Kê8“K“yœ_éþßÛç†w.ÁÐ¥ÚÙ]ªºäRjÓÜ¥ÐÍ\ê~ïÝtCüŠ«/žÝ¥(’Kê8¹T:ÒÆR:©~_*‚¡Kµ³ºTuÉ¥Ô¦¹K¡¹TuCÜ¥¾è.E‘\RÇyÌ¥Ò‘6—ÒIu—Š`èRíl‡.U]r)ݕݥÐ\ªº¹K}Ñ]Š"¹¤Žó˜K¥#m.¥“ê.ÁÐ¥ÚÙ]ªºäRî½ãmÓï—àŠ«Ç›»ÔÝ¥(’Kê8¹T:ÒæR:©îR ]ªíÐ¥ªK.¥6ÍY ݈¥ª›»ÔÝ¥(’Kþ.G]ҟܽÓIu—Š`èR‘û¥ªK.¥6Í] ÿÙú¥~ײéæ.ÕOŠîRÉ%uœÇX*ic)Tw©†.ÙØ¥ªK.¥6Í] ÝÈ¥ª›âwï¾è.E\Ú?òˆKõ‘Í¥tRçU0r)59ºâB7w)ÿÓàu¼íü¾Ôç7ÝÌ¥x“IqwP’Kê8¹T:ÒæR:©îR ]ªíÐ¥ªK.¥6Í] Ý€¥ÐM Ù¶OŠîR="ü«øóýÓ¹T:Òp)‡×¸KE0t©v¶C—ªnèRèF.UÝÄw©/ºKQ$–Ôqs©t¤Í¥tRÝ¥"ºT;Û¡KU7t)t#—ªnîR_t—¢H.©ãì\ú2ÿû¼>²¹ÖõâñLÏöÙÓgÆqRþwÞõ^tÓü§“åW`íœùßM7Íÿ¦¢»Vùßçû§?f×~ûWïKÿëßÿãïÿ«Æ—ÿ³ø‡ûpÖv|Ëk]ÃY×§×GKê_MLF/ã8gJ¶m:f×ü+¤;X»åYøÏßÓñÜÁÐyß89^úëmšÎõ-AŠî`ôé}øùþÉÙÁ_pWºÙÆ]×·×GM¦«5ý”îZ튇®U]ºZ“îZèFWkÕͯ־è®E‘®Vu«§¸VºÛæZ×Çû_G-ìеÚ%]«ºäZ:YîZèF®UÝܵ¾è®E‘\ów9É5é'Wh××û‡2¸–ØpÖŠl|…V]r-,w-tþçÑ+´êæ®õEw-ŠäšºÙÄÚo¿¹BK÷ÛXëúüúhÊÄZïZí¢‡¬U]r-,w-t#תnîZ_t×¢®íŸiy‚kõ˜Íµ®ï¯‚‘kU6d-tɵt²ÖçM7p-t3× ¸kGtæòó4ü9§±VŸLÙ\ë¾TÁеÚeX«‡K¿ƒÿ=,w­oö;xøæº¹kõÅ“¢»ErMÝï)¬•n9\ËÍÖâü{Ïä Ù˜µÚ'ÖÒÉr×B7c­›6ÝÄ -ݵzDdMÝð)®•î¹¹–,w­†¬Ùصª›»–ܵÐÍ\ëcº¹kõÅ“¢»Eb ¾'û4¨O²l®¥FÌ]+íõеèëýž;ùÌK'a‡KWh÷\êƒnäZ}߉AÎZ_t×¢H®©>…µÒ17×Ò‡£»VC×jç=¼¯U]b-,g-t#תnîZ_t×¢H®©>ŵÒ17×R»é®ÁеÚy]«ºäZ:YîZèf®Á}­êæ®õEw-Šäš:àS\+ss-µ›îZ ]«÷еªK®¥“å®…næÜתnîZ_t×¢H®ù»œäšô‡ï?R»é®Áе"T]r-,w-tþçä>™˜Ü4ÝܵúâIÑ]‹"¹¦øÖJÇÜXKí¦»VC׊lìZÕ%×ÒÉr×B7r­ê&ù§A_t×¢®í‡y‚kõñ™ÍµÔn.Ϋ`äZ<†st…†.¹–NÖ:Þv>øÑß×âx3× ¸kG¤~mÿ$ÌS\+ss-µ›îZ ]«÷еªK®¥“å®…nÀZèæ®ÕOŠîZ‰5uÀ§¸V:æp-ÿ¸kE0t­vÞCת.¹–N–»º‘kU71hÛ^<)ºk¡$×ÔŸâZ阛k©-u׊`èZí¼‡®UÝܵ¼Øà®…näZÕM r×ú¢»ErMð)®•޹¹–ÚMw­†®ÕÎ{èZÕ%×ÒÉr×B7s îkU7w­/ºkQ$×Ô'×~ù x}²fs-}´»k¥¥ºV;ï¡kU—\K'Ë] Ý̵.%¼éæ®ÕOŠîZÉ5uÀ§¸V:ææZj7ݵ"ºV;ï¡kU—\K'Ë] Ýȵª›äWh_t×¢H®©>ŵÒ17×R»é®ÁеÚy]«ºäZ:YîZèF®UÝܵ¾è®E‘\ów9É5éß ÎS»é®Áе"v¹ñäÏäZ:YîZ=Þè·’¡›»V_<)ºkQ$×ÔŸÂZé˜k©Ýt׊ ¹–îCË]«zr-,w-tþ³ûFº‰A~…ÖOŠîZÁµýã8Op­>¾³¹–ÚÍÅyŒ\‹Ç€êï6ù)Ógã*—~¿–)ÖÝÀµx߉AÛöâIqw(’kê€Oq­tÌ͵ÔnºkE0t­vÞCת.±–N–»º‘kU71È]ë‹îZÉ5uÀ§¸V:æp-¹kE\KŸyË ¯Ðxrhr-,w­vò£ûZèæ®ÕOŠîZÉ5uÀɵc¿¯Oöl®¥KÊ]+-õеÚyY«º™k¿æÅ w-t#Öªnb³Öݵ(’kê€Oq­tÌ͵t›w׊`èZí¼‡®U]r-,w-t#תnîZ_t×¢H®©>ŵÒ17×Ò¥ç®ÁеÚy]«ºäZ:YîZèF®UÝܵ¾è®E‘\S|Šk¥cn®¥vÓ]+‚¡kµóºVuɵt²ÜµÐ\«º¹k}Ñ]‹"¹¦ø×JÇÜ\Kí¦»VC×jç=t­ê’kéd¹k¡¹Vus×ú¢»ErÍßå$פ?|7螉zþ½g¢†lüZÞoÞ¯ýšŸ)è®…Îÿœô‰ÉMÓÍ]«/žݵ(’kê€Oa­t̵î»Á÷ž‘zO ²V;ôÄZ÷Ý Ž7ì<êñ&ùgh_t×¢®íz‚kõñ¢ÍµÔn.Ϋ`t…ÆcJG®….¹–NÖ:Þ6Í úÉ^oæwíˆ47Ø?)ô×JÇÜ\Kí¦»VC×jç=t­ê’kéd¹k¡›]¡¿¥ÏÚMÓÍ]«/žݵ(kê€Oq­tÌáZNr׊`èZí¼‡®U]r-,w-t#תnbж½xRt×BI®©>ŵÒ17×R»é®ÁеÚy]«º¹ky1Ä] Ýȵª›ä®õEw-Šäš:àS\+ss-]îZ ]«÷еªK®¥“å®…nîZúÔð+´êæ®õEw-Šäš:àS\+ss-}´»kE0t­vÞCת.¹–N–»º¹kéþç®UÝܵ¾è®E‘\S|Šk¥cn®¥vÓ]+‚¡kµóºVuɵt²ÜµÐ\«º¹k}Ñ]‹"¹¦ø×JÇÜ\ë¾|ï­çñÔ¡kµCO®¥“å®…näZÕÍ]ë‹îZÉ5—“\“þðÝ {fëù÷žÙ²áwƒxrjr-,w­ü½R¿–7‡ü ­º¹k}Ñ]‹"¹¦8±vlZŸlÚXKí¦_¡¥¥^¡µó²Vuɵt—w×Bç?ë±oT¡›»V_<)ºkQ×ö3=ÁµúøÓæZºÝ.Ϋ`äZ• Y ]r-¬u¼mb­ÿnÇ›´m/žw‡"¹¦ø×JÇÜ\Kí¦»VC×jç=b-ž´š\K'Ë]«Ç} ÝÄ w­¾xRt×¢H®©>ŵÒ1‡k9ØÉ]+‚¡kµóºVuɵt²ÜµÐ ®ÐÐM r×ê‹'Ew-Šäš:àS\+ss-µ›îZ$×Rµ Ùø ­úܵ¼â®…näZÕM r×ú¢»ErMð)®•޹¹–ìp׊`èZí¼‡¬U]r-,w-t#תnîZ_t×¢H®©>ŵÒ17×R»é®ÁеÚy]«ºäZ:YîZèF®UÝܵ¾è®E‘\S|Šk¥cn®¥vÓ]+‚äZ2ׯÐÚy]«ºäZ:ž»º‘kU7w­/ºkQ$×Ô'׎ÍCë“U›k©Ýt×JK=t­vÞCת.¹–N–»º™k]–~ÓÍ]«/žݵ(’kþ.'¹&ýá»A÷LÙóú(Ö¡kå8ãOƒªK®¥“å®…ÎÿŵÒ17×R»é®ÁеÚy]«ºäZ:YîZèf®åàs¿¯UÝܵ¾è®E‘\S|Šk¥cn®¥vÓ]+‚¡kµóºVuɵt²ÜµÐͯÐô©á®UÝܵ¾è®E‘\S|Šk¥cn®¥vÓ]+‚¡kµóºVuɵt²ÜµÐMYë¬ݵª›»Öݵ(’kþ.'¹&ýá»A÷ÌÛóï=ó6dÃïñäÙäZ:YîZù{ûµª›»Öݵ(’kê€Oa­t̵Ôn:kE0d­ÈÆ®U]r-õüîZèügmß <7{žçæ¬UÝܵ¾è®E\Û?#ö×ê3e›k鯱8¯‚‘kñlÚѺäZ:YëxÛ³Ù7ªþYÝM7s-ÞdRÜ”äš:àS\+ss-µ›îZ ]«÷еªK®¥“å®…nÎZrwÓtƒ¶Tt×êé_bé§;ɵÒ1‡k9úÆ]+‚¡kµóºVuɵt²ÜµÐM]ƒ½÷ÐÍ]«/žݵ(kê€kÇæ¡õɲ͵Ônºk¥¥ºV;ï¡kU7w-/‡¸k¡›¹ÖOöB71ÈY«/žݵ(’kê€Oq­tÌ͵ÔnºkE0t­vÞCת.¹–N–»º‘kU71È]ë‹îZÉ5uÀ§¸V:ææZúr׊`èZí¼‡®U]r-,w-t#תnîZ_t×¢H®©>ŵÒ17×R»é®ÁеÚy]«ºäZ:YîZèF®UÝܵ¾è®E‘\S|Šk¥cn®¥vÓ]+‚¡kµóºVuɵt²ÜµÐy—uè×Î’Î?C«nîZ_t×¢H®ù¹9É5éß ºgòž×GÙ]+Çv¹ñdÜäZ:YîZ=Þ¼_תnîZ_t×¢H®©>…µÒ17ÖRCä¬Áе"»Vuɵî»AŵÒ17×R»é®:ëv¥À³≺C×ÊáΔPÕŽ÷ëÏþ ÿ¬MçIÁù7Eñ¾ž!|Hꇢ»Vè¹¹]6óþI·×ÔUøéúûÿùßÿõÿÜüãŸÿùßýïàWø¿ë#ùEõ‰¹ÍÍÔ†º›µÕÖc*Û•¯¸l2%H4Yž®šLLMvög:‡~»«ïštéoç·»ªó܉™}ÑÍŒâO0Sñ7Íœ~Ù¯O”øÛ_ÿþßþùoÿbçõÁºÍÌÔuº™µ׿îo?>˜2o=› Ì ™÷ZMvögzW7“u© t3C÷çÔ̾èfÖ¢ÿ»ßžLõËß6óðŽú¼Ýf^úë¹yµ×ÚtûqÁ¼ Ì Ùܼ®Ékï:×¥¶ÆÍ‹ãÍÌë‹n^-úîdožÚæošç™òôºÃ‹ˆuý ô ›Ü@©èÇÏñͨúï{~ôZ¾ÔÏ(?ÓÅõËÃè²Ã!›3œîÎ0éèºÃ}Ñ-®E¼‡ª§?ÅÏÖ0ý¬O+nþ¥o~бÑÑ= dÿB6÷/w›‡wêèÇ›ù×Ý¿ZÄ{€Úøïû7»‡–oÍ¿t±¹õ+ÂÈ¿ ü ÙÔ—¿¤ÎÌù#ÝCC7ó¯/ºµˆþù_úÿŽôœ?뛟éÊr?õ^߸e†lpË Ùü–™:1÷“ttË Ýì–ÙÝÏ(:—íž~¤çô~‚ÅGo™:Ôäc?]|nq ÛÎùOÒ~øT ™ÿÙd?~IÍš[L:ºe†n†l_t‹ko™jù¿ÉÏÚÎòm¡!š.>÷¯~]ò!ø2ÿiþué(‡wêè–Ç›ù×Ý¿Z¤K~ÿðäïû7½eÖç.7ÿÒŶøfø×dÇýk²©/?ÎR/¶>¼ëT·Ìv¼©Pܵ#¢jé¿ïßèñ­ßë:ëÙ›¿éJsãë„ÿÙˆÊýõò ;~ mG›ÝBÏR#æþÆ»Îu©áØtÓ[h{ñ¡èþÆg·ÐIÈÓükûìÁÔãoš¿ÿI–Çoš~Ö‡;‡Ëùzt—ë—eÝs9dS—ä‘óêp¸¹}éóÑmŽãMuðIÕtG·‡Šnsqfó—¿Ù?ÏùûdÿyvÜfÿ1&Vù²u›‹`ÔŸ6ÙôfA6Çá¦wgé3Òm&ÙºÙÝ¢/ºÍµèw‹/_7û@Ÿ`³5ß>,—ïåtíºÉõËÇ莲‘É¡››œ>HÝdÒ‘É¡›™ÜÝäZü®ÉŽü wéÚØfŸù—õùÓÍôt#tÓõæÞé*ïØ $d£H蜳v¸géÓ×M'™ºÃ½Âo }ÑM¢ÿÙÞùÙú¦1'[¿dùã—#¿yI¨Ÿõ1ÕÍÜîkY<ÇZ;äíïÔOGã@gÚšnº_M݃ߞë×#í OtéJrwCç½ÕD—N¾ Vo¶ÝÝP樇â~dºÿuè%¯¨xMÅ*ÞRñŽŠ÷T| â#Ÿ¨øLÅ*¾RñŠïTü â'Ͱêsœ¥Ã 1o± z`Éw3ãÜÛœiuÂÉDë—!wBÊD‹¨²b‹!-†¸òbŒ!1†È2c!5†ØrcŽ!9†è²³@vÈÎÙY ; dgì,²³@vÈÎÙY ; dgì,²³@vÈÎÙY ; dgì,²³@vÈÎÙY";Kdg‰ì,‘%²³Dv–ÈÎÙY";Kdg‰ì,‘%²³Dv–ÈÎÙY";Kdg‰ì,‘%²³Dv–ÈÎÙY";+dg…쬲³BvVÈÎ ÙY!;+dg…쬲³BvVÈÎ ÙY!;+dg…쬲³BvVÈÎ ÙY!;+dg…쬑5²³FvÖÈÎÙY#;kdg쬑5²³FvÖÈÎÙY#;kdg쬑5²³FvÖÈÎÙY#;kdg쬑5²³Av6ÈÎÙÙ ;dgƒìl ²³Av6ÈÎÙÙ ;dgƒìl ²³Av6ÈÎÙÙ ;dgƒìl ²³Av6ÈÎÙÙ";[dg‹ìl‘-²³Ev¶ÈÎÙÙ";[dg‹ìl‘-²³Ev¶ÈÎÙÙ";[dg‹ìl‘-²³Ev¶ÈÎÙÙ";;dg‡ìì²³CvvÈÎÙÙ!;;dg‡ìì²³CvvÈÎÙÙ!;;dg‡ìì²³CvvÈÎÙÙ!;;dg‡ì\ ;Èβsì\ ;Èβsì\ ;Èβsì\ ;Èβsì\ ;Èβsì\ ;Èβsì\ ;ÈÎ%²s‰ì\";—ÈÎ%²s‰ì\";—ÈÎ%²s‰ì\";—ÈÎ%²s‰ì\";—ÈÎ%²s‰ì\";—ÈÎ%²s‰ì\";—ÈÎ%²s‰ì\!;WÈβs…ì\!;WÈβs…ì\!;WÈβs…ì\!;WÈβs…ì\!;WÈβs…ì\!;WÈβs…ì\!;WÈÎ5²sì\#;×ÈÎ5²sì\#;×ÈÎ5²sì\#;×ÈÎ5²sì\#;×ÈÎ5²sì\#;×ÈÎ5²sì\#;×ÈÎ5²sìÜ ;7ÈÎ ²sƒìÜ ;7ÈÎ ²sƒìÜ ;7ÈÎ ²sƒìÜ ;7ÈÎ ²sƒìÜ ;7ÈÎ ²sƒìÜ ;7ÈÎ ²sƒìÜ ;7ÈÎ-²s‹ìÜ";·ÈÎ-²s‹ìÜ";·ÈÎ-²s‹ìÜ";·ÈÎ-²s‹ìÜ";·ÈÎ-²s‹ìÜ";·ÈÎ-²s‹ìÜ";·ÈÎ-²s‹ìÜ!;wÈβs‡ìÜ!;wÈβs‡ìÜ!;wÈβs‡ìÜ!;wÈβs‡ìÜ!;wÈβs‡ìÜ!;wÈβs‡ìÜ!;wÈÎ=²sìÜ#;÷ÈÎ=²sìÜ#;÷ÈÎ=²sìÜ#;÷ÈÎ=²sìÜ#;÷ÈÎ=²sìÜ#;÷ÈÎ=²sìÜ#;÷ÈÎ=²sì< ;Èβó€ì< ;Èβó€ì< ;Èβó€ì< ;Èβó€ì< ;Èβó€ì< ;Èβó€ì< ;ÈÎ#²óˆì<";ÈÎ#²óˆì<";ÈÎ#²óˆì<";ÈÎ#²óˆì<";ÈÎ#²óˆì<";ÈÎ#²óˆì<";ÈÎ#²óˆìj¼?j¼@j¼Aj¼Bj¼Cj¼Dj¼Ej¼Fj¼Gj¼Hj¼Ij¼Jj¼Kj¼Lj¼Mj¼Nj¼Oj¼Pj¼Qj¼Rj¼Sj¼Tj¼Uj¼Vj¼Wj¼Xj¼Yj¼Zj¼[j¼\j¼]j¼^j¼_j¼`j¼aj¼bj¼cj¼dj¼ej¼fj¼gj¼hj¼ij¼jj¼kj¼lj¼mj¼nj¼oj¼pj¼qj¼rj¼sj¼tj¼uj¼vj¼wj¼xj¼yj¼zj¼{j¼|j¼}j¼~j¼j¼€j¼j¼‚j¼ƒj¼„j¼…j¼†j¼‡j¼ˆj¼‰j¼Šj¼‹j¼Œj¼j¼Žj¼j¼j¼‘j¼’j¼“j¼”j¼•j¼–j¼—j¼˜j¼™j¼šj¼›j¼œj¼j¼žj¼Ÿj¼ j¼¡j¼¢j¼£j¼¤j¼¥j¼¦j¼§j¼¨j¼©j¼ªj¼«j¼¬j¼­j¼®j¼¯j¼°j¼±j¼²j¼³j¼´j¼µj¼¶j¼·j¼¸j¼¹j¼ºj¼»j¼¼j¼½j¼¾j¼¿j¼Àj¼Áj¼Âj¼Ãj¼Äj¼Åj¼Æj¼Çj¼Èj¼Éj¼Êj¼Ëj¼Ìj¼Íj¼Îj¼Ïj¼Ðj¼Ñj¼Òj¼Ój¼Ôj¼Õj¼Öj¼×j¼Øj¼Ùj¼Új¼Ûj¼Üj¼Ýj¼Þj¼ßj¼àj¼áj¼âj¼ãj¼äj¼åj¼æj¼çj¼èj¼éj¼êj¼ëj¼ìj¼íj¼îj¼ïj¼ðj¼ñj¼òj¼ój¼ôj¼õj¼öj¼÷j¼øj¼ùj¼új¼ûj¼üj¼ýj¼þj¼ÿj¼k¼k¼k¼k¼k¼k¼k¼k¼k¼ k¼ k¼ k¼ k¼ k¼k¼k¼k¼k¼k¼k¼k¼k¼k¼k¼k¼k¼k¼k¼k¼k¼k¼k¼ k¼!k¼"k¼#k¼$k¼%k¼&k¼'k¼(k¼)k¼*k¼+k¼,k¼-k¼.k¼/k¼0k¼1k¼2k¼3k¼4k¼5k¼6k¼7k¼8k¼9k¼:k¼;k¼k¼?k¼@k¼Ak¼Bk¼Ck¼Dk¼Ek¼Fk¼Gk¼Hk¼Ik¼Jk¼Kk¼Lk¼Mk¼Nk¼Ok¼Pk¼Qk¼Rk¼Sk¼Tk¼Uk¼Vk¼Wk¼Xk¼Yk¼ZkÝnm è÷Œe~öhwL~>Ä—ëu‡šœ¥L|±ÁÙïÓèk {§„O™û°çÐÍ­M!Ó>ÖÇñNŽ—þ~>¦ Ýï-ðׇ´}ÑG´QÜ?@xŸëìÚ(r}}Èß}Æß}Äß}Âß}Àß}¾ß}¼ß}ºß}¸ß}¶ß}´ß}²ß}°ß}®ß}¬ß}ªß}¨ß5Ӈꄷà ÑD´>ЇꄜÉ&œLªP&Õ )“*¢¢Q>ü òA‹¸hŒZFC|Ð"2სѴˆÆ÷ Ep4¼-¢£Ñ}¯ÕäªÈŽæö Ev4µ-²£™=h‘MìA‹ìh^ZdGÓzÐ";šÕƒÙѤ´ÈŽæô Ev4¥-²£=h‘MèA‹ìh>ßk5ž‡*²£á¦°gR#@¦°gR#Bû°gR#Dû°gR#FöÅŽ¨Âžé H’)ì™ÔÈ’)ì™ÔH“)ì™ÔÈ“)ì™ÔH”)ì™ÔÈ”)ì™ÔL¯ŒîÃžá ¼4º{&5S¥°gR3U {&5S¥°gR3U {&5S¥°gR3U {&5S¥°gR3U {&5S¥°gR3U {&5S¥°gPó2é>ì™Ô|¯â}Ò}Ø3„©RØ3©™*…=“š©RØ3©™*…=“š©RØ3©™*…=“š©RØ3©™*…=“š©RØ3©™*…=“š©â5Ó}Ø3„M÷aϤæ{•žIÍT)ì™ÔL•žIÍT)ì™ÔL•žIÍT)ì™ÔL•žIÍT)ì™ÔL•žIÍT)ì™ÔL•žAÍ ¨û°gRó½ŠwP÷aÏt¦JaϤfªöLj¦JaϤfªöLj¦JaϤfªöLj¦JaϤfªöLj¦JaϤfªöLj¦ŠWS÷aÏp^N݇=“šïU {&5S¥°gR3U {&5S¥°gR3U {&5S¥°gR3U {&5S¥°gR3U {&5S¥°gR3U {5/­îÞIÍ÷*Þ[݇=ÓA˜*…=“š©RØ3©™*…=“š©RØ3©™*…=“š©RØ3©™*…=“š©RØ3©™*…=“š©RØ3©™*^g݇=ÃAx¡uöLj¾W)ì™ÔL•žIÍT)ì™ÔL•žIÍT)ì™ÔL•žIÍT)ì™ÔL•žIÍT)ì™ÔL•žIÍT)ìÔ¼èº{&5ß«x×uöLaªöLj¦JaϤfªöLj¦JaϤfªöLj¦JaϤfªöLj¦JaϤfªöLj¦JaϤfªxvö á%Ø}Ø3©ù^¥°gR3U {&5S¥°gR3U {&5S¥°gR3U {&5S¥°gR3U {&5S¥°gR3U {&5S¥°gPórì>ì™Ô|¯âýØ}Ø3„©RØ3©™*…=“š©RØ3©™*…=“š©RØ3©™*…=“š©RØ3©™*…=“š©RØ3©™*…=“š©âµÙ}Ø3„g÷aϤæ{•žIÍT)ì™ÔL•žIÍT)ì™ÔL•žIÍT)ì™ÔL•žIÍT)ì™ÔL•žIÍT)ì™ÔL•žAÍ µû°gRó½Šwj÷aÏt¦JaϤfªöLj¦JaϤÎT¥°ç?8ìù×_þåì,Í$Øù·¿þåÿþí¯ù{,~žÁ8Ø9t£`çÐ̓ÓûúõºQ°sèfÁÎ}ÑOCgÁÎQØ8Q°3•™ªSÅ»¦¶â{o›ÚŠïU¼oj+¾WñÆ©­ø^Å;§¶â{oÚŠïU¼wj+¾Wñæ©­ø^Å»§¶â{oŸÚŠïU¼j¼€ºv|xÕìLj¦jÍ÷*^Cµ5ß«xÕÖ|¯âUT[󽊗QmÍ÷*^Gµ5ß«x!ÕÖ|¯â•T[󽊗RmÍ÷*^Kµ5ß«x1ÕÖ|¯âÕÔ}°3p¢`g*3U¦Š÷SmÃ÷*ÞPµ ß«xGÕ6|¯â-UÛð½Š÷TmÃ÷*ÞTµ ß«xWÕ6|¯âmUÛð½Š÷UmÃ÷*ÞXµ ß«xgÕxiuì øðÚª)Ø™ÔLÕ–ïU¼ºj[¾Wñòªmù^Åë«¶å{/°Úöÿ3v/9–eY„§‚jT”H')oÞï.3`þ ~Û‰g¸Çþ¤¨î’éJ·»£±´ ¿U>a}Þû­òëóÞo•ÏXŸ÷~«|Èú¼÷[åSÖç½ß*³>ïýVùœõ„áIagmÕ[å›Öçƒß*_µ>üVù®õùà·Ê—­Ï¿U¾m}>ø­òuëóÁo•ï[Ÿ~«|áú|ð[å×çƒß*_¹>üVùÎõñ¡ë ;CŸº>…EÛª~«|îú|ô[åƒ×ç£ß*Ÿ¼>ýVùèõùè·Êg¯ÏG¿U>|}>ú­òéëóÑo•_Ÿ~«|þú|ô[åØç£ß*ŸÀž°3<)쬱­úd«|û|ò[åKØç“ß*ßÂ>ŸüVùöùä·Ê÷°Ï'¿U¾ˆ}>ù­òMìóÉo•¯bŸO~«|û|ò[åËØç“ß*߯>>Ž=agèã󨧰³h[õÙo•OdŸÏ~«|$û|ö[å3Ùç³ß*Ê>ŸýVùTöùì·ÊDzÏg¿U>—}>û­òÁìóÙo•OfŸÏ~«|4û|ö[å³Ùv†'…5¶U_l•ogŸ/~«|=û|ñ[åûÙç‹ß*_Ð>_üVù†öùâ·ÊW´Ï¿U¾£}¾ø­ò%íóÅo•oiŸ/~«|Mû|ñ[å{Úǵ'ì }|Rûvm«¾ú­òYíóÕo•kŸ¯~«|Zû|ýþ­ú.ìüû?"ìó*ìüWØùàÇaçîGaçîmØù»ÿÝý—á~v~áÞ„ïáþ /Ã7aç—á·†ïþ÷p?ë{¸ÿü÷p?é{¸&îá~Î÷pÿDÜÃý”ïáþy¸‡ûßÃýÓp÷¾‡ûgáîç{÷OÂ=ÜO÷{XØÓŸ9Ý¿`÷£Åô•9ßþ¤ýÿd»0}eÊ«/ì_°t¥°3XÚRØ,}ic–ÆvKg ;ƒ¥5…ÁÒ›ÂÎ`iNag°t§-ýÍvÆ”îvKwZЃ¥;­çÁÒ–ó`éN«y°t§Å,Ýi›–î´KKwÚ¤ƒ¥;íÑÁÒ¶è`éN;t°t§ :XºÓþ,Ýi{~³…1¥;…ÁÒç`éNks°t§¥9XºÓÊ,Ýia–î´.KwZ–ƒ¥;­ÊÁÒå`éNkr°t§%ùͶ#Ç”î´!Kw ;ƒ¥;mÇÁÒvã`éN›q°t§½8XºÓV,Ýi'–î´KwÚ‡ƒ¥;mÃÁÒvá`éN›ð›-ìŒ)Ý)ì –î´KwZƒ¥;-ÀÁÒÖß`éNËo°t§Õ7XºÓâ,Ýií –î´ôKwZyƒ¥;-¼o¶}7¦t§m7XºSØ,ÝiÓ –î´çKwÚrƒ¥;í¸ÁÒ6Ü`éNûm°t§í6XºÓn,Ýi³ –î´×KwÚjßlagLéNag°t§…6XºÓ:,Ýi™ –î´ÊKwZdƒ¥;­±ÁÒ–Ø`éN+l°t§6XºÓú,Ýiy}³í®1¥;m®ÁÒÂÎ`éN[k°t§5XºÓÆ,Ýi_ –î´­KwÚUƒ¥;mªÁÒöÔ`éN[j°t§5XºÓ†úf ;cJw ;ƒ¥;-§ÁÒVÓ`éN‹i°t§µ4XºÓR,Ýi% –î´KwZGƒ¥;-£ÁÒVÑ`éN‹è›m)Ýi –îvKwÚ@ƒ¥;íŸÁÒ¶Ï`éNag°tç+Ý)ìŒ/ÐÂÎ`éNag°t§°3XºSØ,Ý)ì|³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØùf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaç›-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ7[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ßlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØùf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óÍvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ7[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…o¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óÍvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎ ;ßð ;kL}NØY4:agÑTè„ES¢vMNØY4E:agÑTé)ì,š2=m:ag}„>°³huÂ΢éÔ ;‹¶U>=ag|¤°³Æ|•NØY4ߥvÍ—é„Eóm:agÑ|NØY4ß§vm« ;‹¶U…EÛªÂ΢mUagѶª°³h[åcÒvÆG|NzÂ΢ýVví·ª°³h¿U…Eû­*ì,ÚoUagÑ~« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´ÏLOØY´ß*_š>…õ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùõ„ñŸ ž°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvíÓÔví·ÊשOag}ÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U>Z=ag|Äg«'ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…Aûœõ„Eû­òEëSØY±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•]OØñ©ë ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagÐ>=agÑ~«|ûvÖGlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[åãØvÆG|{Â΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´ÏfOØY´ß*_Î>…õ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVù ö„ñŸÔž°³h[UØY´­*ì,ÚVvm« ;¿¡ß†ßýé÷yvþËïÃÎÿü0ìü+÷ƒ°ó¯ÜÛ°ówÿ»÷Ó¯ÜÂοr¯ÃÎ~øöÅ×aç_Éo ßOßÈoÃÏ~Ñ𫆯á?høþ“†ÿ¬á¿hø¯þ›†ÿ®áhøŸþ—†ÿ­áÂÎøOÿüÌéßrúN_™óí¯·°³þ×ÞsúÊ”W_øH–®,ì¬ÿ5Ú²°³Xú²°³X³°³X:³°³XZ³°³Xz³°³Xš³°³Xº³-=Ø…5¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;ƒÝ.^Sº³M¼Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³;Ø…5¥;[·‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;ƒÝ^]Sº³­ºXº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³í9Ø…5¥;[‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;ƒÝŽ\Sº³ ¹Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³M8Ø…5¥;[ƒ‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;ƒÝ¾[Sº³m·Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³­6Ø…5¥;[i‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;ƒÝîZSº³ÍµXº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³ 5Ø…5¥;[O‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;‹¥; ;ƒÝZSº³-´Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xº³°³Xºó•î,ì¬/Ð…ÅÒ…ÅÒ…ÅÒ…Á.ì¬)ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØìÂΚ҅ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…Á.ì¬)ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØìÂΚ҅ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…Á.ì¬)ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØìÂΚ҅ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…Á.ì¬)ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØìÂΚ҅ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…Á.ì¬)ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØìÂΚ҅ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…Á.ì¬)ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØìÂΚ҅ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…ÅÒ…Á.ì¬)ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,ÝYØY,Ý)ì ¸°3ÇÔ§°3i TØ™4*ìLšv&M ;“¦H…IS¥ÂΤ)SagÒÔéyèSag~„Fv&M§ ;“¶U>-ì¬,ì̱­úÙVùn´°3¿m«~¶U¾-ìÌoÛªŸm•ïG ;óÛ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶ÊǤ…õŸ“v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«ví3ÓÂΤýVùÒ´°3?b«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«|€ZØYñ jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÑ>M-ìLÚo•¯S ;ó#¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶ÊG«…õŸ­v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«vísÖÂΤýVù¢µ°3?b«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«|èZØYñ©kagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÑ>-ìLÚo•¯` ;ó#¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶jagÒ¶ÊDZ…õŸÇv&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«ví³ÙÂΤýVùr¶°3?b«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«v&m«|P[ØYñImagÒ¶jagÒ¶jagÒ¶jagÒ¶jaç·ôwaçß2ìüîÝŸÿæoþêþäÿú7ÏOïb^……~v~á~v~áÞ†¿ûßÝùîMØùwúöÿ¾ý)^¸7aç{¸?ÃËðMØùeø­á»?Á=Üàî?ÿ=ÜOúî}÷s¾‡û1ßÃý”ïá~È÷p?ã{¸ñ=ÜOøî|÷ó½‡ûñÞÃýtïá~¸÷°ý=¦ûÙbº 0ÝÓWæ|û“¶º»_,¦¯Lyõ…ý^ÁÒ•ÂÎ`iKag°ô¥°3XSØ,)ì –Ö´«KoÚÔƒ¥9íéÁÒ¶ô7Û’SºSØ,ÝiA–îvKwZ΃¥;…ÁÒó`éNag°t§°3XºSØ,Ý)ì –îvKw ;ßl»xLéN›x°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –î´q¿Ùî˜ÒÖí`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØùfÛ«cJwÚªƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§íùͶ<Ç”î´:Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ7ÛŽSºÓ†,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;mÂo¶E8¦t§58XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾ÙöݘҶÝ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýi«}³-µ1¥;­´ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óͶ»Æ”î´¹Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNê›mA)Ýi= –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…o¶=4¦t§-4XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tç+Ý)ìŒ/ÐÂÎ`éNag°t§°óÍvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaç›-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…o¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ßlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØùf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaç›-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ7[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ßlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØùf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óÍvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ7[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;'ì|Ã'ì¬1õ9agÑè„ES¡vM‰NØY45:agÑé„ES¥vM™NØY4u:agÑêyhÔ ;ë#tê„EÛ*ŸŒž°3>RØYc¾JOagÑ|—NØY4_¦§°³h¾M'ì,š¯ÓSØY4ß§vÍê)ì,šoÔSØY4_©§°³h[UØY´­*ì,ÚVù˜ô„ñŸ“ž°³h[UØY´ßªÂ΢mUagÑ~« ;‹¶U…Eû­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagÐ>3=agÑ~«|izÂÎúˆ­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«|€zÂÎøˆOPOØY´ßªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3hŸ¦ž°³h¿U¾N=ag}ÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U>Z=ag|Äg«'ì,ÚoUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´ÏYOØY´ß*_´ž°³>b« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*ºž°3>âS×ví·ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì Ú'°'ì,Úo•¯`OØY±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•cOØñyì ;‹ö[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVví³Ùví·Ê—³'ì¬ØªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶʵ'ìŒø¤ö„Eû­*ì,ÚVvm« ;‹¶U…ßÐß…ßýaç˜oaçwß…“þéÝ/ÀÃÎ/ÜÂÎ/Ü›°óï~û6ؼÿò/ÜÂÎ/Ü›°ó=ÜŸáeø&ìü2üÖðÝŸàîp÷Ÿÿî'}÷ƒ¾‡û9ßÃý˜ïá~Ê÷p?ä{¸Ÿñ=Üøî'|÷¾‡ûùÞÃýxïá~º÷p?Ü{XØÓW¾}ûƒ<û·ì8}eΫ/ì'‹/ì‹é+S^}a¿W°t¥°3XÚRØ,})ì –ÆvKg ;ƒ¥5…ÁÒ›ÂÎ`iNag°t§-ýÍvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ7Û.SºÓ&,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;mÜo¶°3¦t§u;XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾Ùöê˜Ò¶ê`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýi{~³…1¥;­ÎÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óͶ#Ç”î´!Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éN›ð›-ìŒ)Ýi –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…o¶}7¦t§m7XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKwÚjßlagLéN+m°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|³í®1¥;m®ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓ†úf ;cJwZOƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaç›m)Ýi –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –î|¥;…ñºSØ,Ý)ì|³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØùf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaç›-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ7[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ßlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØùf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óÍvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ7[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…o¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óÍvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎ ;ßð ;kL}NØY4:agÑTè„ES¢vMNØY4E:agÑTé„ES¦vMNØY4…:agÑTêyèÔ ;ë#¶Ê'£'ìŒvÖ˜¯Ò ;‹æ»tÂ΢ù2°³h¾M'ì,š¯Ó ;‹æûtÂ΢ùB°³h¾Q'ì,š¯Ô ;‹æ;õvm« ;‹¶U>&=ag|Äç¤'ì,ÚoUagÑ~« ;‹ö[UØY´ßªÂ΢ýVví·ª°³h¿U…Eû­*ì,ÚoUagѶª°³h[UØ´ÏLOØY´ß*_šž°³>b« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ* ž°3>âÔví·ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì Ú§©'ì,Úo•¯SOØY±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•VOØñÙê ;‹ö[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvísÖví·Ê­'ì¬ØªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶʇ®'ìŒøÔõ„Eû­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;ƒö ì ;‹ö[å+ØvÖGlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[åãØvÆG|{Â΢ýVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…Aûlö„Eû­òåì ;ë#¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­òAí ;ã#>©=agÑ~« ;‹¶U…EÛªÂ΢mUaç7ôwaç?û#ÂÎ1¯ÂÎß–þéÝ/ÀÃÎ/ÜÂÎ/ÜÛ°ó»+ìüÂý(ìü½ ;ßÃý^†oÂÎ/Ão ßý îáþ÷pÿùïá~Ò÷p?è{¸Ÿó=Üùî§|÷C¾‡ûßÃýˆïá~Â÷p?à{¸Ÿï=Ü÷î§{÷ý‡…1}åÛ·?Hag°àt¿Y°ûÉbº_,¦¯LyõÃ~¯`éJag°´¥°3XúRØ,)ì –ÎvKk ;ƒ¥7…ÁÒœÂÎ`éN[ú›-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…o¶]<¦t§M'=agÑ~« ;‹ö[UØY´ßªÂ΢ýVví·ª°³h¿U…Eû­*ì,ÚoUagÑ~« ;‹ö[UØY´­*ì Úg¦'ì,Úo•/MOØY±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•POØñ ê ;‹ö[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvíÓÔví·Êש'ì¬ØªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶÊG«'ìŒølõ„Eû­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;ƒö9ë ;‹ö[å‹ÖvÖGlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[åC×vÆG|êzÂ΢ýVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…Aûö„Eû­òì ;ë#¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­òqì ;ã#>=agÑ~« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂΠ}6{Â΢ýVùrö„õ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVù ö„ñ‘ÿcä~v-¿Ž ¿ ò ¸é¶‘H¶,™ ž6S!`ÀáÀóS«¬£{έOÜd©´ôKçžµk²µ—ŸÔnØY´wUagѶª°³h[UØY´­*ìüB¿ ;Ocù×ÿú§ÿ˜pó·ûíï>M"ù_ÿôûo>}úòÍþîñß¿ÿæ‡ÏŸbžÂÎïË?>€Ãο}èÛï? ;?¸×°ó_°óƒû(ìüà^ÂÎw8?Ãcøv~ ß¾óÜáüw8þ;œ#}‡s ïpŽóÎa¾Ã9Êw8ùçßáâ;œ#|‡s€ïpŽïÎá½Ã9ºw8÷ ;cúäÛÛRØìOœÎ™;GÓ9±˜>™òôo˜ó –®vK[ ;ƒ¥/…ÁÒ˜ÂÎ`éLag°´¦°3XzSØ,Í)ì –îtKÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØù²ÝÅcJwº‰Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éN7î—-ìŒ)Ýéº,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;_¶{uLéN·ê`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýéöü²…1¥;]ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçËvGŽ)Ýé†,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;Ý„_¶°3¦t§kp°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|Ùî»1¥;Ývƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§[íËvÆ”ît¥ –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…/ÛÝ5¦t§›k°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îtC}ÙÂΘҮ§ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óe»‡Æ”ît –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;ÿ@w ;ß/vÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçËvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΗ-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΗ-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…/[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…/[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;_¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;_¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾lagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾lagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒ¯tç+Ý)ìŒïÒÂÎ`éNag°t§°óe ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óe ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçËvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éΆ/¼ag©Ï†ES  ;‹¦BvM‰6ì,šmØY4EÚ°³hª´agÑ”iÃ΢©Ó†ES¨ ;‹¦RvM©6ì ÚOF7ì,ÚVùÕè†õî¥ ;‹æfÚ°³hî¦ ;‹ævÚ°³hî§ ;‹æ†Ú°³hî¨ ;‹æ–Ú°³hî© ;‹æ¦Ú°³hï*?&ݰ3>âç¤ví]UØY´wUagÑÞU…E{Wví]UØY´wUagÑÞU…E{Wví]UØY´wUagÑÞU…Aû™é†E{Wù¥é†õ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùê†ñ?Aݰ³hïªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?Mݰ³hï*¿Nݰ³>b« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?Zݰ3>âg«ví]UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mÕ϶ÊÏX(ì¬oÛªÂ΢mUagѶª°3h?gݰ³hï*¿hݰ³>b« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?tݰ3>â§®ví]UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVví'°ví]åW°vÖGlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[åDZvÆGü…ŸûÆSøù]€ùÇÏS‰ø8üüàæ<ÿ¿ÎÿÄÿþáË—o_ƒÎ?½}oø7î»Ï¯Üü2dŸ¿¼û÷ÍOõà^ÂÏw8?Ócø~~ ß¿óÝáü@w8?ÏΑ¿Ã9ðw8Çýç°ßáõ;œƒ~‡sÌïpùοÃ9àw8Çûçpßáí;œƒ}‡…Ÿ1}òíí)ü öÉ¥'öÉœ§é“'OÓ9Ñøî“)Oìœg°t¥ð3XÚRø,})ü –Æ~Kg ?ƒ¥5…ŸÁÒ›ÂÏ`iNág°t§[üË~Æ”ît…–î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…Ÿ/Û]=¦t§›z°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –ît#ÙÂϘҮãÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ðóe»wÇ”îtë–î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒn×/[øSºÓÕ:XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~¾lwè˜ÒnÐÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;ݘƒ¥;…ŸÁÒÂÏ`éNág°t§›òË~Æ”îtM–î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…Ÿ/Û}8¦t§Ûp°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –îtë}ÙÂϘҮ¼ÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ðóe»ÛÆ”ît³ –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒn°/[øSºÓõ5XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~¾l÷Ô˜Òn©ÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSøù²¿ÐÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü|ÙÂϘÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSøù²…Ÿ1¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSøù²…Ÿ1¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ðóe ?cJw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ðóe ?cJw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNáçË~Æ”î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNáçË~Æ”î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ—-üŒ)Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ—-üŒ)Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3Xºó•î~ÆèÎWºSø_ ;…ŸÁÒÂÏ—-üŒ)Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ—-üŒ)Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…Ÿ/[øSºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;~¾ð†Ÿ5¦>~M6ü,š møY4%Úð³hj´ágÑiÃÏ¢©Ò†ŸES¦ ?‹¦N~M¡6ü,šJmøY4¥Úð3h?Ýð³h[åW£~ÖG¸—6ü,š›iÃÏ¢¹›6ü,šÛiÃÏ¢¹Ÿ6ü,šjÃÏ¢¹£6ü,š[jÃÏ¢¹§6ü,š›jÃÏ¢½«ü˜tÃÏøˆŸ“nøY´wUágÑÞU…ŸE{W~í]UøY´wUágÑÞU…ŸE{W~í]UøY´wUágÑÞU…ŸE{W~íg¦~í]å—¦~ÖGlUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[å¨~ÆGüuÃÏ¢½« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ ý4uÃÏ¢½«ü:uÃÏúˆ­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m«ühuÃÏøˆŸ­nøY´wUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U?Û*?cÝð³¾m« ?‹¶U…ŸEÛªÂÏ ýœuÃÏ¢½«ü¢uÃÏúˆ­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³hïªÂÏ¢mUágѶªð³h[凮~ÆGüÔuÃÏ¢½« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ ývÃÏ¢½«ü vÃÏúˆ­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m«ü8vÃÏøˆŸÇnøY´wUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[Uø´ŸÍnøY´w•_ÎnøY±U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢m•Ônøñ“Ú ?‹ö®*ü,ÚV~m« ?‹¶U…Ÿ_èwáçi"#ü<Õç§°sÌSØù]`ùÇÏŸ~>;?¸ÂÎnþáOaç/'ìüàæ¿ß¸/ï¸ù)ÜKØùçgx _ÂÎá[Ãw~‚;œàçχs¤ïpôÎq¾Ã9Ìw8Gùç ßáã;œC|‡s„ïpðÎñ½Ã9¼w8G÷çàÞaagLŸ|{ûA ;ƒý‰Ó9³`ŸvM6ì,š mØY4%Ú°³hj´agÑiÃ΢©Ò†ES¦ ;‹¦NvM¡6ì,šJmØY4¥Ú°3h?ݰ³h[åW£vÖG¸—6ì,š›iÃ΢¹›6ì,šÛiÃ΢¹Ÿ6ì,šjÃ΢¹£6ì,š[jÃ΢¹§6ì,š›jÃ΢½«ü˜tÃÎøˆŸ“nØY´wUagÑÞU…E{Wví]UØY´wUagÑÞU…E{Wví]UØY´wUagÑÞU…E{Wvíg¦ví]å—¦vÖGlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[å¨vÆGüuÃ΢½« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂΠý4uÃ΢½«ü:uÃÎúˆ­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«ühuÃÎøˆŸ­nØY´wUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªŸm•²þPØYß¶U…EÛªÂΠýœuÃ΢½«ü¢uÃÎúˆ­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üÐuÃÎøˆŸºnØY´wUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´ŸÀnØY´w•_ÁnØY±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•ÇnØñóØ ;‹ö®*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;ƒö³Ù ;‹ö®òËÙ ;ë#¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­òƒÚ ;ã#~R»agÑÞU…EÛªÂ΢mUagѶª°ó ý.ìüýŸvŽy ;¿ 'ÿøùÓoÀÇaç÷QØùÁ½„¿|wÂÎnþþ¿aç÷v¾Ãù×°ócøÖðŸàç¸Ãùóßáé;œ}‡sœïpóÎQ¾Ã9Èw8Çøçßáá;œ|‡s|ïpïÎѽÃ9¸wXØÓ'ßÞ~ÂÎ`âtÎ,Ø9²˜Î‰ÅôÉ”§ÜW°t¥°3XÚRØ,})ì –ÆvKg ;ƒ¥5…ÁÒ›ÂÎ`iNag°t§[úËvÆ”îtE–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…/Û]<¦t§›x°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îtã~ÙÂΘҮÛÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óe»WÇ”ît«–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒnÏ/[ØSºÓÕ9XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾lwä˜ÒnÈÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒîÃÁÒÂÎ`éNag°t§›ðËvÆ”ît –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…/Û}7¦t§Ûn°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –ît«}ÙÂΘҮ´ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óe»»Æ”îts –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒn¨/[ØSºÓõ4XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾l÷ИÒn¡ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØù²…1¥;…ÁÒ_èNag|îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;_¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾lagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾lagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØù²…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØù²…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óe ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óe ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;_éNag|î|¥;…ï ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óe ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçËvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éΆ/¼ag©Ï†ES  ;‹¦BvM‰6ì,šmØY4EÚ°³hª´agÑ”iÃ΢©Ó†ES¨ ;‹¦RvM©6ì ÚOF7ì,ÚVùÕè†õî¥ ;‹æfÚ°³hî¦ ;‹ævÚ°³hî§ ;‹æ†Ú°³hî¨ ;‹æ–Ú°³hî© ;‹æ¦Ú°³hï*?&ݰ3>âç¤ví]UØY´wUagÑÞU…E{Wví]UØY´wUagÑÞU…E{Wví]UØY´wUagÑÞU…Aû™é†E{Wù¥é†õ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùê†ñ?Aݰ³hïªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?Mݰ³hï*¿Nݰ³>b« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?Zݰ3>âg«ví]UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvíç¬ví]å­vÖGlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[凮vÆGüÔuÃ΢½« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂΠývÃ΢½«ü vÃÎúˆ­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«ü8vÃÎøˆŸÇnØY´wUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´ŸÍnØY´w•_ÎnØY±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•ÔnØñ“Ú ;‹ö®*ì,ÚVvm« ;‹¶U…_èwaç¿þ3ÂÎ1Oaçwå?ú ø8ìüà> ;?¸×°ó÷'ìüà> ;?¸—°óÎÏð¾„÷†ïüw8?ÀΟÿçHßáè;œã|‡s˜ïpŽòÎA¾Ã9Æw8‡øçßáà;œã{‡sxïpŽîÎÁ½ÃÂΘ>ùööƒvû§sfÁΑÅtN,¦O¦<ý漂¥+…ÁÒ–ÂÎ`éKag°4¦°3X:SØ,­)ì –ÞvKs ;ƒ¥;ÝÒ_¶°3¦t§+z°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|Ùîâ1¥;Ýă¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§÷ËvÆ”îtÝ–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…/Û½:¦t§[u°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –ît{~ÙÂΘҮÎÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óe»#Ç”îtC–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒnÂ/[ØSºÓ58XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾l÷ݘÒn»ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓ­öe ;cJwºÒKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΗíîSºÓÍ5XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKwº¡¾lagLéN×Ó`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØù²ÝCcJwº…Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçËvÆ”îvKw ;ƒ¥;¿ÐÂÎøÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØù²…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØù²…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óe ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óe ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçËvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçËvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΗ-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΗ-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw¾ÒÂÎøÝ)ì|Ù¤;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØù²…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óe ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tgÃÎÞ°³ÆÔgÃ΢)ІES¡ ;‹¦DvM6ì,š"mØY4UÚ°³hÊ´agÑÔiÃ΢)Ô†ES© ;‹¦Tví'£vm«üjtÃÎú÷Ò†Es3mØY4wÓ†Es;mØY4÷Ó†EsCmØY4wÔ†EsKmØY4÷Ô†EsSmØY´w•“nØñsÒ ;‹ö®*ì,Ú»ª°³hïªÂ΢½« ;‹ö®*ì,Ú»ª°³hïªÂ΢½« ;‹ö®*ì,Ú»ª°³hïªÂΠýÌtÃ΢½«üÒtÃÎúˆ­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üuÃÎøˆŸ nØY´wUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ÿ¦nØY´w•_§nØY±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•­nØñ³Õ ;‹ö®*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;ƒösÖ ;‹ö®ò‹Ö ;ë#¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­òC× ;ã#~êºagÑÞU…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagÐ~»agÑÞU~»ag}ÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~»ag|ÄÏc7ì,Ú»ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚÏf7ì,Ú»Ê/g7ì¬ØªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶÊj7ìŒøIí†E{Wvm« ;‹¶U…EÛªÂÎ/ô»°óßüa瘧°ó»ÀòŸ?ý|v~p…ÜKØù»wAéùË?¸ÂÎî%ì|‡ó3<†/açÇð­á;?ÁÎp‡óç¿Ã9Òw8úç8ßáæ;œ£|‡sïpŽñÎ!¾Ã9Âw8øçøÞáÞ;œ£{‡spï°°3¦O¾½ý …ÁþÄé“9O_˜#‹/̉ÅôÉ”§/ÌyKW ;ƒ¥-…ÁÒ—ÂÎ`iLag°t¦°3XZSØ,½)ì –ævKwº¥¿lagLéNWô`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØù²ÝÅcJwº‰Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éN7î—-ìŒ)Ýéº,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;_¶{uLéN·ê`éÎÿ1vo»–g…o%ò·Ç€KÝ2$ìÌž4œ! l”„\?ï(gzÍÕõHN> •­5Ç_>øT#…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§íùÍvÆ”î´:Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ7ÛŽSºÓ†,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;mÂo¶°3¦t§58XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾ÙöݘҶÝ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýi«}³…1¥;­´ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óͶ»Æ”î´¹Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNê›-ìŒ)Ýi= –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…o¶=4¦t§-4XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ßlagLéNag°t§°3XºSØ,Ýù–îvÆ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaç›-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…o¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ßlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØùf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaç›-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ7[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ßlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv¾ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºóKºSØù>¡°3¦tç=Ý)ìŒèNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØùf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaç›-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒv¾ávÖ˜úœ°³h tÂ΢©Ð ;‹¦D'ì,š°³hŠtÂ΢©Ò ;‹¦L'ì,š:°³h uÂ΢©Ô ;‹¦T'ì ÚOFOØY´­ò«ÑvÖ!¼—NØY4o¦vÍ»é„Eóv:agѼŸNØY4o¨vÍ;ê„Eó–:agѼ§NØY4oªví»ÊIO؇ø9é ;‹ö]UØY´ïªÂ΢}Wví»ª°³hßU…Eû®*ì,ÚwUagѾ« ;‹ö]UØY´ïªÂ΢}Wvíg¦'ì,Úw•_šž°³±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m• ž°3ñÔví»ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚOSOØY´ï*¿N=agb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?Z=agâg«'ì,ÚwUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ÿ³ž°³hßU~ÑzÂÎ:ÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~èzÂÎ8ÄO]OØY´ïªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?=agѾ«ü ö„uˆ­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«ü8ö„qˆŸÇž°³hßU…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagÐ~6{Â΢}Wùåì ;ë[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùAí ;ã?©=agѾ« ;‹¶U…EÛªÂ΢mUaçWôë°óçŸ2ìüÙg_|òõWßýèW?ûäíOóvþï~üÛ¯¿úñw¿Þ=€†wЛ/?vþ{vþ (ý'/ÿÜWaçŸ~úúßïO_¸ç°óÿ—á/^Èç°óäKÃ÷Ï_È—á_hø—þ•†ßjø×þ†«áßiø÷þƒ†ÿ¨á?iøK ßkøÏþ‹† ;ãOÿöÉ·—¿ýÂÎb¿áôÉœ§žé{¸úîs¾‡û˜ïá>å{¸ùî3¾‡ûˆïá>á{¸øîó½‡ûxïá>Ý{¸÷¶¿ÇôÉ·—¤°3Ø}´˜>™ótÂ>Y°O¢<±O¦v~p¯ÂÎ÷p?Ãcø*ìü¾4|÷ÜÃý÷pþ{¸Oú‡ûœïá>æ{¸OùîC¾‡ûŒïá>â{¸Oøî¾‡û|ïá>Þ{¸O÷îý‡…1}Çéþ[öNŸÌyùIûßdÆ ûb1}2åé„}¯`éJag°´¥°3XúRØ,)ì –ÎvKk ;ƒ¥7…ÁÒœÂÎ`éN[ú›-ìŒ)ÝiE–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…o¶]<¦t§M}ú¿Í¿û¿_ÿæþëÿöŸÿñ擯¿úîG¿úÙ'oòyg<…Ÿ?»ÂÏß??¸ýÿý#~½Äo¿þâ‹BÒß<þo¾|~þ€Û/ó8ïUøù‹Ï_ÿûí§zp¯ÂÏ÷p?Ócø*üü¾4~÷ÝÃý@÷p?Ï=Ü'÷ÁßÃ}î÷pû=ܧ~÷¡ßÃ}æ÷pù=Ü'~÷ßÃ}Þ÷p÷=ܧ}÷aßÃÂϘ¾ãtÿ­ûäÒË÷öÉœ§é“'OÓ}Ñ8÷É”'vß3XºRø,m)ü –¾~Kc ?ƒ¥3…ŸÁÒšÂÏ`éMág°4§ð3XºÓÿf ?cJwZქ;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNáç›mW)ÝiS–î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒ6ò7[øSºÓ:,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ßl{wLéN[w°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î´]¿ÙÂϘÒVë`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSøùfÛ¡cJwÚ ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw~NwZ˜ãºÓº,ÝiY–î´*¿Ù6å˜Ò_ÐÖä8î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…Ÿo¶}8¦t§m8XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~KwÚzßlágLéN+o°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,ÝùÆî`GÒ£€ð« ¿€‘wA2–þeѶ}°¯s÷pàù©È¥5Ý“Ÿ<>!¥Båe;þ2Rª‚ÂÏ›m·)Ýi³ –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒ6Ø›-üŒ)Ýi} –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…Ÿ7ÛžSºÓ–,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…Ÿ7[øSºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3Xºó+Ý)üŒèNág°t§ð3XºSøy³…Ÿ1¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ðóf ?cJw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ðóf ?cJw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNáçÍ~Æ”î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNáçÍ~Æ”î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ›-üŒ)Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ›-üŒ)Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…Ÿ7[øSºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…Ÿ7[øSºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?o¶ð3¦t§ð3XºSø,Ý)ü –î~Kw^èNágœ@w^èNágœ@w ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSøy³…Ÿ1¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ðóf ?cJw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°tgÂÏžð³ÆÔgÂÏ¢)ЄŸES¡ ?‹¦D~M&ü,š"MøY4Ušð³hÊ4ágÑÔiÂÏ¢)Ô„ŸES© ?‹¦T~í'£~m«üjtÂÏ:„÷Ò„ŸEófšð³hÞM~ÍÛiÂÏ¢y?MøY4o¨ ?‹æ5ágѼ¥&ü,š÷Ô„ŸEó¦šð³hßU~L:ágâç¤~í»ªð³hßU…ŸEû®*ü,ÚwUágѾ« ?‹ö]UøY´ïªÂÏ¢}W~í»ªð³hßU…ŸEû®*ü ÚÏL'ü,Úw•_šNøY‡ØªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶÊP'üŒCüuÂÏ¢}W~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸAûiꄟEû®òëÔ ?ë[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚVùÑꄟqˆŸ­NøY´ïªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U~Çz}±U~Éz}±U~Ëz}±U~Ízù9넟ñßÒZ/¿hð³±U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~í»ªð³hßU…ŸEû®*ü,Úw•ºNø‡ø©ë„ŸEû®*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?ƒöØ ?‹þ—ùì±­ò;Ø«ð³þ‘¶ªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[åDZ~Æ!~;ágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü ÚÏf'ü,Úw•_ÎNøY‡ØªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶÊj'üŒCü¤vÂÏ¢}W~m« ?‹¶U…ŸEÛªÂÏOô›ðói'#ü|ªÏa瘇°ó›pò§¾ï‡ïÜùýaØùÎÿ|å~x”>ówî9ìüý ;ß¹§°óžŸá>| ;߇¯ ßóìáùöðüõïáù¤÷ð|Ð{x>ç=<óžOyχ¼‡ç3ÞÃóïáù„÷ð|À{x>ß=<ïžOwχ»‡…1}ðíõ¹Î¿ À~æôÁœ‡Î'‹Î‹éƒ)'œï,])ì –¶vK_ ;ƒ¥1…ÁÒ™ÂÎ`iMag°ô¦°3XšSØ,ÝiK¿ÙÂΘÒVô`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³íâ1¥;mâÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓÆ}³…1¥;­ÛÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°ófÛ«cJwÚªƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§íùf ;cJwZƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçͶ#Ç”î´!Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –î|¡;-ÄqÝi–î´ KwZ…o¶M8¦t§=8Xºs£;…qÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞlûnLéNÛn°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –î´ÕÞlagLéNag°t§…6XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì¼ÙvטÒ6×`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,ÝiC½ÙÂΘÒÖÓ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³í¡1¥;m¡ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒ_éNagœ@w ;ƒ¥;…7[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;o¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;o¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì¼ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì¼ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºóBw ;ãºóBw ;ãºSØ,Ý)ì –îvKw ;ƒ¥;…7[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;o¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw&ì¼á ;kL}&ì,šMØY4š°³hJ4agÑÔhÂ΢)Ò„ES¥ ;‹¦LvM&ì,šBMØY4•š°³hJ5agÐ~2:agѶʯF'ì¬Cx/MØY4o¦ ;‹æÝ4agѼ&ì,š÷Ó„E󆚰³hÞQvÍ[jÂ΢yOMØY4oª ;‹ö]åǤvÆ!~N:agѾ« ;‹ö]UØY´ïªÂ΢}Wví»ª°³hßU…Eû®*ì,ÚwUagѾ« ;‹ö]UØY´ïªÂΠýÌtÂ΢}Wù¥é„uˆ­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üuÂÎ8ÄOP'ì,ÚwUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ÿ¦NØY´ï*¿N°³±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•­N؇øÙê„Eû®*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[åw¬vÖ!¶ª°³h[UØY´­òsÖ ;ã?h°³h[å7­Wagb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´ïªÂ΢mUagѶª°³h[凮vÆ!~ê:agѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚO`'ì,ú_>ä³Ç¶Êï`'쬤­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùqì„qˆŸÇNØY´­*ì,ÚwUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?›°³hßU~9;agb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?¨°3ñ“Ú ;‹ö]UØY´­*ì,ÚVvm« ;?ÑoÂΧ‰ünØ9æ!ìüñ9œüé㇯Àûaç;÷^ØùÎ?øCØùMPúüÍß¹óŸ¯Ü÷;ì|çžÂÎ{x~†ûð)ì|¾6|ÏO°‡çØÃó׿‡ç“ÞÃóAïáùœ÷ð|Ì{x>å=<òžÏxÏG¼‡çÞÃóïáù|÷ð|¼{x>Ý=<îvÆôÁ·×¤°3ØÏœ>˜ópÂùdqÂùb1}0åá„󽂥+…ÁÒ–ÂÎ`éKag°4¦°3X:SØ,­)ì –ÞvKs ;ƒ¥;mé7[ØSºÓŠ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;o¶]<¦t§M…ïÃ׆ïù öðü{xþú÷ð|Ò{x>è=<Ÿóžyϧ¼‡çCÞÃóïáùˆ÷ð|Â{x>à=<Ÿïžwϧ»‡çÃÝÃÂΘ>øöúƒvû™ÓsN8Ÿ,N8_,¦¦<œp¾W°t¥°3XÚRØ,})ì –ÆvKg ;ƒ¥5…ÁÒ›ÂÎ`iNag°t§-ýf ;cJwZу¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçͶ‹Ç”î´‰Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éN÷ÍvÆ”î´nKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΛm¯Ž)Ýi«–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒ¶ç›-ìŒ)Ýiu–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…7ÛŽSºÓ†,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –î´ KwÚ…ƒ¥;mÂ7[ØSºs£;…qÝ)ì –î´KwÚƒ¥;m¿ÁÒvß`éN›o°t§½7XºÓÖ,Ýiç –î´ñKwÚwo¶°3¦tçgºSØ'ÐÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§­öf ;cJwZiƒ¥;-´ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçͶ»Æ”î´¹Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNêÍvƔKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΛm)Ýi –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΛ-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;¿ÒÂÎû„ÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçÍvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçÍvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΛ-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΛ-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…7[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tç…îvÆ tç…îvÆ t§°3XºSØ,Ý)ì¼ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3Xº3aç OØYcê3agÑhÂ΢©Ð„ES¢ ;‹¦FvM‘&ì,š*MØY4eš°³hê4agÑjÂ΢©Ô„ESª ;ƒö“Ñ ;‹¶U~5:agÂ{iÂ΢y3MØY4ï¦ ;‹æí4agѼŸ&ì,š7Ô„EóŽš°³hÞRvÍ{jÂ΢ySMØY´ï*?&°3ñsÒ ;‹ö]UØY´ïªÂ΢}Wví»ª°³hßU…Eû®*ì,ÚwUagѾ« ;‹ö]UØY´ïªÂ΢}Wvíg¦ví»Ê/M'ì¬ClUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[å¨vÆ!~‚:agѾ« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂΠý4uÂ΢}Wùuê„uˆ­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«ühuÂÎ8ÄÏV'ì,ÚwUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ÿ³NØY´ï*¿h½ü¤õ*쬳mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?t°³h[å·®—»^…u¶­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVví'°vm«ü vÂÎ:ÄVýb«üö*쬳mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•ÇN؇øyì„Eÿ›’Â΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?›°³hßU~9;agb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?¨°3ñ“Ú ;‹ö]UØY´­*ì,ÚVvm« ;?ÑoÂÎÿa瘇°óß~üö¿?ýøíï?ýøû_þóÏo>}üðx?ì|çÞ ;ß¹ç°ó› ôù›¿sï…ïÜSØyÏÏp>…ïÃ׆ïù öðü{xþú÷ð|Ò{x>è=<Ÿóžyϧ¼‡çCÞÃóïáùˆ÷ð|Â{x>à=<Ÿïžwϧ»‡çÃÝÃÂΘ>øöúƒvû™ÓsN8Ÿ,N8_,¦¦<œp¾W°t¥°3XÚRØ,})ì –ÆvKg ;ƒ¥5…ÁÒ›ÂÎ`iNag°t§-ýf ;cJwZу¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçͶ‹Ç”î´‰Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éN÷ÍvÆ”î´nKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΛm¯Ž)Ýi«–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒ¶ç›-ìŒ)Ýiu–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…7ÛŽSºÓ†,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;mÂ7[ØSºÓ,Ýi –î´KwZ€ƒ¥;­¿ÁÒ–ß`éN«o°t§Å7XºÓÚ,Ýié –î´òKwZxo¶}7¦t§ÿc°t§]7XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –î´ÕÞlagLéN+m°t§°3XºÓ:,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì¼ÙvטÒ6×`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,ÝiC½ÙÂΘÒÖÓ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³í¡1¥;m¡ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óf ;cJw~£;…qÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;o¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;o¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì¼ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì¼ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw^èNagœ@w^èNagœ@w ;ƒ¥;…7[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;o¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw&ì¼á ;kL}&ì,šMØY4š°³hJ4agÑÔhÂ΢)Ò„ES¥ ;‹¦LvM&ì,šBMØY4•š°³hJ5agÐ~2:agѶʯF'ì¬Cx/MØY4o¦ ;‹æÝ4agѼ&ì,š÷Ó„E󆚰³hÞQvÍ[jÂ΢yOMØY4oª ;‹ö]åǤvÆ!~N:agѾ« ;‹ö]UØY´ïªÂ΢}Wví»ª°³hßU…Eû®*ì,ÚwUagѾ« ;‹ö]UØY´ïªÂΠýÌtÂ΢}Wù¥é„uˆ­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üuÂÎ8ÄOP'ì,ÚwUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ÿ¦NØY´ï*¿N°³±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•­N؇øÙê„Eû®*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;ƒösÖ ;‹ö]å­vÖ!¶êf«üªõºÙ*¿k½n¶Ê/[¯›­òÛÖëf«üºõºÙ*¿o½n¶Ê/\¯›­ò×ëf«üÊõºÙ*¿s½üÐuÂÎÂO]¯Â΢}Wvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…Aû ì„Eû®ò+Ø ;ë[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùqì„qˆŸÇNØY´ïªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?›°³hßU~9;agb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?¨°3ñ“Ú ;‹ö]UØY´­*ì,ÚVvm« ;?ÑoÂÎÿ`Øù»ï¾ÿæÿÝæë㇘‡°ó+ìüx?ì|çÞ ;ß¹ç°ó› ôù›¿sOaç¿ýõùÏw~Š;÷vÞÃó3܇Oaçûðµá{~‚=â=<ŸðžxÏ织çãÝÃóéîáùp÷°°3¦Ÿ8=ÿ.û™Ós^ÒëÁ“‡éùbqîƒ)ìù^ÁÒ•ÂÎ`iKag°ô¥°3XSØ,)ì –ÖvKo ;ƒ¥9…ÁÒ¶ô›-ìŒ)ÝiE–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…7Û.SºÓ&,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;mÜ7[ØSºÓº,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;o¶½:¦t§­:XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKwÚžo¶°3¦t§Õ9XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞl;rLéNr°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –î´ ßlagLéNkp°t§°3XºÓ ,Ýi–î´þKwZ~ƒ¥;­¾ÁÒß`éNko°t§¥7XºÓÊ,Ýiá½ÙöݘҶÝ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýi«½ÙÂΘÒVÚ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy³í®1¥;m®ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓ†z³…1¥;­§ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°ófÛCcJwÚBƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óf ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçÍvÆ”îvKw~£;…qÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞlagLÿÇÈÝíæy\¾•ÂPX‰Ô¦Eàå(Š’hY”%æ¬жýAöú»×84?j€éI•aìo½“ƒYt§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì¼³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óÎvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaç-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…w¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ïlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì¼³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒ¯t§°3N ;_éNagœ@w ;ïlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì¼³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3Xº³ÂÎ;¼ÂÎSŸvMVØY4ZagÑ”h…ES£vM‘VØY4UZagÑ”i…ES§vM¡VØY4•ZagÑ”j…AûÉè ;‹¶U~5ºÂÎ:„÷Ò ;‹æÍ´Â΢y7­°³hÞN+ì,š÷Ó ;‹æ µÂ΢yG­°³hÞR+ì,š÷Ô ;‹æMµÂ΢}Wù1é ;ã?']agѾ« ;‹ö]UØY´ïªÂ΢}Wví»ª°³hßU…Eû®*ì,ÚwUagѾ« ;‹ö]UØY´ïªÂΠýÌt…Eû®òKÓvÖ!¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­òÔvÆ!~‚ºÂ΢}Wvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…Aûiê ;‹ö]åש+ì¬ClUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[åG«+ìŒCülu…Eû®*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;ƒösÖví»Ê/ZWØY‡ØªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶÊ]W؇ø©ë ;‹ö]UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVví'°+ì,Úw•_Á®°³±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•Ç®°3ñóØví»ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚÏfWØY´ï*¿œ]agb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?¨]agâ'µ+ì,ÚwUagѶª°³h[UØY´­*ìü„~v~ùýóaçÅœ„÷4œ|öò/À³aç_¹gÂοrOÃÎߥ/ÿî3aç_Ï; ;cøæñÄÓ°ó¯äcÃ÷í#ù8¼Ñð†ï5ü á­†?høQÃ5ü¤á†Ÿ5üIÃ/~Õð^Ã?j8agü«?N|{üwœ“½àôÄœ“^“½âôÄ”“®ÉÒ• ;럶LØY,}™°³X3ag±tfÂÎbiÍ„ÅÒ› ;‹¥9vKwfKvÂΚÒYÑ‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ3ºsFw&ì¬sé΄ÅÒ ;ƒ]¼¦tg6ñbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKwfãvÂΚÒY·‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ º3Ûu@wf·.–îÌf],Ý™½:ØKº3[u±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;³=;agMéάÎÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbéÎkº3›r@wfO.–îÌ–\,Ý™9Ø+º3r±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;³ ;agMéάÁÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbéκ3[o@wfç-–îÌÆ[,Ý™}7Økº3Ûn±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;³Õ;agMéά´ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbéÎ[º3l@wf-–îÌöZ,Ý™Ý5غ3›k±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;³¡;agMéά§ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbéÎ;º3Ûh@wf-–îÌ&Z,Ý™=4Ø÷tg¶Ðbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì vÂÎšÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒtçÝ™°³Î¥;vKw&ì vÂÎšÒ ;‹¥;vKwné΄uÝ™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;·tç–îLØYçÒ ;‹¥;v;agMé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØì„5¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;éÎGº3agKw&ì,–îLØì„5¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag°vÖ”îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–î|¢;Ÿè΄u.Ý™°³Xº3ag°vÖ”îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÁNØYSº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xºó™î|¦;vÖ¹tgÂÎbé΄ÁNØYSº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;v;agMé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbéκó…îLØYçÒ ;‹¥;v;agMé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;_é΄uÝùJw&ìŒ&ì¬)Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,ݹ§;÷tgÂÎ:—îLØY,Ý™°3Ø ;kJw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±t§°3àÂÎSŸÂΤ)PagÒT¨°3iJTØ™45*ìLš"v&M• ;“¦L…IS§ÂΤ)TagÒTª°3iJUØY´ŸŒv&m«üj´°3±Ug¶Ê/G ;ól[uf«üz´°3϶Ug¶Ê/H ;ól[uf«Îl•Ÿ‘~GZØ™ÿMlÕ™­ò[ÒÃI ;ëOú9iagÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«&ìLÚVMØ™´­š°3i[un«üÀô˜°3϶Uv&m«&ì,ÚÏL ;“ö]å—¦…yˆ­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«&ìLÚVùééqa«üøô¸°U~~z\Ø*?@-ì¬?A-ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«.m•¥væÙ¾«&ìLÚwÕ„EûijagÒ¾«ü:µ°3±Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛ*?W=^Û*?X=^Û*?Y=^Û*?Z-ì¬?[-ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«®l•²væÙ¾«&ìLÚwÕ„Eû9kagÒ¾«ü¢µ°3±Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛ*?q=ÞØ*?r=ÞØ*?s=ÞØ*?t-ì¬?u-ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«®m•¿væÙ¾«&ìLÚwÕ„Eû lagÒ¾«ü ¶°3±Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛ*?‹=ÞÚ*?Œ=ÞÚ*?=ÞÚ*?Ž-ì¬?-ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«nl•ÌvæÙ¾«&ìLÚwÕ„EûÙlagÒ¾«ür¶°3±Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛ*?¥=ÞÙ*?¦=ÞÙ*?§=ÞÙ*?¨-ì¬?©-ìLÚVMØ™´­š°3i[5agÒ¶jÂÎOéoÂÎ/þаsÌIØù¶°ó/Àóaçî¹°ó÷4ìüMPzþÍ?pÏ…¸'aç}8?ÃÃðIØùaøØðŸ`ΰç_ÿ>œOzνçsÞ‡ó1ïÃù”÷á|Èûp>ã}8ñ>ü¬á|À;9ÿ£°çã݇ó?ûp>Ü}ØþÓùl1ÿ-Àt>ZLOÌyüI[݃/ÓSNN˜ï,])ì –¶vK_ ;ƒ¥1…ÁÒ™ÂÎ`iMag°ô¦°3XšSØ,ÝiK¿³-é1¥;­èÁÒÂÎ`éNëy°t§°3XºÓj,Ý)ì –î´–Kw ;ƒ¥;gt§ƒ¥;ïéNagœ@w ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØyg ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw>ÐÂÎ8î| ;…qÝ)ì¼³…1¥;…ÁÒÂÎ`éNag°tç–îvÆ t§°3XºSØ,Ý)ì –îvKwnéNagœ@wnéNagœ@w ;ïlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒt§°3N ;éNagœ@w ;ïlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒOt§°3N ;ŸèNagœ@w ;ïlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÏt§°3N ;ŸéNagœ@w ;ïlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒ/t§°3N ;_èNagœ@w ;ïlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,ÝùJw ;ï'vÆ”îÜÓÂÎ8îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,ݹ§;…qݹ§;…qÝ)ì¼³…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3Xº³ÂÎ;¼ÂÎSŸvMVØY4ZagÑ”h…ES£vM‘VØY4UZagÑ”i…ES§vM¡VØY4•ZagÑ”j…AûÉè ;‹¶U~5ºÂÎ:„÷ÒQØY4o¦vÍ»é(ì,š·Ó ;‹æýtvÍj…EóŽ: ;‹æ-uøé ;ë[uÆ›êðSÒ£°3ÎöcÒvm«üžô8÷]å¥Ç¹­ò›ÒãÜw•_•ç¶ÊïJsßU~YzœÛ*¿-=Î}Wùuéqn«Îm•˜®°³~K[UØY´ïªÂΠýÌt…EÛ*¿4]ag⻪°³hßU…Eû®*ì,ÚwUagѾ« ;‹ö]UØY´ïªÂ΢m•Ÿž®°³±U…EÛªÂΠýu…EÛ*¿A=.}Wùêqi«üõ¸´U~‰z\Ú*¿E=.m•_£—¶ÊïQK[å©Ç¥­º´U~”ºÂÎú-mUagѶª°3h?M]agѶʯSWØY‡ø®*ì,ÚwUagѾ« ;‹ö]UØY´ïªÂ΢}Wví»ª°³h[åçª+ì¬ClUagѶª°3h?Z]agѶÊïV+ßU~¹z\Ù*¿]=®l•_¯W¶ÊïW+[å¬Ç•­òÖãÊVùëqe«®l•²®°³~K[UØY´­*ì ÚÏYWØY´­ò‹ÖvÖ!¾« ;‹ö]UØY´ïªÂ΢}Wví»ª°³hßU…Eû®*ì,ÚVù‰ë ;ë[UØY´­*ì Ú]WØY´­ò[×ãÚw•_»×¶Êï]k[å¯Çµ­ò›×ãÚVùÕëqm«üîõ¸¶U~ùz\Ûªk[åǯ+ì¬ßÒVvm« ;ƒöØvm«ü v…uˆïªÂ΢}Wví»ª°³hßU…Eû®*ì,ÚwUagѾ« ;‹¶U~»ÂÎ:ÄVvm« ;ƒöãØvm«ü>ö¸ñ]å²Ç­òÙãÆVù•ìqc«üNö¸±U~){ÜØ*¿•=nl•_Ë7¶êÆVùÁì ;ë·´U…EÛªÂΠýlv…EÛ*¿œ]ag⻪°³hßU…Eû®*ì,ÚwUagѾ« ;‹ö]UØY´ïªÂ΢m•ŸÒ®°³±U…EÛªÂΠý v…EÛ*¿©=Þû®ò«Úã½­ò»Úã½­òËÚã½­ÚÞÖ~vþÍ_vŽy ;¿ü~ ;ÿ<v~àž ;?pOÃÎߥçßü÷\Øù{vÞ‡óq? Ÿ„† ßù°÷áüûp>ê}8Ÿô>œzÎç¼çcÞ‡ó)ïÃù÷á|Æûp>â}øYß4œÏwÿÏÇ»çÓ݇óáîÃÂΘžq:_-Ø NOÌyüI ;ã„ùb1=1åä„ù^ÁÒ•ÂÎ`iKag°ô¥°3XSØ,)ì –ÖvKo ;ƒ¥9…ÁÒ¶ô;[ØSºÓŠ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºsFwÚÈãºSØ,Ýi–î´‹ßÙÂΘÒñ`éNkx°t§%ö}8Ÿú>œ}Îg¾ç#߇³”݇?i8Ÿ÷NÎǽçÓÞ‡óaïÃÂϘžq:_5Ø NOÌyüI ?ã„ù¢1=1åä„ùžÁÒ•ÂÏ`iKág°ô¥ð3XSø,)ü –Ö~Ko ?ƒ¥9…ŸÁÒ¶ø;[øSºÓ ,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºsFw ?ãºÓ¾,Ý)ü –î´«ßÙÂϘÒõ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒsºÓ^'ÐÂÏ`éNág°t§üÎ~ƔKw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î\жï8î~Kw ?ƒ¥;íÝw¶ð3¦t§¥;XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°tç’î´cÇ t§ð3XºSø,Ýi»¾³…Ÿ1¥;­ÖÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;¯éN›tœ@w ?ƒ¥;…ŸÁÒvè;[øSºÓ,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºsEwÚ—ãºSø,Ý)ü –î´)ßÙÂϘÒÖä`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒ7t§­8N ;…ŸÁÒÂÏ`éNûð-üŒ)Ýi–î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,ݹ¦;í¾qÝ)ü –î~KwÚzïlágLéN+o°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éÎ[ºÓ†'ÐÂÏ`éNág°t§ÝöÎ~Æ”î´ØKw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –îÜÐöØ8î~Kw ?ƒ¥;m°w¶ð3¦t§õ5XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°tçÝi[èNág°t§ð3XºÓžzg ?cJwZRƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î¼§;…ŸqÝ)ü –î~Kw ?ƒ¥;…Ÿw¶ð3¦t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°tçÝ)üŒèNág°t§ð3XºSøygoéNág°t§ð3XºSø,Ý)ü –î~KwnéNágœ@w ?ƒ¥;…ŸÁÒ[ºSø'ÐÂÏ`éNág°t§ðóÎþ@w ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ðóÎ~Æ”î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î|¤;…ŸqÝ)ü –î~Kw ?ïìt§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ïlágLéNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éÎ'ºSø'ÐÂÏ`éNág°t§ðóÎÞÑÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü¼³…Ÿ1¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;ŸéNágœ@w ?ƒ¥;…ŸÁÒÂÏ;ûÝ)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ;[øSºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3Xºó…î~Æ t§ð3XºSø,Ý)ü¼³_éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~ÞÙÂϘÒ{ºSø'Ð{ºSø'ÐÂÏ`éNág°t§ð3XºSø,Ý)ü –îÜÓÂÏ8î~Kw ?ƒ¥;…Ÿwöt§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~KwVøy‡WøYcê³ÂÏ¢)Ð ?‹¦B+ü,š­ð³hj´ÂÏ¢)Ò ?‹¦J+ü,š2­ð³hê´ÂÏ¢)Ô ?‹¦R+ü,šR­ð3h?]ágѶʯFWøY‡ð^ZágѼ™VøY4ï¦~ÍÛi…ŸEó~ZágѼ¡VøY4ï¨~Í[j…ŸEóžZágѼ©?%= ?ã?&]ágѶÊïIWøY‡ØªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U~`ºÂÏ:ÄwUágѾ« ?ƒö3Ó~m«üÒt…Ÿuˆ­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[å§§+ü¬ClUágѶªð3h?@]ágѶÊoPWøY‡ØªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U~”ºÂÏ:ÄV~m« ?ƒöÓÔ~m«ü:u…Ÿuˆ­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[åçª+ü¬ClUágѶªð3h?Z]ágѶÊïVWøY‡ØªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U~ȺÂÏ:ÄV~m« ?ƒösÖ~m«ü¢u…Ÿuˆ­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[å'®+ü¬ClUágѶªð3h?t]ágѶÊo]WøY‡ØªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U~üºÂÏ:ÄV~m« ?ƒöØ~m«ü v…Ÿuˆ­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[åg±+ü¬ClUágѶªð3h?Ž]ágѶÊïcWøY‡ØªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U~0»ÂÏ:ÄV~m« ?ƒö³Ù~m«ürv…Ÿuˆ­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[å§´+ü¬ClUágѶªð3h?¨]ágѶÊojWøY‡ØªÂÏ¢mUágѶªð³èo­ú&ü<åŸÿûŸÿsÂÍ/þñÅ÷¿™DòÊ:¿úþ$ìsvþÍÓpòÙË—¿Ï‡¸ùÿÓŽþyþÄÿýáÕ«oBÑç= ;ÃÍöá¼§açWOÿûÍOñÀ= ;ïÃù†OÂÎÃdžïüûp~€}8ÿú÷á|Òûp>è}8Ÿó>œyΧ¼çCÞ‡óïÃ; g麓?i8ŸïNÎÇ»çÓ݇óáîÃÂΘžøöøƒóÕ‚½àôÄœ“N<9™Î‹sOL9aç{KW ;ƒ¥-…ÁÒ—ÂÎ`iLag°t¦°3Ø;N©ÍAo ;ã\šSØ,ÝiK¿³…1¥;­èÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;gwdéÎÝ)쌿FwÚÆƒ¥;íâw¶°3¦t§Eyl«ü.öðÃØ£°³~¤­*ì Úc'ì,ÚVù}섵ÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØYôÉc[峇ŸÌ…õ#mUagÐ~6;agѶÊ/g'ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢OÛ*¿¥=ü˜ö(ì¬i« ;ƒöƒÚ ;‹¶U~S;ag-±U…EÛªÂ΢mUagÑ­úv^íäo†cÎÂÎÿñ>œ|ñéÓoÀ·ÃÎoÜúçü§aç7nýçWÒß}ý¹ß ;¿í{vÞ‡ë×ð6|v~~mø®_Á>\¿€}¸þõïÃu¤÷á:Ðûpç}¸ó>\Gy®ƒ¼×1Þ‡' ×ÞÉG Ÿ4\‡wÿ¯¯£»×Á݇…1=óíë/¤°3ØÏœž™s¶aYlX'Ó3SÎ6¬ó –®vK[ ;ƒ¥/…ÁÒ˜ÂÎ`éLag°´æ 6…±â4§°36Ðnéw¶°3¦t§+z°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎݹ ;…±—î\ÐÂÎØ@wº‹ßÙÂΘÒ.âÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;—t§?¨Œ t§[w°t§°3XºÓûÎvÆ”îtÝ–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,ÝùLwú³ÉØ@wº[Kw ;ƒ¥;Ý«ïlagLéN—ê`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒïèNèN7è`éNag°t§Ûó-ìŒ)Ýéê,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3Xºó=ÝéO cÝéž,Ý)ì –îtG¾³…1¥;]ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw~ ;ý¡cl ;݆ƒ¥;…ÁÒnÂw¶°3¦t§kp°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎt§?gŒ t§;o°t§°3XºÓ}÷ÎvÆ”îtÙ –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýù‰îôG‹±ît³ –îvKwºÕÞÙÂΘҮ´ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;?Óþ416Ðî¯ÁÒÂÎ`éNw×;[ØSºÓÅ5XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tçºÓ ƺÓ-5XºSØ,Ýé†zg ;cJwºžKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îüJwú3ÃØ@wº‹Kw ;ƒ¥;ÝCïlagLéN—Ð`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒ/tç Ý)쌽tç Ý)ìŒ t§°óÎvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –î\Ñ+ºSØ{éÎÝ)ìŒ t§°óÎvÆ”îvKw ;ƒ¥;×t§°36ÐÂÎ`éNag°t§°3XºsMw ;cݹ¦;×t§°3öÒkºSØèNaç-ìŒ)Ý)ì –îvKwnèNagl ;…ÁÒÂÎ`éNag°t§°3XºSØ,ݹ¡;…±îÜÐÂÎØ@w ;ïlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎ-ݹ¥;…±—îÜÒÂÎØ@w ;ïlagLéNag°t§°3XºsGw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ tçŽîvƺSØyg ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKwîéÎ=Ý)쌽tçžîvƺSØyg ;cJw ;ƒ¥;…ÁÒÝ)ìŒ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;'ºSØèΉîvƺSØyg ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKwèÎÝ)쌽tçîvƺSØyg ;cJw ;ƒ¥;…ÁÒGºSØèNag°t§°3XºSØ,Ý)ì –îvKwéNagl ;t§°36ÐÂÎ;[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºóDwžèNagì¥;Ot§°36ÐÂÎ;[ØSºSØ,Ý)ì –î<ÓÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºóLw ;cÝy¦;…±îvÞÙÂΘÒÂÎ`éNag°tç…îvƺóBw ;cÝ)ì –îvKw ;ƒ¥;/tç…îvÆ^ºóBw ;cÝ)ì¼³…1¥;…ÁÒÂÎ`éÎ+Ý)ìŒ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;¯t§°36ÐWºSØè΄wxÂÎSŸ ;‹¦@vM…&ì,šMØY45š°³hŠ4agÑTiÂ΢)Ó„ES§ ;‹¦PvM¥&ì,šRMØ´ŸŒNØY´­ò«Ñ ;k ¿KvÍ/Ó„EóÛ4agÑü:MØY4¿OvÍ/Ô„Eó5agÑüJMØY4¿SvÍ/Õ„Eû[åǤvÆ’ÂÎóÿë&ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­òÓ£°³–ø[UØY´¿U…Aû™é„EÛ*¿4°³–تÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~zzvÖ[UØY´­*ì ÚP'ì,ÚVù ꄵÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­ò£Ô£°³–تÂ΢mUagÐ~š:agѶʯS'ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•Ÿ«…µÄVvm« ;ƒö£Õ ;‹¶U~·:ag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üõ(ì¬%¶ª°³h[UØ´Ÿ³NØY´­ò‹Ö ;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[å'®Gag-±U…EÛªÂΠýÐuÂ΢m•ߺNØYKlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?~= ;k‰­*ì,ÚVví'°vm«ü vÂÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùYìQØYKlUagѶª°3h?ް³h[å÷±vÖ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶÊfÂÎZb« ;‹¶U…AûÙì„EÛ*¿œ°³–تÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~J{vÖ[UØY´­*ì Új'ì,ÚVùM턵ÄVvm« ;‹¶U…E´êCØy5‘¿vŽ9 ;ÚÂοß;¿qß ;¿qëÏYØùCPzÝÀ¾që?¿rúÓû¾õ«xãÞ…÷áú5¼ ߅߆_¾ëW°×/`®ýûpé}¸ô>\Çy®Ã¼×QÞ‡ë ïÃuŒ÷á:Äûp]ºîÃu€÷á:¾ûpÞ}¸Žî>\wvÆô‚ÓujÁ~æôÌœ¯¿ÒãÌ“³é:±Ø{fÊ»Î+XºRØ,m)ì –¾vKc ;ƒ¥3…ÁÒšÂÎ`éÍAq ;cÕ9èN·ôû†ÂΘҮèÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;t§°36Ð ºSØèÎÝé.~ßPØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºsIwºwǺSØ,Ý)ì –îtã¾³…1¥;]·ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw>Ón×±îvKw ;ƒ¥;Ý«ïlagLéN—ê`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒïèNwèØ@w ;ƒ¥;…ÁÒnÏw¶°3¦t§«s°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎ÷t§›rl ;…ÁÒÂÎ`éNwä;[ØSºÓ9XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tçºÓ}86ÐÂÎ`éNag°t§›ð-ìŒ)Ýé,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3Xºó#ÝéÖèNag°t§°3XºÓ}÷ÎvÆ”îtÙ –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýù‰ît· t§°3XºSØ,ÝéV{g ;cJwºÒKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îüLwºÁƺSØ,Ý)ì –îtw½³…1¥;]\ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw~¡;ÝScÝ)ì –îvKwº¡ÞÙÂΘҮ§ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;¿Òn£±îvKw ;ƒ¥;ÝCïlagLéN—Ð`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒ/t§°36Ð/t§°36Ð/t§°ó¾¡°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tçŠîvƺsEw ;cݹ¢;…÷ …1¥;…ÁÒÂÎ`éNag°tçšîvƺSØ,Ý)ì –îvKw®éÎ5Ý)쌽tçšîvƺsMw ;ï ;cJw ;ƒ¥;…ÁÒÂÎ`éÎ Ý)ìŒ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;7t§°36кSØyßPØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºsKw ;cݹ¥;…±îÜÒÂÎû†ÂΘÒÂÎ`éNag°t§°3XºsGw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ tçŽîvÞ7vÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îÜÓÂÎØ@wîéNagl ;÷t§°ó¾¡°3¦t§°3XºSØ,Ý)ì –îœèNagl ;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý9ÑÂÎØ@wNt§°ó¾¡°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tçîvƺó@w ;cÝy ;…÷ …1¥;…ÁÒÂÎ`éNag°tç‘îvƺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒGºSØèÎ#Ý)ì¼o(ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýy¢;…±î<ÑÂÎØ@wžèNaç}CagLéNag°t§°3XºSØ,Ýy¦;…±îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tç™îvƺóLw ;ï ;cJw ;ƒ¥;…ÁÒÂÎ`éÎ Ý)ìŒ tç…îvƺSØ,Ý)ì –î¼ÐÂÎØ@w^èNagl ;/t§°ó¾¡°3¦t§°3XºSØ,Ý)ì –î¼ÒÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºóJw ;cÝy¥;vÞWLØYcê3agÑhÂ΢©Ð„ES¢ ;‹¦FvM‘&ì,š*MØY4eš°³hê4agÑjÂ΢©Ô„ESª ;ƒö“Ñ ;‹¶U~5:ag-áwiÂ΢ùeš°³h~›&ì,š_§ ;‹æ÷iÂ΢ù…š°³h~£&ì,š_© ;‹æwjÂ΢ù¥š°³h«ü˜tÂÎXRØYcþÝ„EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~`:ag-ñ·ª°³h« ;ƒö3Ó ;‹¶U~i:ag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üôtÂÎZb« ;‹¶U…Aûê„EÛ*¿A°³–تÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~”:ag-±U…EÛªÂΠý4uÂ΢m•_§NØYKlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?W°³–تÂ΢mUagÐ~´:agѶÊïV'ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•²NØYKlUagѶª°3h?g°³h[å­vÖ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶÊO\'ì¬%¶ª°³h[UØ´ºNØY´­ò[× ;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[åǯvÖ[UØY´­*ì ÚO`'ì,ÚVù섵ÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­ò³Ø ;k‰­*ì,ÚVvíDZvm«ü>vÂÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùÁ섵ÄVvm« ;ƒö³Ù ;‹¶U~9;ag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«ü”vÂÎZb« ;‹¶U…AûAí„EÛ*¿©°³–تÂ΢mUagѶª°³èV};ÿå_;Çœ…?„“/>}ú øvØùûVØù{vþ”^7°oÜúßýOÃÎoÜ»°ó>\¿†·á»°óÛðkÃwý öáúìÃõ¯®#½×Þ‡ë8ïÃu˜÷á:Êûpä}¸Žñ>\‡x®K×}ø¨á:¾;¹ï>\Gw®ƒ» ;czæÛ×_ȱN-ØÏœž™s¶aYlX'Ó3SÎ6¬ó –®vK[ ;ƒ¥/…ÁÒ˜ÂÎ`éLag°´¦°3XzSØ,Í9¨Naç}C·ô˜Ò ºÓ=6ÐÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;t§°36ÐÂÎ`éÎÝ)ì¼oè.SºÓMvÂÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùÁ섵ÄVvm« ;ƒö³Ù ;‹¶U~9;ag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«ü”vÂÎZb« ;‹¶U…AûAí„EÛ*¿©°³–تÂ΢mUagѶª°³èV};ÿ•aç?þñO¿ûûßþñoÿý_¿;>}Š9 ;ÿùo¿ÿŸ¿ÿí÷ÿø?àâ øvØù·Eÿþ—o…߸÷açAéuûƽ ;ÿùïÿùÖ¯â{vÞ‡ë×ð6|v~~mø®_Á>\¿€}¸þõïÃu¤÷á:Ðûpç}¸ó>\Gy®ƒ¼×1Þ‡ëïÃuéº5\Çw'×á݇ëèîÃup÷aagLÏ|ûú éöìgNÏÌ9ÛpæÉÙtXì=3åŒ]ç,])ì –¶vK_ ;ƒ¥1…ÁÒ™ÂÎ`iMag°ô¦°3XšSØ,Ýé–~g/èNag°tç‚îvƺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ t§°3XºSØ,Ýé.~g/éN7ñ`éN÷ð`éN·ð`éNwð`éN7ð`éN÷ï`éN·ï`éNwï`éN7ï`éN÷î`éNag°t§°3XºÓûÎvÆ”îtÝ–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,ÝùLwº]ǺSØ,Ý)ì –ît¯¾³…1¥;]ªƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw¾£;Ý¡cÝ)ì –îvKwº=ßÙÂΘҮÎÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;ßÓnʱîvKw ;ƒ¥;Ý‘ïlagLéNä`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒèN÷áØ@w ;ƒ¥;…ÁÒnÂw¶°3¦t§kp°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎt§[ol ;…ÁÒÂÎ`éN÷Ý;[ØSºÓe7XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tç'ºÓÝ66ÐÂÎ`éNag°t§[í-ìŒ)ÝéJ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3Xºó3ÝéèNag°t§°3XºÓÝõÎvÆ”îtq –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýù…îtO t§°3XºSØ,Ýé†zg ;cJwºžKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îüJwºÆºSØ,Ý)ì –ît½³…1¥;]Bƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw¾ÐÂÎØ@w ;ƒ¥;…ÁÒÂÎ;{Ew ;ƒ¥;Wt§°36ÐÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw®èNagl ;…ÁÒÂÎ`éNa罦;…ÁÒkºSØèNag°t§°3XºSØ,ݹ¦;…±îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óÎÞÐÂÎ`éÎ Ý)ìŒ t§°3XºSØ,Ý)ì –îÜÐÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØygoéNag°tç–îvƺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎ-Ý)ìŒ t§°3XºSØ,Ý)ì¼³wt§°3XºsGw ;cÝ)ì –îvKw ;ƒ¥;wt§°36ÐÂÎ`éNag°t§°3XºSØ,Ý)ì –îvÞÙ{ºSØ,ݹ§;…±îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºsOw ;cÝ)ì –îvKw ;ïì‰îvKwNt§°36ÐÂÎ`éNag°t§°3Xºs¢;…±îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óÎ>ÐÂÎ`éÎÝ)ìŒ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒºSØèNag°t§°3XºSØygéNag°tç‘îvƺSØ,Ý)ì –îvKwéNagl ;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì¼³Ot§°3XºóDw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tç‰îvƺSØ,Ý)ì –îvÞÙgºSØ,Ýy¦;…±îvKw ;ƒ¥;…ÁÒgºSØèNag°t§°3XºSØ,Ý)ì –îvKw ;ïì Ý)ì –î¼ÐÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éÎ Ý)ìŒ tç…îvƺóBw ;cÝ)ì –îvKw ;ïì+Ý)ì –î¼ÒÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éÎ+Ý)ìŒ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;vÞáã =vM&ì,šš°³–P¢ ;‹¦FvM‘&ì,š*MØY4eš°³hê4agÑjÂ΢©Ô„ESª ;ƒö“Ñ ;‹æGiÂ΢ùY:üntÂÎZÂ/Ó„EóÛ4agÑü:MØY4¿OvÍ/Ô„Eó5agÑüJMØY4¿SvÍ/Õ„Eû[åǤvÆ?'°³h[UØY´¿U—¶ÊJK[åg¥Ç¥­òÃÒãÒVùiéqi«ü¸ô¸´U~^z\Ú*?0°³þ}û[UØY´¿U…Aû™é„Eû[å—¦vÖ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶÊOO'ì¬%¶ª°³h[UØ´ NØY´­òÔ ;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[åG©vÖ[UØY´­*ì ÚOS'ì,ÚVùuꄵÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­òsÕ ;k‰­*ì,ÚVvíG«vm«ünuÂÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVù!넵ÄVvm« ;ƒösÖ ;‹¶U~Ñ:ag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üÄuÂÎZb« ;‹¶U…Aû¡ë„EÛ*¿u°³–تÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~ü:ag-±U…EÛªÂΠývÂ΢m•_ÁNØYKlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?‹°³–تÂ΢mUagÐ~;agѶÊïc'ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•ÌNØYKlUagѶª°3h?›°³h[å—³vÖ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶÊOi'ì¬%¶ª°³h[UØ´ÔNØY´­ò›Ú ;k‰­*ì,ÚVvm« ;‹þhÕ‡°óþ a瘳°ó_Þ‡“/>}ú øvØùûVØù{vþ”^·oÜ·ÂÎoÜ»°ó>\¿†·á»°óÛðkÃwý öáúìÃõ¯®#½×Þ‡ë8ïÃu˜÷á:Êûpä}¸Žñ>\‡x®K×}ø¨á:¾;¹ï>\Gw®ƒ» ;czæÛ×_Hag°Ÿ9=3çlÃ:²Ø°N,¦g¦œmXç,])ì –¶vK_ ;ƒ¥1…ÁÒ™ÂÎ`iMag°ô¦°3XšSØ,Ýé–~g ;cJwúÛË`éNô`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;t§°36ÐÂÎ`éNag°t§»ø-ìŒ)Ýé/,ƒ¥;]Ã¥;]ƒ¥;]Áƒ¥;]Àƒ¥;]¿ƒ¥;]¾ƒ¥;]½ƒ¥;—t§{wl ;…ÁÒÂÎ`éN7î;[ØSºÓu;XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tç3ÝévèNag°t§°3XºÓ½úÎvÆ”ît©–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,ÝùŽît‡Ž t§°3XºSØ,Ýéö|g ;cJwº:Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –î|Owº)ǺSØ,Ý)ì –îtG¾³…1¥;]ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw~ ;݇cÝ)ì –îvKwº ßÙÂΘҮÁÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;?Òn½±îvKw ;ƒ¥;ÝwïlagLéN—Ý`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒŸèNwÛØ@w ;ƒ¥;…ÁÒnµw¶°3¦t§+m°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÏt§ll ;…ÁÒÂÎ`éNw×;[ØSºÓÅ5XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tçºÓ=56ÐÂÎ`éNag°t§ê-ìŒ)Ýéz,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3Xºó+Ýé6èNag°t§°3XºÓ=ôÎvÆ”ît –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,ÝùBw ;cÝ)ì –îvKw ;ïlagLéÎÝ)ìŒ tçŠîvƺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒ+ºSØèNag°t§°3XºSØyg ;cJw®éNagl ;×t§°36ÐÂÎ`éNag°t§°3XºsMw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ;[ØSºsCw ;cݹ¡;…±îvKw ;ƒ¥;…ÁÒºSØèNag°t§°3XºSØ,Ý)ì –îvÞÙÂΘÒ[ºSØèÎ-Ý)ìŒ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;·t§°36ÐÂÎ`éNag°t§°óÎvÆ”îÜÑÂÎØ@wîèNagl ;…ÁÒÂÎ`éNag°tçŽîvƺSØ,Ý)ì –îvKw ;ƒ¥;…w¶°3¦tçžîvƺsOw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎ=Ý)ìŒ t§°3XºSØ,Ý)ì¼³…1¥;'ºSØèΉîvƺSØ,Ý)ì –îvKwNt§°36ÐÂÎ`éNag°t§°3XºSØ,Ý)ì¼³…1¥;t§°36кSØèNag°t§°3XºSØ,Ý)ì –îvKwèNagl ;…ÁÒÂÎ`éNaç-ìŒ)Ýy¤;…±î<ÒÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éÎ#Ý)ìŒ t§°3XºSØù»·Ý<°ä°Â¯bÌÓã‘Al`‹lµZ­%JâéÎ0‚8q‚ÌÄÏïZ{Ì©ý rnj˜æú]ö"XºSØ,Ý)ì –îv>ÙÂΘÒ[ºSØèÎ-Ý)ìŒ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;·t§°36ÐÂÎ`éNag°t§°óÉvÆ”îÜÑÂÎØ@wîèNagl ;…ÁÒÂÎ`éNag°tçŽîvƺSØ,Ý)ì –îvKw ;ƒ¥;…O¶°3¦tçžîvƺsOw ;cÝ)ì –îvKw ;ƒ¥;÷t§°36Ð{ºsOw ;c/Ý)ì –îvKw ;ŸlagLéÎÝ)ìŒ tçîvƺSØ,Ý)ì –îvKwèNagl ;…ÁÒÂÎ`éNag°t§°3Xº³ÃÎ'¼ÃÎSŸµèÏ;k ÚagÑth-J´ÃÎZBvØY4EÚagÑTi‡ES¦vMvØY4…ÚagÑTj‡ESªví'£;ì,ÚVùÕèzɯ¥vÖn~1-¿Ýag-áwÓ;‹æ·Ó;‹æ÷Ó;‹æ7Ô;‹æwÔ;‹æ·Ô;‹æ÷Ô;‹æ7Õ;‹öw•“î°3–vÖØßU¶Ê/J×…­ò›ÒUØY?‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•˜î°³–ø»ª°³hWvíg¦;ì,ÚVù¥é;k‰ÿ,ì,Úÿvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[å§§;ì¬%¶ª°³h[UØ´ î°³h[å7¨;ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•¥î°³–تÂ΢mUagÐ~šºÃ΢m•_§î°³–تÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~®ºÃÎZb« ;‹¶U…AûÑê;‹¶U~·ºÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVù!ë;k‰­*ì,ÚVvíç¬;ì,ÚVùEë;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[å'®;ì¬%¶ª°³h[UØ´ºî°³h[å·®;ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•¿î°³–تÂ΢mUagÐ~»Ã΢m•_Áî°³–تÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~»ÃÎZb« ;‹¶U…Aûqì;‹¶U~»ÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùÁì;k‰­*ì,ÚVvíg³;ì,ÚVùåì;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[å§´;ì¬%¶ª°³h[UØ´Ôî°³h[å7µ;ì¬%¶ª°³h[UØY´­*ì,úk«ž‡_üþûaçÍ< ;ÿý×açÿ¾vþûNØù7îyØù« ôüûNØù7îiØÃ×_6> ;ÿF~iø¾ùB~þ¢á[ Õð†W¾×ðƒ†×~Ô𓆟5¼ÑðVÃ; ï5|ÐpÂÎøO?—YÓ N/9}bΗßÞzEö'NŸ˜òdÃÏdéÊ„õÿ Ú2ag±ôeÂÎbiÌ„ÅÒ™ ;‹¥5vKo&ì,–æLØY,Ý™+=Ø ;kJwæD/–îLØY,Ý™ó¼Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw^Ò ;kÝ™°³Xº3ag±tgnñ`'ì¬)Ý™°³Xº3gx±tgŽðbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,ݹ ;sw׺3ag±tgÂÎbéÎ\ÜÁNØYSº3çv±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³XºsIw溮 tgÂÎbé΄ÅÒ¹«ƒ°³¦tgŽêbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tçGº37tm ;vKw&ì,–îÌõì„5¥;s:Kw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;¯èÎ\ʵîLØY,Ý™°³Xº37r°vÖ”îÌ\,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îüDwæ® tgÂÎbé΄ÅÒ¹„ƒ°³¦tgÎàbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tç5Ý™«·6Ð ;‹¥;vKwæÞ vÂΚÒ9v‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒŸéÎܶµîLØY,Ý™°³Xº3Wm°vÖ”îÌI[,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–;sÁÖº3ag±tgÂÎbéÎÜ®ÁNØYSº3‡k±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xºó Ý™;µ6Ð ;‹¥;vKwæB vÂΚÒ9O‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ·tg®ÑÚ@w&ì,–îLØY,Ý™;4Ø ;kJwæ-–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw~¥;vÖº3ag±tgÂÎbé΄ÁNØYSº3ag±tçÝ™°³6ÐwtgÂÎÚ@w&ì,–îLØY,Ý™°³Xº3ag±tçÝ™°³6Ð ;‹¥;vKw&ì vÂÎšÒ ;‹¥;WtgÂÎÚ@w®è΄µîLØY,Ý™°³Xº3ag±tçŠîLØYè΄ÅÒ ;‹¥;vKw&ì vÂÎšÒ ;‹¥;ïé΄µî¼§;vÖº3ag±tgÂÎbé΄ÅÒ÷tgÂÎÚ@w&ì,–îLØY,Ý™°³Xº3ag°vÖ”îLØY,Ýù@w&ì¬ tçÝ™°³6Ð ;‹¥;vKw&ì,–îLØY,Ýù@w&ì¬ tgÂÎbé΄ÅÒ ;ƒ°³¦tgÂÎbéÎ5Ý™°³6Ðkº3agm ;vKw&ì,–îLØY,ݹ¦;vÖº3ag±tgÂÎbé΄ÅÒ ;ƒ°³¦tgÂÎbéÎGº3agm ;é΄µîLØY,Ý™°³Xº3ag±tgÂÎbéÎGº3agm ;vKw&ì,–îLØì„5¥;vKw>Ñ ;kÝùDw&ì¬ tgÂÎbé΄ÅÒ ;‹¥;Ÿè΄µîLØY,Ý™°³Xº3ag±tgÂÎ`'ì¬)Ý™°³Xºó™îLØYèÎgº3agm ;vKw&ì,–îLØY,Ý™°³Xºó™îLØYè΄ÅÒ ;‹¥;v;agMé΄ÅÒº3agm ;7tgÂÎÚ@w&ì,–îLØY,Ý™°³XºsCw&ì¬ tgÂÎbé΄ÅÒ ;‹¥;v;agMé΄ÅÒ[º3agm ;·tgÂÎÚ@w&ì,–îLØY,Ý™°³Xº3ag±tç–îLØYè΄ÅÒ ;‹¥;v;agMé΄ÅÒ;º3agm ;wtgÂÎÚ@w&ì,–îLØY,Ý™°³XºsGw&ì¬ tgÂÎbé΄ÅÒ ;‹¥;v;agMé΄ÅÒ{º3agm ;÷tgÂÎÚ@w&ì,–îLØY,Ý™°³XºsOw&ì¬ tgÂÎbé΄ÅÒ ;‹¥;v;agMé΄ÅÒº3agm ;tgÂÎÚ@w&ì,–îLØY,Ý™°³Xºó@w&ì¬ tgÂÎbé΄ÅÒ ;‹¥;…væ˜úv&MÖ7^‡.*´*ìÌÿIZ´¾ñDtÑ£õG¢‹&­o<]ti}ã¡è¢MëOE}Zßx,ºhÔúÆsÑE§Ö7Œ.[å'£…õK{i«üj´°3—ð{i½´U~9ZØ™»mÕK~9-¿-ìÌݶê%¿ –_væn[õ’_R˯H ;s·­òCÒõÒVù)ézi«ü˜´°³~À ;sìïª ;“¶Uv&íïª ;“¶Uv&íïª ;“¶Uv&íïª ;“¶Uv&íï*?0-ìÌ%üçoMØ™4ÿ\víg¦…IÛ*¿4-ìÌ%¶jÂΤmÕ„IÛª ;“¶Uv&m«&ìLÚVMØ™´­š°3i[å§§…¹ÄVMØ™´­š°³h?@-ìLÚVù jag.±Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛ*?J-ìÌ%¶jÂΤmÕ„EûijagҶʯS ;s‰­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«&ìLÚVù¹jag.±Uv&m«&ì,ÚV ;“¶U~·ZØ™KlÕ„IÛª ;“¶Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶ÊY ;s‰­š°3i[5agÑ~ÎZØ™´­ò‹ÖÂÎ\b«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶U~âZØ™KlÕ„IÛª ;‹öC×ÂΤm•ߺvæ[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«&ìLÚVMØ™´­òã×ÂÎ\b«&ìLÚVMØY´ŸÀv&m«ü ¶°3—ت ;“¶Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤm•ŸÅvæ[5agÒ¶jÂ΢ý8¶°3i[å÷±…¹ÄVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«ü`¶°3—ت ;“¶Uvíg³…IÛ*¿œ-ìÌ%¶jÂΤmÕ„IÛª ;“¶Uv&m«&ìLÚVMØ™´­š°3i[å§´…¹ÄVMØ™´­š°³h?¨-ìLÚVùMmag.±Uv&m«&ìLÚVMØ™ô×V}vþá¿vŽyvþ‡#ìüàûaçGî{açGîyØù« ôü—ä¾v~äž…Ïáü‡ÏÂÎÃ/ ßùœÃùœÃùÏç#}ç}çã|çÃ|ç£|çƒ|çc|çC|?k8à“œï9œï9œî9œî9ì~é|l1O-¦—œ>1ç˯´Ó=6Ì'Ó'¦<Ù0ŸW°t¥«=XÚÒÍ,}éb–Æt¯KgºÖƒ¥5ÝêÁÒ›.õ`iNwz°t§+ýÉv¤Ç”ît¢Kw ;ƒ¥;çÁÒÂÎ`éN§y°t§°3XºÓY,Ý)ì –ît’Kw^ÒîñØ@wºÆƒ¥;ÝâO¶S<¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓÙ,Ýéè–îtr?Ù.î˜ÒKºÓ¹èNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNÇu°t§Ó:XºÓaýd»«cJw~¤;Õ±îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îtBKw: ƒ¥;ÏO¶ë9¦tçÝétŽ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§C9XºÓ™,ÝéH~²ÝÈ1¥;?ÑäØ@w ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw:‡ƒ¥;ÃÁÒNá'Û%SºóšîtǺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓÑ,Ýéä –îtð>ÙîݘҟéNÇnl ;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;¶ÁÒÛ`éNgí“íª)ÝyCw:icÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýé€ –ît¾Kw:^Ÿl·kLéÎ/t§Ã56ÐÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÎÔ`éNGj°t§õÉv¡Æ”î¼¥;§±îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îtŒKw:Eƒ¥;¢O¶;4¦tçWºÓèNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éίt§°36ÐÂÎ`éNaç“-ìŒ)Ý)ì –îvKwÞÑÂÎØ@wÞÑÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tçÝ)ìŒ t§°3XºSØùd ;cJw ;ƒ¥;…ÁÒ+ºSØèÎÝ)ìŒ t§°3XºSØ,Ý)ì –î\ÑÂÎØ@w ;ƒ¥;…ÁÒÂÎ'[ØSºSØ,Ý)ì –î¼§;…±î¼§;…±îvKw ;ƒ¥;…ÁÒ÷t§°36ÐÂÎ`éNag°t§°óÉvÆ”îvKw ;ƒ¥;èNagl ;èNagl ;…ÁÒÂÎ`éNag°t§°3XºóîvƺSØ,Ý)ì|²…1¥;…ÁÒÂÎ`éÎ5Ý)ìŒ tçšîvƺSØ,Ý)ì –îvKw®éNagl ;…ÁÒÂÎ`éNaç“-ìŒ)Ý)ì –îvKw>ÒÂÎØ@w>ÒÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tç#Ý)ìŒ t§°3XºSØùd ;cJw ;ƒ¥;…ÁÒOt§°36ÐOt§°36ÐÂÎ`éNag°t§°3Xºó‰îvƺSØ,Ý)ì –îv>ÙÂΘÒÂÎ`éNag°tç3Ý)ìŒ tç3Ý)ìŒ t§°3XºSØ,Ý)ì –îvKw>ÓÂÎØ@w ;ƒ¥;…O¶°3¦t§°3XºSØ,ݹ¡;…±îÜÐÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éÎ Ý)ìŒ t§°3XºSØ,Ý)ì|²…1¥;…ÁÒÂÎ`éÎ-Ý)ìŒ tç–îvƺSØ,Ý)ì –îvKw ;ƒ¥;·t§°36ÐÂÎ`éNaç“-ìŒ)Ý)ì –îvKwîèNagl ;wt§°36ÐÂÎ`éNag°t§°3XºsGw ;cÝ)ì –îvKw ;ŸlagLéNag°t§°3XºsOw ;cݹ§;…±îvKw ;ƒ¥;…ÁÒ{ºSØèNag°t§°3XºSØùd ;cJw ;ƒ¥;…ÁÒºSØèÎÝ)ìŒ t§°3XºSØ,Ý)ì –î<ÐÂÎØ@w ;ƒ¥;…ÁÒv>ávÖ˜úì°³h ´Ã΢©Ð;‹¦DkÑ¢vÖz´Ã΢iÒ;‹¦K;ì,š6í°³hú´Ã΢iÔ;‹¦S;ì,ÚVùÉè;cIagù­´Ã΢ù½´Ã΢ùÍ´Ã΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~HºÃÎZ¯ªvíǤ;ì,ÚVù=é*ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶê‚ÿüí°³–Ø*¿2]~fºÃÎØí‡¦Ë/MwØYKlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mÕ¥­òëÓui«üþtùê;ãôÔå7¨;ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶêG[åw©ëG[å—©ËOSwØ? §.¿NÝag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U¯l•_¬®W¶ÊoV—­î°3~@?[]~·ºÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«~²U~˺~²U~ͺüœu‡ñúAëò‹ÖvÖ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[õÚVù•ëzm«üÎuù¡ë;ãôS×å·®;ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶêg[å÷¯ëg[å°ËO`wØ? Á.¿‚Ýag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶Uol•_Æ®7¶Êoc—Çî°3~@?]~»ÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«~±U~3»~±U~5»ülv‡ñúáìòËÙvÖ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[õÖVù5ízk«üžvùAí;ãô“Úå7µ;ì¬%¶ª°³h[UØY´­*ì,úk«¾ ;ÿaç¿ý»¿þáÅïŸüŸI'ÿËÿÿÓŸÿÏÿ~ý?þ×ÿü×?ÿãï~øÝ?ý÷ù«ÿ÷¿[|ÑŽ/áç¿?ÂϾ~~ä¾~~䞇Ÿ¿ NÿøøƒýðwÏÂÏ/þæùÏ7¿ªÇ}ÏÂÏçp~MÃgáçÇá—ÆïüŠÎáü‚ÎáüzÎá|äÏá|àÏá|ÜÏá|ØÏá|ÔÏá|ÐÏá|ÌÏá|ÈÏá|ÄÏá|ÀÏá|¼Ïá†óÑ>É ?Ÿh·Ó N/9}bΗ_iágìO4¦OLy²a>Ï`éJág°´¥ð3XúRø,)ü –Î~Kk ?ƒ¥7…ŸÁÒœÂÏ`éNWü“-üŒ)Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kwú;Ì`éN…ùd»ÕcJwúÌ`éNwz°t§+=XºÓ,ÝéB–îtŸKwºÎƒ¥;ÝæÁÒ.ó`éNwy°t§«ÙÂϘÒÂÏ`éNág°t§ð3Xºóžî~ƺóžî~ƺSø,Ý)ü –î~KwÞÓÂÏØ@w ?ƒ¥;…ŸO¶ð3¦t§ð3XºSø,Ý)ü –î| ;…Ÿ±î| ;…Ÿ±î~Kw ?ƒ¥;…ŸÁÒÂÏ`éκSøèNáç“-üŒ)Ý)ü –î~Kw ?ƒ¥;×t§ð36ÐkºSøèNág°t§ð3XºSø,ݹ¦;…Ÿ±î~Kw ?ŸlágLéNág°t§ð3XºSø,ÝùHw ?cÝùHw ?cÝ)ü –î~Kw ?ƒ¥;…ŸÁÒt§ð36ÐÂÏ'[øSºSø,Ý)ü –î~Kw>ÑÂÏØ@w>ÑÂÏØ@w ?ƒ¥;…ŸÁÒÂÏ`éÎ'ºSøèNág°t§ðóÉ~Æ”î~Kw ?ƒ¥;…ŸÁÒÏt§ð36ÐÏt§ð36ÐÂÏ`éNág°t§ð3XºSø,ÝùLw ?cÝ)ü|²…Ÿ1¥;…ŸÁÒÂÏ`éNág°tç†î~ƺsCw ?cÝ)ü –î~Kw ?ƒ¥;7t§ð36ÐÂÏ`éNáç“-üŒ)Ý)ü –î~Kw ?ƒ¥;·t§ð36Ð[ºSøèNág°t§ð3XºSø,Ý)ü –îÜÒÂÏØ@w ?ŸlágLéNág°t§ð3XºSø,ݹ£;…Ÿ±îÜÑÂÏØ@w ?ƒ¥;…ŸÁÒÂÏ`éÎÝ)üŒ t§ð3XºSøùd ?cJw ?ƒ¥;…ŸÁÒÂÏ`éÎ=Ý)üŒ tçžî~ƺSø,Ý)ü –î~KwîéNágl ;…ŸÁÒÂÏ'[øSºSø,Ý)ü –î~KwèNágl ;t§ð36ÐÂÏ`éNág°t§ð3Xºó@w ?cÝ)ü –îìðó ïð³ÆÔg‡ŸES ~M…vøY4%ÚágÑÔh-z´ÃÏZB“vøY4]ÚágÑ´i‡ŸEÓ§~M£vøY4ÚágѶÊOFwøK ?kÌo¥~Íï¥~Ío¦~Íï¦UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶê%¿ªvøKü˜t‡ŸEÛªÂÏ¢ý]ua«ü¤t]Ø*?*]¶ÊÏJ×…­òÃÒua«ü´t]Ø*?.]¶ÊÏK×…­òÓua«üÄt‡Ÿõ»´U~eºÃÏXrù’žø¡é?k‰­º´U~lº.m•Ÿ›®K[å§ëÒVùÉ麴U~tº.m•Ÿ®K[凧ëÒVùé麴U~|º ?ëwi« ?ƒöÔ~íï*¿AÝág-±U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢m•Ÿ¦îð3–øqê?‹öwÕ+[åªë•­òÕõÊVù‘êze«üLu½²U~¨º^Ù*?U]¯l•«®W¶ÊÏU×+[å««ð³~—¶ªð3h?ZÝágÑþ®ò»Õ~Ö[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚVù9ë?c‰´îð³hW½¶U~Ôº^Û*?k]¯m•¶®×¶ÊO[×k[åÇ­ëµ­òóÖõÚVùëzm«üÄu½¶U~äº ?ëwi« ?ƒöC×~íï*¿uÝág-±U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢m•ŸÀîð3–øì?‹öwÕ[凰ë­òSØõÆVù1ìzc«üv½±U~»ÞØ*?‰]ol•Å®7¶ÊÏb×[凱«ð³~—¶ªð3h?ŽÝágÑþ®òûØ~Ö[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚVùÙì?c‰Îîð³hW½µU~<»ÞÚ*?Ÿ]om•Ю·¶ÊOh×[[åG´ë­­ò3ÚõÖVù!ízk«ü”v½µU~L» ?ëwi« ?ƒöƒÚ~íï*¿©Ýág-±U…ŸEÛªÂÏ¢mUágÑ_[õUøùo~žêó“°sÌ“°óÏÃÉ/ÿøâ/À÷ÃÎÜ÷ÂÎܳ°ó?|”žÏó#÷<ìüâùÏ7¿ŠGîYØùίáqø,ìü8üÒð_Á9œ_À9œÿüçpþ¡8‡ó>‡óÄ9œó9œ Îá|ÏáüãpçC|ç†s8às8ÿ(œÃùðžÃùèžÃùàžÃÂΘ>ñíË/dͧì%§OÌy²á‰'O¦ó‰ÅÞ'¦Ù.á˜Òîà`éNag°t§8XºÓ,Ýéþ –îtýKwº}ƒ¥;]¾ÁÒîÞ`éNWo°t§›7XºSØ,ÝéÞ}²…1¥;»ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óÉvÕÆ”îtÓKw ;ƒ¥;ݳÁÒ®Ù`éN·l°t§K6XºÓ,ÝéŠ –îtÃKwº`ƒ¥;ݯÁÒÂÎ`éN·ë“-ìŒ)Ýép –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…O¶ 5¦t§û4XºSØ,Ýé6 –ît™KwºKƒ¥;]¥ÁÒnÒ`éNi°t§{4XºÓ5,Ýé –îvKwºCŸlagLéNGh°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýù•îv>7vÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éÎ;ºSØèÎ;ºSØèNag°t§°3XºSØ,Ý)ì –î¼£;…Ï …1¥;…ÁÒÂÎ`éNag°t§°3XºsEw ;cݹ¢;…±îvKw ;ƒ¥;…ÁÒ+ºSØèNaç“-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒ÷t§°36Ð÷t§°36ÐÂÎ`éNag°t§°3XºóžîvƺSØùd ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°tçÝ)ìŒ tçÝ)ìŒ t§°3XºSØ,Ý)ì –îvKw>ÐÂÎç†ÂΘÒÂÎ`éNag°t§°3XºSØ,ݹ¦;…±î\ÓÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éÎ5Ý)ìŒ t§°óÉvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éÎGºSØèÎGºSØèNag°t§°3XºSØ,Ý)ì –î|¤;…Ï …1¥;…ÁÒÂÎ`éNag°t§°3Xºó‰îvƺó‰îvƺSØ,Ý)ì –îvKw>ÑÂÎØ@w ;ŸlagLéNag°t§°3XºSØ,Ý)ì –î|¦;…±î|¦;…±îvKw ;ƒ¥;…ÁÒÂÎ`éÎgºSØùÜPØSºSØ,Ý)ì –îvKw ;ƒ¥;7t§°36кSØèNag°t§°3XºSØ,ݹ¡;…±îv>ÙÂΘÒÂÎ`éNag°t§°3XºSØ,ݹ¥;…±îÜÒÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tç–îv>7vÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ tçŽîvƺSØ,Ý)ì –îvKwîèNagl ;…O¶°3¦t§°3XºSØ,Ý)ì –îvKwîéNagl ;÷t§°36ÐÂÎ`éNag°t§°3XºsOw ;cÝ)ì|²…1¥;…ÁÒÂÎ`éNag°t§°3Xºó@w ;cÝy ;…±îvKw ;ƒ¥;…ÁÒºSØèÎ;Ÿð;kL}vØY4ÚagÑTh‡ES¢vMvØY4EZ‹&­o<]ti‡õ?I›vØY4}ÚagÑ4j‡EÓ©vm«üdt‡±¤°³ÆüVÚagÑü^ÚagÑüfÚagÑünÚagÑüvZ…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«ü˜t‡±ÄÏIWagÑþ®*ì,ÚßU…Eû»ª°³hWvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[ua«üÈtvÆn?3]~gº ;k‰­º´U~kº ;k·­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­ºôw•ߟ.?@ÝagüOú ê*ì,ÚVùê*ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³hWùiê;c‰§î°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvíG«;ì,ÚÿúÝê;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üœu‡±ÄZwØY´¿« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂΠýÐu‡Eû»Êo]wØYKlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[å'°;ìŒ%~»Ã΢ý]UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvíDZ;ì,ÚßU~»ÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?›Ýag,ñÃÙvíïªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?¨ÝagÑþ®ò›ÚvÖ[UØY´­*ì,ÚVvýµU_…§±ü§ÿûÏÿ6áæþÛ¿ÿÃ$’ÿõÏóÿ~vŽyvþÃópòË?¾ø ðý°ó#7ÿ÷üüiÚÑÿþO/^|оü²ïyØù+n>Ïû¾v~äž…Ïáü‡ÏÂÎÃ/ ßùœÃùœÃùÏç#}ç}çã|çÃ|ç£|çƒ|çc|çC|ç#|ç|çã{çÃ{ç£{çƒ{ ;cúÄ·/¿ÂÎ`Ÿ¸ô„}bΓé|d±a>±˜>1åɆù¼‚¥+…ÁÒ–ÂÎ`éK{°4¦°3X:SØ,­)ì –ÞvKs ;ƒ¥;]éO¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv>Ùnñ˜Ò.ñ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓÍ,Ýéâ~²Ü1¥;…ÁÒŽí`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§ÃúÉvWÇ”îtUKw ;ƒ¥;]ÔÁÒîé`éN×t°t§[:XºÓ%,Ý鎖îtEKwº¡ƒ¥;]ÐÁÒîç`éN×ó“}Ewºƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§ùÉvÆ”ît Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ'Û%SºÓ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;Ý»O¶°3¦t§c7XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv>Ù®Ú˜ÒnÚ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýév}²…1¥;®ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óÉv¡Æ”îtŸKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNwè“-ìŒ)Ýé –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…O¶°3¦tçÝ)ìŒ t§°3XºSØ,Ý)ì –îvKwÞÑÂÎØ@wÞÑÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNaç“-ìŒ)ݹ¢;…±îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ tçŠîvƺSØ,Ý)ì –îvKw®èNaçsCagLéNag°t§°3XºSØ,Ý)ì –îvKwÞÓÂÎØ@wÞÓÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éÎ{ºSØùÜPØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒt§°36Ðt§°36ÐÂÎ`éNag°t§°3XºSØùd ;cJw®éNagl ;…ÁÒÂÎ`éNag°t§°3XºsMw ;cݹ¦;…±îvKw ;ƒ¥;…ÁÒkºSØùÜPØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒt§°36Ðt§°36ÐÂÎ`éNag°t§°3XºSØùd ;cJw>ÑÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tçÝ)ìŒ tçÝ)ìŒ t§°3XºSØ,Ý)ì –î|¢;…Ï …1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,ÝùLw ;cÝùLw ;cÝ)ì –îvKw ;ƒ¥;…O¶°3¦tç†îvƺSØ,Ý)ì –îvKw ;ƒ¥;7t§°36кSØèNag°t§°3XºSØ,ݹ¡;…Ï …1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,ݹ¥;…±îüc÷’bi’@x+¢W µ*»Ô þ$#¢Gñ~Oµí 7O.q#·¢GãP•×~ÏãV/t§°36ÐÂÎ`éNag°t§°3XºSØy²…1¥;¯t§°36ÐÂÎ`éNag°t§°3XºSØ,Ýy¥;…±î¼ÒÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éÎ+Ý)ì<7vÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tçîvƺóFw ;cÝ)ì –îvKw ;ƒ¥;ot§°óÜPØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒwºSØèÎ;Ý)ìŒ t§°3XºSØ,Ý)ì –î¼Óvž+vØYcê³Ã΢)Ð;‹¦B;ì,ší°³hj´Ã΢)Ò;‹¦JGagÑ”é8hÓ;k }ÚagÑ4j‡EÓ©vm«üdt‡±¤°³Æ<•vØY4Ï¥vÍ“i‡EólÚagÑ« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚÏLwØY´Ï*¿4= ;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üu‡±ÄOPwØY´­*ì,ÚV]Ø*?D=.l•Ÿ¢¶ÊQ [åç¨Ç…­òƒÔãÂVùIêqa«ü(õ¸°U~–z\Ø*?L=.l•Ÿ¦î°3~y?NÝagѶª°³h[UØY´ÏªÂ΢}Vví³ª°³hŸU…Eû¬*ì,ÚgUagÑ>« ;‹öYUØY´ÏªÂΠýhu‡Eûo@¿[Ýag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«®l•_²…µÛVvm«üœu‡±ÄZwØY´ÏªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?tÝagÑ>«üÖu‡µÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~»ÃÎXâG°;ì,ÚgUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Çî°³hŸU~»ÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?›Ýag,ñÃÙví³ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚjwØY´Ï*¿©Ýag-±U…EÛªÂ΢mUagÑ_­úv^íäoÃÎ1gaçaçßÀ÷aç·þ=ÿß°ó‰[ÿüàþþ%(½¾ç÷]ØùÄ} ;ÏáúNÃOaçÓð£á»~‚9\?À®?þ9\Ÿô®z×ç<‡ëcžÃõ)Ïáúçp}Æs¸>â9\Ÿð®x×ç;‡ëãÃõéÎáúpç°°3¦?9]_-Ø_œž™óñ“ë“ņõÅbzfÊÙ†õ½‚¥+…ÁÒ–ÂÎ`éKag°4¦°3X:SØ,­)ì –ÞvKs ;ƒ¥;ÝÒO¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvžlwñ˜ÒnâÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓûd ;cJwºnKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΓí^SºÓ­:XºSØ,Ý)ì –îtŸ–ît›–ît—–ît“–ît–ît‹–ît‡–îtƒ–ît–ît{>ÙÂΘÒKºSØèNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓùd ;cJwº Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKwºKw ;ƒ¥;…'ÛM8¦t§{p°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îtß=ÙÂΘÒ.»ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°ód»ÕÆ”ît§ –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒî®'[ØSºÓÅ5XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvžl7Ô˜Òî§ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓ=ôd ;cJwº„Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΓ-ìŒ)Ý)ì –î\ÓÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tçšîvƺsMw ;cÝ)ì –îvKw ;O¶°3¦t§°3XºsCw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒºSØèÎ Ý)ìŒ t§°3XºSØ,Ý)ì<ÙÂΘÒ[ºSØèNag°t§°3XºSØ,Ý)ì –îvKwnéNagl ;·t§°36ÐÂÎ`éNag°t§°ód ;cJwîèNagl ;…ÁÒÂÎ`éNag°t§°3XºSØ,ݹ£;…±îÜÑÂÎØ@w ;ƒ¥;…ÁÒÂΓ-ìŒ)Ý)ì –îÜÓÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tçžîvƺsOw ;cÝ)ì –îvKw ;O¶°3¦tçîvƺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒºSØèÎÝ)ìŒ t§°3XºSØ,Ý)ì<ÙÂΘÒÂÎ`éÎ#Ý)ìŒ t§°3XºSØ,Ý)ì –îvKwéNagl ;t§°36ÐÂÎ`éNag°t§°ód ;cJwžèNagl ;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýy¢;…±î<ÑÂÎØ@w ;ƒ¥;…ÁÒÂΓ-ìŒ)Ý)ì –î<ÓÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tç™îvƺóLw ;cÝ)ì –îvKw ;O¶°3¦tç…îvƺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒºSØèÎ Ý)ìŒ t§°3XºSØ,Ý)ì<ÙÂΘÒÂÎ`éÎ+Ý)ìŒ t§°3XºSØ,Ý)ì –îvKw^éNagl ;¯t§°36ÐÂÎ`éNag°t§°ód ;cJwÞèNagl ;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýy£;…±î¼ÑÂÎØ@w ;ƒ¥;…ÁÒÂΓ-ìŒ)Ýy§;…±îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tçîvƺóNw ;cÝ)ì –îvKw ;Ov‡5¦=ÇA}vØYK(Ð;‹¦B;ì,ší°³hj´Ã΢)Ò;‹¦J;ì,š2í°³hêtôi‡µ„Fí°³h:µÃ΢m•ŸŒî°3–vÖ˜§Ò;‹æ¹´Ã΢y2í°³hžM;ì,š§Ó;‹æù´Ã΢yB…EóŒ: ;‹¶U…EÛªÂ΢mUagѶÊIwØKüœt‡Eû¬*ì,ÚgUagÑ>« ;‹öYUØY´ÏªÂ΢}Vvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?3ÝagÑ>«üÒt‡µÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~€ºÃÎXâ'¨;ì,ÚgUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ÿ¦î°³hŸU~zøyêQØY»mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?ZÝagѶÊïVwØYKlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛª+[å—¬;ì¬Ý¶ª°³h[åç¬;ìŒ%~кÃ΢ý7`agѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagÑ>« ;‹¶U…Aû¡ë;‹öYå·®;ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­òØvÆ?‚ÝagÑ>« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂΠý8v‡Eû¬òûØvÖ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùÙì;c‰Îî°³hŸU…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagÐ~P»Ã΢}VùMí;k‰­*ì,ÚVvm« ;‹þjÕ—°ój"vŽ9 ;ÿ1ÂοïÃÎ'î»°ó‰[ÿ=gaç/Aéõ=Ÿ¸õÏîÇÏÿ~ë§8qŸÂÎs¸~†ÓðSØù4ühø®Ÿ`×0‡ë×'=‡ëƒžÃõ9Ïáú˜çp}Ês¸>ä9\Ÿñ®x×'<‡ëžÃõùÎáúxçp}ºs¸>Ü9,ìŒéON×W ö§gæ|ü¤…±a}±˜ž™r¶a}¯`éJag°´¥°3XúRØ,)ì –ÎvKk ;ƒ¥7…ÁÒœÂÎ`éN·ô“-ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…'Û]<¦t§›x°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îtã>ÙÂΘҮÛÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°ód»WÇ”ît«–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒnÏ'[ØSºÓÕ9XºÓÅ9XºÓµ9XºÓ¥9XºÓ•9XºÓ…9XºÓu9XºÓe9XºÓU9XºÓE9XºÓ59XºÓ%ùd»#Ç”î\Ñ.ȱîvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –ît–îvKw ;O¶›pLéN÷à`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýé¾{²…1¥;]vƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçÉv«)ÝéN,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;Ý]O¶°3¦t§‹k°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì<Ùn¨1¥;ÝOƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§{èÉvÆ”ît –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…'[ØSºSØ,Ý)ì –î\ÓÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tçšîvƺsMw ;cÝ)ì –îvžlagLéNag°t§°3XºsCw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒºSØèÎ Ý)ìŒ t§°3XºSØy²…1¥;…ÁÒ[ºSØèNag°t§°3XºSØ,Ý)ì –îvKwnéNagl ;·t§°36ÐÂÎ`éNaçÉvÆ”îvKwîèNagl ;…ÁÒÂÎ`éNag°t§°3XºSØ,ݹ£;…±îÜÑÂÎØ@w ;ƒ¥;…'[ØSºSØ,Ý)ì –îÜÓÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tçžîvƺsOw ;cÝ)ì –îvžlagLéNag°tçîvƺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒºSØèÎÝ)ìŒ t§°3XºSØy²…1¥;…ÁÒÂÎ`éÎ#Ý)ìŒ t§°3XºSØ,Ý)ì –îvKwéNagl ;t§°36ÐÂÎ`éNaçÉvÆ”îvKwžèNagl ;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýy¢;…±î<ÑÂÎØ@w ;ƒ¥;…'[ØSºSØ,Ý)ì –î<ÓÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tç™îvƺóLw ;cÝ)ì –îvžlagLéNag°tç…îvƺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒºSØèÎ Ý)ìŒ t§°3XºSØy²…1¥;…ÁÒÂÎ`éÎ+Ý)ìŒ t§°3XºSØ,Ý)ì –îvKw^éNagl ;¯t§°36ÐÂÎ`éNaçÉvÆ”îvKwÞèNagl ;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýy£;…±î¼ÑÂÎØ@w ;ƒ¥;…'[ØSºSØ,Ýy§;…±îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tçîvƺóNw ;cÝ)ì –îvžì;kL{vØY4ý9 ´ÃÎZB…vØY4%ÚagÑÔh‡ES¤vM•vØY4eÚagÑÔi‡ES¨ã Q;ì¬%tj‡EÛ*?Ýag,)쬱­úi«ünt‡µ›'Ó;‹æÙ´Ã΢y:í°³hžO;ì,š'Ô;‹æµÃ΢yJ…EÛªÂ΢mUagѶÊIwØKüœt‡EÛªÂ΢}Vví³ª°³hŸU…Eû¬*ì,ÚgUagÑ>« ;‹öYUØY´­*ì,ÚVvm« ;ƒö3Óví³Ê/MwØYKlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[å¨;ìŒ%~‚ºÃ΢}Vvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…Aûiê;‹öYåש;ì¬%¶êÒVù…êqi«üFõ¸´U~¥z\Ú*¿S=.m•_ª—¶ÊoUK[åתǥ­ò{ÕãÒVùÅêqi«üfõð£Õv†~¶zøÝê;k‰­*ì,ÚgUagÑ>« ;‹öYUØY´ÏªÂ΢}Vví³ª°³hŸU…Eû¬º²U~ËzvÖnŸU~κÃÎXâ­;ì,Úvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…Aû¡ë;‹ö߀~ëºÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?Ýag,ñ#Øví³ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚcwØY´Ï*¿Ýag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•ŸÍî°3–øáì;‹öYUØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvíµ;ì,Úg•ßÔî°³–تÂ΢mUagѶª°³è¯V} ;ÿɰó_ÿúã/ÿýŸÿó/ÿû_9þøsvþNþy¾;ÿ^ôo~v>qŸÃÎ_‚Òë{>që¿û#ìü·aç÷)ì<‡ëg8 ?…OÆïú æpýs¸þøçp}Òs¸>è9\Ÿó®y×§<‡ëCžÃõÏáúˆçp}Âs¸>à9\Ÿï®w×§;‡ëÃÃÂΘžùöñƒô¿eû‹Ó3sÎ6¬OÖ‹é™)gÖ÷ –®vK[ ;ƒ¥/…ÁÒ˜ÂÎ`éLag°´¦°3XzSØ,Í)ì –îtK?ÙÂΘÒÂÎ`éNô`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°ód»‹Ç”ît–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒnÜ'[ØSºÓu;XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvžl÷ê˜ÒnÕÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓíùd ;cJwº:Kw ;ƒ¥;]›ƒ¥;]šƒ¥;]™ƒ¥;]˜ƒ¥;]—ƒ¥;]–ƒ¥;]•ƒ¥;]”ƒ¥;]“ƒ¥;]’O¶;rLéN7ä`éÎÝ)ìŒ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§Ëp°t§°ód» Ç”ît–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒî»'[ØSºÓe7XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvžl·Ú˜Òî´ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓÝõd ;cJwº¸Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΓí†SºÓý4XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKwº‡žlagLéN—Ð`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy²…1¥;…ÁÒÂÎ`éNag°tçšîvƺSØ,Ý)ì –îvKw ;ƒ¥;×t§°36ÐkºSØèNaçÉvÆ”îvKw ;ƒ¥;…ÁÒºSØèNag°t§°3XºSØ,Ý)ì –îÜÐÂÎØ@wnèNagl ;…'[ØSºSØ,Ý)ì –îÜÒÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºsKw ;cݹ¥;…±îvžlagLéNag°t§°3XºsGw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ tçŽîvƺSØy²…1¥;…ÁÒÂÎ`éNag°tçžîvƺSØ,Ý)ì –îvKw ;ƒ¥;÷t§°36Ð{ºSØèNaçÉvÆ”îvKw ;ƒ¥;t§°36ÐÂÎ`éNag°t§°3XºSØ,Ý)ì –î<ÐÂÎØ@wèNagl ;…'[ØSºSØ,Ý)ì –îvKwéNagl ;…ÁÒÂÎ`éNag°t§°3XºóHw ;cÝy¤;…±îvžlagLéNag°t§°3XºóDw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ tç‰îvƺSØy²…1¥;…ÁÒÂÎ`éNag°tç™îvƺSØ,Ý)ì –îvKw ;ƒ¥;Ït§°36ÐgºSØèNaçÉvÆ”îvKw ;ƒ¥;/t§°36ÐÂÎ`éNag°t§°3XºSØ,Ý)ì –î¼ÐÂÎØ@w^èNagl ;…'[ØSºSØ,Ý)ì –îvKw^éNagl ;…ÁÒÂÎ`éNag°t§°3XºóJw ;cÝy¥;…±îvžlagLéNag°t§°3XºóFw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ tçîvƺSØy²…1¥;…ÁÒÂÎ`éÎ;Ý)ìŒ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;ït§°36ÐwºSØèNaçÉƴg‡EÓŸvMƒŽƒ í°³–P¢vMvØY4EÚagÑTi‡ES¦vMvØY4…ÚagÑTê8èÔ;k‰­ò“ÑvÆ’ÂÎÛªÂ΢mÕO[å—£;ì¬Ý<›vØY4O§vÍói‡Eó„ÚagÑ<£vØY4O©vÍsê(ì,ÚVvm«ü˜t‡±ÄÏIwØY´­*ì,ÚVví³ª°³hŸU…Eû¬*ì,ÚgUagÑ>« ;‹öYUØY´ÏªÂ΢mUagѶª°3h?3ÝagÑ>«üÒt‡µÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~€ºÃÎXâ'¨;ì,ÚgUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ÿ¦î°³hŸU~ºÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?ZÝag,ñ³Õví³Ê/WÂÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~κÃÎXâ­;ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…Aû¡ë;‹ö߀~ëºÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?Ýag,ñ#Øví³ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚcwØY´Ï*¿Ýag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•ŸÍî°3–øáì;‹öYUØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvíµ;ì,Úg•ßÔî°³–تÂ΢mUagѶª°³è¯V} ;ÿÇ?vŽ9 ;ÿís8ùç?~߇OÜwaç÷9ìü%(½¾ç÷]ØùÄ} ;ÏáúNÃOaçÓð£á»~‚9\?À®?þ9\Ÿô®z×ç<‡ëcžÃõ)Ïáúçp}Æs¸>â9\Ÿð®x×ç;‡ëãÃõéÎáúpç°°3¦g¾}ü …ÁþâôÌœ³ ë“ņõÅbzfÊÙ†õ½‚¥+…ÁÒ–ÂÎ`éKag°4¦°3X:SØ,­)ì –ÞvKs ;ƒ¥;ÝÒO¶°3¦t§°3XºSØ,Ýéz,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì<Ùîâ1¥;Ýă¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§÷ÉvÆ”îtÝ–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…'Û½:¦t§[u°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –ît{>ÙÂΘҮÎÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°ód»#Ç”îtC–îvKwºKwºKwºKwºKwºKwºKwºKwºKwº Kwº Kwº Ÿì?èN÷à`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýé¾{²…1¥;]vƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçÉv«)ÝéN,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;Ý]O¶°3¦t§‹k°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì<Ùn¨1¥;ÝOƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§{èÉvÆ”ît –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…'[ØSºSØ,Ý)ì –îvKw ;ƒ¥;×t§°36ÐÂÎ`éNag°t§°3XºSØ,ݹ¦;…±î\ÓÂÎsCagLéNag°t§°3XºSØ,Ý)ì –îÜÐÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tç†îvƺsCw ;Ï …1¥;…ÁÒÂÎ`éNag°tç–îvƺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒ[ºSØèÎ-Ý)ì<7vÆ”îvKw ;ƒ¥;…ÁÒ;ºSØèNag°t§°3XºSØ,Ý)ì –îvKwîèNagl ;wt§°óÜPØSºSØ,Ý)ì –îvKw ;ƒ¥;÷t§°36ÐÂÎ`éNag°t§°3XºSØ,ݹ§;…±îÜÓÂÎsCagLéNag°t§°3XºSØ,Ýy ;…±îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tçîvƺó@w ;Ï …1¥;…ÁÒÂÎ`éNag°t§°3XºóHw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒGºSØèÎ#Ý)ì<7vÆ”îvKw ;ƒ¥;…ÁÒ'ºSØèNag°t§°3XºSØ,Ý)ì –îvKwžèNagl ;Ot§°óÜPØSºSØ,Ý)ì –îvKw ;ƒ¥;Ït§°36ÐÂÎ`éNag°t§°3XºSØ,Ýy¦;…±î<ÓÂÎsCagLéNag°t§°3XºSØ,Ýy¡;…±îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tç…îvƺóBw ;Ï …1¥;…ÁÒÂÎ`éNag°t§°3XºóJw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒWºSØèÎ+Ý)ì<7vÆ”îvKw ;ƒ¥;…ÁÒ7ºSØèNag°t§°3XºSØ,Ý)ì –îvKwÞèNagl ;ot§°óÜPØSºSØ,Ý)ì –îvKwÞéNagl ;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýy§;…±î¼ÓÂÎsÃ;kL{vØY4ýÙagÑ4h‡EÓ¡ã D;ì¬%Ôh‡ES¤vM•vØY4eÚagÑÔi‡ES¨vM¥vØY4¥:[å'£;ìŒÝ…5¶U…EÛªÂ΢mÕO[å·£;ì¬Ý« ;‹öYUØY´ÏªÂ΢mUagÐ~fºÃ΢}Vù¥é;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üu‡±ÄOPwØY´ÏªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?MÝagÑ>«ü:u‡µÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~´ºÃÎXâg«;ì,ÚgUagѶêÊVùñêqe«ü|õ¸²U~Àz\Ù*?a=®l•±W¶ÊÏX+[凬Ǖ­òSÖãÊVù1ëqe«üœu‡ñËûAë;‹¶U…EÛªÂ΢}Vví³ª°³hŸU…Eû¬*ì,ÚgUagÑ>« ;‹öYUØY´ÏªÂ΢}Vv퇮;ì,Úú­ë;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üv‡±Ä`wØY´ÏªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?ŽÝagÑ>«ü>v‡µÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~6»ÃÎX⇳;ì,ÚgUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ôî°³hŸU~S»ÃÎZb« ;‹¶U…EÛªÂ΢¿Zõ%ìü÷"ìsvþs„߇OÜwaç÷9ìü%(½¾ç÷]ØùÄ} ;ÏáúNÃOaçÓð£á»~‚9\?À®?þ9\Ÿô®z×ç<‡ëcžÃõ)Ïáúçp}Æs¸>â9\Ÿð®x×ç;‡ëãÃõéÎáúpç°°3¦?9]_-Ø_œž™óñ“ë“ņõÅbzfÊÙ†õ½‚¥+…ÁÒ–ÂÎ`éKag°4¦°3X:SØ,­)ì –ÞvKs ;ƒ¥;ÝÒO¶°3¦t§°3XºSØ,Ý)ì –ît9–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì<Ùîâ1¥;Ýă¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§÷ÉvÆ”îtÝ–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…'Û½:¦t§[u°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –ît{>ÙÂΘҮÎÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°ód»#Ç”îtC–îvKw ;ƒ¥;݃¥;ÝŒƒ¥;Ý‹ƒ¥;ÝŠƒ¥;݉ƒ¥;݈ƒ¥;݇ƒ¥;݆ƒ¥;Ý…ƒ¥;Ý„O¶°3¦tçt§°36ÐÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§ûîÉvÆ”îtÙ –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…'Û­6¦t§;m°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îtw=ÙÂΘÒ.®ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°ód»¡Æ”ît? –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒî¡'[ØSºÓ%4XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvžlagLéNag°t§°3XºSØ,Ý)ì –îvKw®éNagl ;…ÁÒÂÎ`éNag°t§°3XºsMw ;cÝ)ì<ÙºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒºSØèNag°t§°3XºSØ,Ý)ì –îÜÐÂÎØ@w ;Oö–îvKw ;ƒ¥;…ÁÒÂÎ`éÎ-Ý)ìŒ t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;·t§°36ÐÂΓ½£;…ÁÒÂÎ`éNag°t§°3XºsGw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ t§°ódïéNag°t§°3XºSØ,Ý)ì –îvKwîéNagl ;…ÁÒÂÎ`éNag°t§°3XºsOw ;cÝ)ì<ÙºSØ,Ý)ì –îvKw ;ƒ¥;t§°36ÐÂÎ`éNag°t§°3XºSØ,Ý)ì –î<ÐÂÎØ@w ;Oö‘îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tç‘îvƺSØ,Ý)ì –îvKw ;ƒ¥;t§°36ÐÂΓ}¢;…ÁÒÂÎ`éNag°t§°3XºóDw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ t§°ódŸéNag°t§°3XºSØ,Ý)ì –îvKwžéNagl ;…ÁÒÂÎ`éNag°t§°3XºóLw ;cÝ)ì<ÙºSØ,Ý)ì –îvKw ;ƒ¥;/t§°36ÐÂÎ`éNag°t§°3XºSØ,Ý)ì –î¼ÐÂÎØ@w ;Oö•îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tç•îvƺSØ,Ý)ì –îvKw ;ƒ¥;¯t§°36ÐÂΓ}£;…ÁÒÂÎ`éNag°t§°3XºóFw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ t§°ódßéNag°t§°3XºSØ,Ý)ì –î¼ÓÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºóNw ;cÝÙaç íÙagÑôg‡EÓ ÿcìÞvû¾Ž ¿Jà(ìÔv’" °UÕÉæA)ê®Ц= Iß¿³¶K‹ÔþµWÅ`a„FëÿSÁ^ÙagÑth‡EÓ¢õÌÑEÖ3DMZÏ<]ti=óPtѦõÌSÑEŸÖ3EZÏ<]tj=ó`´°3þüdt‡Eó£´üjtvÖ[UØY´­*ì,ÚV½àÇiùõè;k·­zÁÔò ÒvÖn[õ‚©åW¤;ì¬Ý¶ê?TË/IwØY»m•“î°3–ø9é;‹¶U…EÛªÂ΢mUagѶª°³hþ£· ;‹¶U…Eó¾UØY´­*ì,šÿø­Â΢mUagÑüpvíg¦;ì,Úß*¿4Ýag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m• î°3–ø ê;‹ö·ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚOSwØY´¿U~ºÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?ZÝag,ñ³ÕvíoUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ÿ³î°³h«ü¢uùIë*ì¬Ý¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´ºî°³h[å·®;ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­òØvÆ?‚ÝagÑþ°°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚcwØY´¿U~»ÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?›Ýag,ñÃÙvíoUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ôî°³h«ü¦v‡µÄVvm« ;‹¶U…EnÕÓ°ó÷_9ì¼™Gaçß~vþ?à‹aç_¸/„áž„ûÙŸûOßþÂ}!ìü ÷8ìŒáËO‡!?5|_"? ßhøVÃ5üIà /5¼ÒðZÃwÞhø^Ã[ ï4ü á½†5œ°3þ£Ÿó½¦ÿÈéœ>2çÓßÞ„µ÷Ÿ9}dÊ£ ¯ÈÒ•¹ÚëO£-s³K_æb/–ÆÌ½^,™k½XZ3·z±ôf.õbiÎÜéÅÒ¹Òƒ°³¦tgNôbé΄ÅÒ ;‹¥;vKwæ4/–îLØY,Ý™³¼Xº3ag±tgNòbé΄ÅÒ9Ç‹¥;v;·xMéÎ\âÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îÌÅì„5¥;snKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°3ع«kJwæª.–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tg®ç`'ì¬)ݙӹXº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÁÎ\Sº3r±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;s ;agMéΜÁÅÒ9‚‹¥;sKwæ.–îÌù[,Ý™ã·Xº3§o±tgßbéΜ½ÅÒ9z‹¥;sòKwæà vîÝšÒWtgŽÝÚ@w&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°3عjkJwæ¦-–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgn×`'ì¬)ݙõXº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÁÎ…ZSº3÷i±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;s‡;agMéΡÅÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw&ì vÂÎšÒ ;‹¥;vKw&ì,–îLØY,Ý™°³Xº3ag±tç'º3agm ;vKw&ì,–îLØY,Ý™°³XºóÝ™°36LØYSºsAw&ì¬ tgÂÎbé΄ÅÒ ;‹¥;vKw.è΄µîLØY,Ý™°³Xº3ag±tgÂÎbéÎÝ™°36LØYSºsIw&ì¬ tgÂÎbé΄ÅÒ ;‹¥;—tgÂÎÚ@w&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbéÎ%Ý™°36LØYSºsEw&ì¬ tgÂÎbé΄ÅÒ ;‹¥;WtgÂÎÚ@w&ì,–îLØY,Ý™°³Xº3ag±tgÂÎbéÎÝ™°36LØYSºsMw&ì¬ tgÂÎbé΄ÅÒ ;‹¥;vKw®é΄µîLØY,Ý™°³Xº3ag±tgÂÎbéÎ5Ý™°36LØYSºóŽîLØYè΄ÅÒ ;‹¥;vKwÞÑ ;kÝ™°³Xº3ag±tgÂÎbé΄ÅÒ ;‹¥;ïè΄±aÂΚÒº3agm ;vKw&ì,–îLØY,Ý™°³XºsCw&ì¬ tgÂÎbé΄ÅÒ ;‹¥;vKwnè΄±aÂΚÒ÷tgÂÎÚ@w&ì,–îLØY,Ý™°³XºóžîLØYè΄ÅÒ ;‹¥;vKw&ì,–îLØY,ÝyOw&ìŒ vÖ”îÜÒ ;kÝ™°³Xº3ag±tgÂÎbé΄ÅÒ[º3agm ;vKw&ì,–îLØY,Ý™°³XºsKw&ìŒ vÖ”îÜÑ ;kÝ™°³Xº3ag±tgÂÎbéÎÝ™°³6Ð ;‹¥;vKw&ì,–îLØY,Ý™°³XºsGw&ìŒ vÖ”î| ;vÖº3ag±tgÂÎbé΄ÅÒ ;‹¥;è΄µîLØY,Ý™°³Xº3ag±tgÂÎbéκ3agl˜°³¦tçžîLØYè΄ÅÒ ;‹¥;vKwîé΄µîLØY,Ý™°³Xº3ag±tgÂÎbé΄ÅÒ{º3agl˜°³¦tç#Ý™°³6Ð ;‹¥;vKw&ì,–î|¤;vÖº3ag±tgÂÎbé΄ÅÒ ;‹¥;vKw>ÒÂÎXQØ™cê³ý)ìÌ%4¨°3i:TØ™4-*ìLšv&M“Ö3ÏD'ìÌ%”iMØ™4uZv&M¡Ö„IS©5agÒ”jMØY´ŸŒv&m«üj´°3—ت ;“¶Uv&m«&ìLÚV½°U~?º&ìÌݶꅭòÒ5agî¶U/l•ß‘® ;s·­za«ü–tù1iagý‘~NZØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶jÂ΢ýÌ´°3i«üÒ´°3—ت ;“¶Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«üµ°³–ø jagÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;‹öÓÔÂΤý­òëÔÂÎ\b«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«&ìLÚVMØ™´­ò£ÕÂÎZâg«…IÛª ;“¶Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«&ì,ÚÏY ;“ö·Ê/Z ;s‰­zi«üªu½´U~׺^Ú*¿l]/m•ß¶®—¶Ê¯[×K[å÷­ë¥­ò ×õÒVùëzi«üÊu½´U~çºüе°³„ðS×å·®…¹ÄVMØ™´¿Uv&íoÕ„Iû[5agÒþVMØ™´¿Uv&íoÕ„Iû[5agÒþVMØ™´¿Uv&ío•ŸÀvÖ?‚-ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«&ìLÚVMØ™´­š°3i[5agÑ~[Ø™´ÿôûØÂÎ\b«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«&ìLÚVMØ™´­ò³ÙÂÎZ⇳…IÛª ;“¶Uv&m«&ìLÚVMØ™´­š°3i[5agÒ¶jÂΤmÕ„IÛª ;“¶Uv&m«&ì,Új ;“ö·Êoj ;s‰­š°3i[5agÒ¶jÂΤ?·ê³°ó7 ;ÿ›¿û滯ýϤ“ÿô?ýÛýÇËý÷ûóßþðÕ7_ýñ÷úÕ_þðÕúöûv< ?ÿî?ÿ |9üüÀ})üüÀ= ?ÿî7OÿÜù›yàž„Ÿ¿ûû§ÜüU=pOÂÏçpþš†OÂÏÃOßù+:‡ótç¯çÎOþÎþÎÏýÎýÎOýÎýÎÏüÎüÎOüÎüÎÏûÎûÎOûÎûvßÇt~֘ίÓù§ÓGæ|ú+-ü v~ј>2åцù=ƒ¥+]õÁÒ–nú`éK}°4¦ð3X:Sø,­)ü –Þ~Ks ?ƒ¥;]ñO¶#>¦t§>XºSø,Ý)ü –î~Kw ?ƒ¥;îÁÒÂÏ`éNG{°t§ð3XºÓÁ,Ý)ü –ît¬?Ùnõ˜Ò.õ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ýé"²ä1¥;ãÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ðóÉvwÇ”îtuKw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éN×õ“í¸Ž)Ýé´–î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸO¶:¦t§ :XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kwº”Ÿl‡rLéNgr°t§ð3XºÓ‰,Ýé@–îtKw:Žƒ¥;ÆÁÒã`éNgq°t§£8XºÓI,Ýé ~²ÝÃ1¥;]ÃÁÒná`éN—p°t§;8XºÓ,Ýé–îtKwºƒ¥;]¿ÁÒnß`éN—o°t§»7XºÓÕûd;zcJw:yƒ¥;¼ÁÒÎÝ`éNÇn°t§S7XºÓ¡,ÝéÌ –îtäKw:qƒ¥;¸ÁÒÎÛ`éNÇí“í¶)ÝyCw:lcÝ)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ŸllLéN÷k°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –ît§>ÙÎÔ˜ÒŽÔ`éNág°t§ð3XºSø,Ý)ü –î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSøùd ?cJw ?ƒ¥;…ŸÁÒÂÏ`éNág°t§ð3XºSø,Ý)ü –îüDw ?cÝ)ü –î~Kw ?ƒ¥;…ŸO¶ð3¦tç‚î~ƺsAw ?cÝ)ü –î~Kw ?ƒ¥;…ŸÁÒ ºSøèNág°t§ð3XºSø,Ý)ü|²…Ÿ1¥;—t§ð36ÐKºSøèNág°t§ð3XºSø,ݹ¤;…Ÿ±î~Kw ?ƒ¥;…ŸÁÒÂÏ`éNáç“-üŒ)ݹ¢;…Ÿ±î\ÑÂÏØ@w ?ƒ¥;…ŸÁÒÂÏ`éÎÝ)üŒ t§ð3XºSø,Ý)ü –î~Kw ?ŸlágLéÎ5Ý)üŒ tçšî~ƺSø,Ý)ü –î~Kw ?ƒ¥;×t§ð36ÐÂÏ`éNág°t§ð3XºSøùd ?cJwÞÑÂÏØ@wÞÑÂÏØ@w ?ƒ¥;…ŸÁÒÂÏ`éÎ;ºSøèNág°t§ð3XºSø,Ý)ü –î~>ÙÂϘÒºSøèÎ Ý)üŒ t§ð3XºSø,Ý)ü –î~KwnèNágl ;…ŸÁÒÂÏ`éNág°t§ðóÉ~Ɣ;…Ÿ±î¼§;…Ÿ±î~Kw ?ƒ¥;…ŸÁÒ÷t§ð36ÐÂÏ`éNág°t§ð3XºSø,Ý)ü|²…Ÿ1¥;·t§ð36Ð[ºSøèNág°t§ð3XºSø,Ý)ü –îÜÒÂÏØ@w ?ƒ¥;…ŸÁÒÂÏ`éNáç“-üŒ)ݹ£;…Ÿ±îÜÑÂÏØ@w ?ƒ¥;…ŸÁÒÂÏ`éÎÝ)üŒ t§ð3XºSø,Ý)ü –î~Kw ?ŸlágLéκSøèκSøèNág°t§ð3XºSø,Ý)ü –î| ;…Ÿ±î~Kw ?ƒ¥;…ŸÁÒÂÏ'[øSºsOw ?cݹ§;…Ÿ±î~Kw ?ƒ¥;…ŸÁÒ{ºSøèNág°t§ð3XºSø,Ý)ü –î~>ÙÂϘÒt§ð36Ðt§ð36ÐÂÏ`éNág°t§ð3Xºó‘î~ƺSø,Ý)ü –î~Kw ?ƒ¥;…ŸOv‡Ÿ5¦=kQŸ~Ö ´žyZøYKèÐ?‹¦E;ü,šíð³hš´ÃÏ¢éÒzæ¡hág-¡N;ü,šBíð³h*µÃÏ¢)Õ?ƒö“Ñ~m«üjt‡Ÿµ„ߥUøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágÑüJ­ÂÏ¢ùÚágÑüR­ÂÏ¢ý­òcÒ~Æ?'ÝágÑþV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~íoUágѶªð3h?3ÝágÑþVù¥é?k‰­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m«üu‡Ÿ±ÄOPwøY´¿U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágÐ~šºÃÏ¢ý­òëÔ~Ö[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚVùÑê?c‰Ÿ­îð³h« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ ýœu‡ŸEû[å­;ü¬%¶ªð³h[UøY´­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­òC×~Æ?uÝágÑþV½²U~îº^Ù*?x]¯l•Ÿ¼®W¶Ê^×+[åg¯ë•­òÃ×õÊVùéëze«üøu½²U~þº^Ù*?€]¯l•ŸÀîð3<)ü¬ñÛ*¿ƒ]¯ý­òKØõÚß*¿…]¯ý­òkØõÚß*¿‡]¯ý­ò‹ØõÚß*¿‰]¯ý­ò«ØõÚß*¿‹]¯ý­òËØõÚß*¿]~»ÃÏÐÇÏc—ßÇîð³–ø[UøY´¿U…ŸEû[UøY´¿U…ŸEû[UøY´¿U…ŸEû[UøY´¿U…ŸEû[UøY´¿U…ŸEû[åg³;üŒ%~8»ÃÏ¢ý­*ü,ÚV~m« ?‹¶U…ŸEÛªÂÏ¢mUágѶªð³h[UøY´­*ü,ÚV~m« ?ƒöƒÚ~íý¦v‡ŸµÄV~m« ?‹¶U…ŸEnÕgáç_3ü<ÕçGaç˜Oaçï¿~N~ñí÷?_;?p_ ;?pOÃο}úçÎïù{vþî)7Ü“°ó9œ¿†‡á“°óÃðSÃwþ ÎáüœÃùÿÎOúÎúÎÏùÎùÎOùÎùÎÏøÎøÎOøÎøÎÏ÷Î÷ÎO÷Î÷vÆô‘oŸþBºÞƒÿ·ÓGæ<ÚðÈ“GÓùÅbÃ#S±ó{KW ;ƒ¥-…ÁÒ—ÂÎ`iL÷z°t¦°3XZSØ,½)ì –ævKwºÒŸlagLéN'z°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|²Ýâ1¥;]âÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓÅýd ;cJw:·ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaç“í®Ž)Ý骖îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒ®ç'[ØSºÓé,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;Ÿl7rLéNr°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –ît ?ÙÂΘÒÎà`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØùd»wcJwºvƒ¥;…ÁÒ.Ý`éNwn°t§+7XºÓ,Ýé –îtßKwºnƒ¥;ݶÁÒ.Û`éNwm°t§«öÉvÆ”îvKw:hƒ¥;³ÁÒŽÙ`éN§l°t§C6XºÓ,Ýéˆ –îtÂKw:`ƒ¥;¯ÁÒŽ×'ÛíSºÓå,Ýé¿°,Ýéj –ît³KwºXƒ¥;Ý«ÁÒ®Õ`éN·j°t§K5XºÓ,ÝéJ –ît£KwºPŸlÿÍĘÒþ{‰ÁÒŽÓ`éN§i°t§Ã4XºÓY,Ýé( –ît’Kw:Hƒ¥;£ÁÒŽÑ`éN§h°t§CôÉv‡Æ”îüHw:BcÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ŸlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎOt§°36ÐÂÎ`éNag°t§°óÉvÆ”îvKw.èNagl ;t§°36ÐÂÎ`éNag°t§°3XºSØ,ݹ ;…±îvKw ;ƒ¥;…O¶°3¦t§°3XºsIw ;cݹ¤;…±îvKw ;ƒ¥;…ÁÒKºSØèNag°t§°3XºSØ,Ý)ì|²…1¥;…ÁÒ+ºSØèÎÝ)ìŒ t§°3XºSØ,Ý)ì –î\ÑÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNaç“-ìŒ)Ý)ì –î\ÓÂÎØ@w®éNagl ;…ÁÒÂÎ`éNag°t§°3XºsMw ;cÝ)ì –îvKw ;ŸlagLéNag°tçÝ)ìŒ tçÝ)ìŒ t§°3XºSØ,Ý)ì –î¼£;…±îvKw ;ƒ¥;…ÁÒÂÎ'[ØSºSØ,ݹ¡;…±îÜÐÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tç†îvƺSØ,Ý)ì –îv>ÙÂΘÒÂÎ`éÎ{ºSØèÎ{ºSØèNag°t§°3XºSØ,ÝyOw ;cÝ)ì –îvKw ;ƒ¥;…O¶°3¦t§°3XºsKw ;cݹ¥;…±îvKw ;ƒ¥;…ÁÒÂÎ`éÎ-Ý)ìŒ t§°3XºSØ,Ý)ì|²…1¥;…ÁÒ;ºSØèÎÝ)ìŒ t§°3XºSØ,Ý)ì –îÜÑÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNaç“-ìŒ)Ý)ì –î| ;…±î| ;…±îvKw ;ƒ¥;…ÁÒÂÎ`éκSØèNag°t§°3XºSØùd ;cJw ;ƒ¥;÷t§°36Ð{ºSØèNag°t§°3XºSØ,ݹ§;…±îvKw ;ƒ¥;…ÁÒÂÎ'[ØSºSØ,ÝùHw ;cÝùHw ;cÝ)ì –îvKw ;ƒ¥;éNagl ;…ÁÒÂÎ`éNag°t§°óÉƴg‡EÓŸµ(Ð;k Z‹í°³–ТvMvØY4MZÏ<]ti‡µ›6­gžŠ.ú´žy,ºhÔzæ¹è¢S뙣ËVùÉè;ãÿøü(-¿Ýag-áwi‡EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U/ø¡Z~IºÃÎÚm«ü˜t‡±ÄÏIwØY´¿U…Eû[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY4ÿ\…Aû™é;‹ö·Ê/MwØYKlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[å¨;ìŒ%~‚ºÃ΢ý­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;ƒöÓÔvío•_§î°³–تÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶÊVwØKülu‡Eû[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvíç¬;ì,Úß*¿hÝag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•ºî°3–ø©ë;‹ö·ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚO`wØY´¿U~»^Û*¿ƒÝagý‘¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[åDZ;ìŒ%~»Ã΢mÕ«üDv½±U~$»ÞØ*?“]ol•Ê®7¶ÊOe×[åDzë­òsÙõÆVùÁìzc«üdv½±U~4»ÞØ*?›ÝagxRØYã<¶U~;»Þú_@¿ž]oý­òûÙõÖß*¿ ]oý­òÚõÖß*¿¢]oý­ò;ÚõÖß*¿¤]oý­ò[ÚõÖß*¿¦]oý­ò{Úåµ;ì }ü¤vùMí;k‰¿U…Eû[UØY´¿U…Eþ­ú,ìü÷ÿ°sÌ£°ó7OÃÉ/¾ýþgàËaçîKaçîiØùwOÿÜù=?p_ ;?pOÂÎçpþ†OÂÎÃO ßù+8‡ópç?þs8?és8ÿLœÃù9ŸÃù'âÎOùÎ?çp~Æçpþi8‡ó>‡óÏÂ9œŸï9œÎáütÏáüsp ;cúÈ·O!…ÁÎ?˜>2çцùÉ‚_,¦Ly´a~¯`éJag°´¥°3XúÒÅ,)ì –Ît­KkºÕƒ¥7]êÁÒœîô`éNWú“-ìŒ)ÝéD–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw:ǃ¥;…O¶[<¦t§KÙÂΘÒNÚ`éNm°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØùd»]cJwº\ƒ¥;…ÁÒ®Ö`éN7k°t§‹5XºÓ½,ÝéZ –ît«KwºTƒ¥;Ý©ÁÒ®Ô`éN7j°t§ õÉvÆ”îvKw:Nƒ¥;¦ÁÒÓ`éNgi°t§£4XºÓI,Ýé –îtŽKw:Fƒ¥;¢ÁÒÑ'ÛSºÓ,Ýù‘îvƺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|²…1¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒŸèNagl ;…ÁÒÂÎ'[ØSºSØ,Ý)ì –î\ÐÂÎØ@w.èNagl ;…ÁÒÂÎ`éNag°t§°3XºsAw ;cÝ)ì –îv>ÙÂΘÒÂÎ`éNag°tç’îvƺsIw ;cÝ)ì –îvKw ;ƒ¥;—t§°36ÐÂÎ`éNag°t§°óÉvÆ”îvKw ;ƒ¥;Wt§°36Ð+ºSØèNag°t§°3XºSØ,ݹ¢;…±îvKw ;ƒ¥;…O¶°3¦t§°3XºSØ,ݹ¦;…±î\ÓÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éNag°tçšîvƺSØ,Ý)ì|²…1¥;…ÁÒÂÎ`éÎ;ºSØèÎ;ºSØèNag°t§°3XºSØ,ÝyGw ;cÝ)ì –îvKw ;ŸlagLéNag°t§°3XºsCw ;cݹ¡;…±îvKw ;ƒ¥;…ÁÒÂÎ`éÎ Ý)ìŒ t§°3XºSØùd ;cJw ;ƒ¥;…ÁÒ÷t§°36Ð÷t§°36ÐÂÎ`éNag°t§°3XºóžîvƺSØ,Ý)ì –îv>ÙÂΘÒÂÎ`éNag°tç–îvƺsKw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒ[ºSØèNag°t§°óÉvÆ”îvKw ;ƒ¥;wt§°36Ð;ºSØèNag°t§°3XºSØ,ݹ£;…±îvKw ;ƒ¥;…O¶°3¦t§°3XºSØ,Ýù@w ;cÝù@w ;cÝ)ì –îvKw ;ƒ¥;…ÁÒt§°36ÐÂÎ`éNaç“-ìŒ)Ý)ì –îvKwîéNagl ;÷t§°36ÐÂÎ`éNag°t§°3XºsOw ;cÝ)ì –îvKw ;ŸlagLéNag°t§°3Xºó‘îvƺó‘îvƺSØ,Ý)ì –îvKw>ÒÂÎØ@w ;ƒ¥;…ÁÒÂÎ'»ÃÎÓžvMvØY4 Z‹ í°³–P¢µhÑ;k =ÚagÑ4i=óL´°³–P¦µhÓ;k }ÚagÑ4j‡EÓ©vm«üdt‡±¤°³Æ¶ê?KËïFwØY»ùeZ…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U/ø©Z~Kºü˜t‡ñGú9é;‹¶U…Eû[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚÏLwØY´¿U~iºÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?@Ýag,ñÔvíoUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ÿ¦î°³h«ü:u‡µÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~´ºÃÎXâg«;ì,ÚߪÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?gÝagÑþVùEë;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üÐu‡±ÄO]wØY´¿U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagÐ~»Ã΢ý­ò+ØvÖ[õÚVù%ì*ì¬Ý¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶÊcwØKü‡ó×ð0|v~~jøÎ_Á9œ¿€s8ÿñŸÃùIŸÃùAŸÃù9ŸÃù1ŸÃù)ŸÃù!ŸÃùŸÃùŸÃù ŸÃùŸÃùùžÃùñžÃùéžÃùážÃÂΘ>òíÓ_Hag°?púÈœGæÿ½À†ùÅbúÈ”Gæ÷ –®vK[ ;ƒ¥/]ìÁÒ˜ÂÎ`éLag°´¦°3XzSØ,Í)ì –ît¥?ÙÂΘÒÂÎ`éNz°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓ1þd»ÅcJwºÄƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§‹ûÉvÆ”îtnKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ'Û]SºÓU,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;]ÏO¶°3¦t§Ó9XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îv>Ùnä˜Ò.ä`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýé~²…1¥;ÁÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°óÉvïÆ”îtíKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNWí“-ìŒ)Ýé¤ –îvKw:gƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…O¶Û5¦t§Ë5XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKwºPŸlagLéNçi°t§ã4XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì|²Ý¡1¥;]¡ÁÒÂÎ`éNh°t§û3XºÓõ,Ýù‘îvƺSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ'[ØSºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îüDw ;cÝ)ì|²…1¥;…ÁÒÂÎ`éNag°tç‚îvƺsAw ;cÝ)ì –îvKw ;ƒ¥;…ÁÒ ºSØèNaç“-ìŒ)Ý)ì –îvKw ;ƒ¥;—t§°36ÐKºSØèNag°t§°3XºSØ,ݹ¤;…±îvKw ;ŸlagLéNag°t§°3XºSØ,ݹ¢;…±î\ÑÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ t§°3XºSØùd ;cJw ;ƒ¥;…ÁÒÂÎ`éÎ5Ý)ìŒ tçšîvƺSØ,Ý)ì –îvKw ;ƒ¥;×t§°36ÐÂÎ'[ØSºSØ,Ý)ì –îvKwÞÑÂÎØ@wÞÑÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éÎ;ºSØèNag°t§°óÉvÆ”îvKw ;ƒ¥;…ÁÒºSØèÎ Ý)ìŒ t§°3XºSØ,Ý)ì –îvKwnèNagl ;…O¶°3¦t§°3XºSØ,Ý)ì –î¼§;…±î¼§;…±îvKw ;ƒ¥;…ÁÒ÷t§°36ÐÂÎ`éNaç“-ìŒ)Ý)ì –îvKw ;ƒ¥;·t§°36Ð[ºSØèNag°t§°3XºSØ,Ý)ì –îÜÒÂÎØ@w ;ŸlagLéNag°t§°3XºSØ,ݹ£;…±îÜÑÂÎØ@w ;ƒ¥;…ÁÒÂÎ`éÎݹ£;wt§°3þ4ºSØùd ;cJw ;ƒ¥;…ÁÒÂÎ`éκSØèκSØèNag°t§°3XºSØ,Ý)ì –î| ;…±îv>ÙÂΘÒÂÎ`éNag°t§°3XºsOw ;cݹ§;…±îvKw ;ƒ¥;…ÁÒ{ºSØèNag°t§°óÉvÆ”îvKw ;ƒ¥;…ÁÒt§°36Ðt§°36ÐÂÎ`éNag°t§°3Xºó‘îvƺSØ,Ý)ì|²;ì¬1íÙagÑôg‡EÓ vM‡Ö¢D;ì¬%Ôh-z´ÃÎZB“Ö3ÏD ;k eÚagÑÔi-ú´ÃÎZB£vØY4ÚagѶÊOFwØK ;ÿ/#÷²birPøUD?€Qµª«dp þ¢ '.çý:í‰Ùøù+šCžSû+§F‚ÍÒn)Ïú£A,mUagѶê ¦Ã/GwØY»y6…EÛªÂ΢mUagѶª°³hžQGagѶª°³h[UØY´­*ì,ÚVù1é;c‰Ÿ“î°³h[UØY´­*ì,ÚgUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagÐ~fºÃ΢}Vù¥é;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«üu‡±ÄOPwØY´ÏªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?MÝagÑ>«ü:u‡µÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~´ºÃÎXâg«;ì,ÚgUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mÕo¶ÊOYÂÎÚm« ;ƒösÖví³Ê/ZwØYKlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[凮;ìŒ%~êºÃ΢}Vvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…Aû ì;‹öYåW°;ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­òãØvÆ?ÝagÑ>« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂΠýlv‡Eû¬òËÙvÖ[õ¯¶Ê¯gÂÎÚm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«ü v‡±ÄOjwØY´ÏªÂ΢mÕ7ŸU~X{|³U~Z{|ûÞªïÂΫünØ9æ,ìü—ËÀò—ŸþÞ;Ÿ¸õ§Yõèÿ^íèÿýÛ/¿|¸Ü÷õmßâ߸¿~¼äÖ_þ´ï½°ó‰»;ÏáúN˰óiøÖð]?Á®Ïzן×'=‡ëƒžÃõ9Ïáú˜çp}Ês¸>ä9\Ÿñ®x×'<‡ëžÃõùÎáúxçp}ºs¸>Ü9,ìŒé™oo?Hag°g.±gæœM×'‹ ë‹ÅôÌ”³ ëß`éJag°´¥°3XúÒ=XSØ,)ì –ÖvKo ;ƒ¥9…ÁÒné'[ØSºSØ,Ý)ì –ît=–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvžlwñ˜ÒnâÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓûd ;cJwºnKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΓí^SºÓ­:XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKwº=ŸlagLéNWç`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy²Ý‘cJwº!Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;݆ƒ¥;…ÁÒnÂ'[ØSºÓ58XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvžl÷ݘÒn»ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºÓ­öd ;cJwºÒKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΓíîSºÓÍ5XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKwº¡žlagLéN×Ó`éNag°t§«i°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°ód»‡Æ”ît –îvKw ;ƒ¥;Ý?ƒ¥;Ý>ƒ¥;…ÁÒot§°36ÐÂÎ`éNag°t§°3XºSØ,Ý)ì<ÙÂΘÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3Xºóot§°óÜPØSºSØ,Ý)ì –îvKw ;ƒ¥;Wt§°36Ð+ºSØèNag°t§°3XºSØ,Ý)ì –î\ÑÂÎsCagLéNag°t§°3XºSØ,Ý)ì –î\ÓÂÎØ@w®éNagl ;…ÁÒÂÎ`éNag°tçšîvƺSØy²…1¥;…ÁÒÂÎ`éNag°t§°3XºsCw ;cݹ¡;…±îvKw ;ƒ¥;…ÁÒºSØèNaçÉvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éÎ-Ý)ìŒ tç–îvƺSØ,Ý)ì –îvKw ;ƒ¥;·t§°óÜPØSºSØ,Ý)ì –îvKw ;ƒ¥;wt§°36Ð;ºSØèNag°t§°3XºSØ,ݹ£;…±îvžlagLéNag°t§°3XºSØ,Ý)ì –îÜÓÂÎØ@wîéNagl ;…ÁÒÂÎ`éNag°t§°3XºsOw ;Ï …1¥;…ÁÒÂÎ`éNag°t§°3Xºó@w ;cÝy ;…±îvKw ;ƒ¥;…ÁÒºSØèNaçÉvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éÎ#Ý)ìŒ tç‘îvƺSØ,Ý)ì –îvKw ;ƒ¥;t§°óÜPØSºSØ,Ý)ì –îvKw ;ƒ¥;Ot§°36Ð'ºSØèNag°t§°3XºSØ,Ý)ì –î<ÑÂÎsCagLéNag°t§°3XºSØ,Ý)ì –î<ÓÂÎØ@wžéNagl ;…ÁÒÂÎ`éNag°t§°3XºóLw ;Ï …1¥;…ÁÒÂÎ`éNag°t§°3XºóBw ;cÝy¡;…±îvKw ;ƒ¥;…ÁÒºSØèNaçÉvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éÎ+Ý)ìŒ tç•îvƺSØ,Ý)ì –îvKw^éNagl ;…'»ÃÎÓžvMvØY4 ÚagÑth‡EÓ¢ãOD ;k E:štüà™hagí¦L;ì,š:í°³h u4j‡µ„Ní°³h[å'£;ìŒ%…5¶U…EÛªÂ΢mÕM‡ßŽî°³vÛªÂ΢mUagѶª°³hžQ;ì,š§ÔQØY´­*ì,ÚVvm«ü˜t‡±ÄÏIwØY´­*ì,ÚVvm« ;‹æ¿òŽÂ΢mUagѶª°³h[UØY´ÏªÂ΢mUagѶª°³h[UØ´Ÿ™î°³hŸU~iºÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?@Ýag,ñÔví³ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚOSwØY´Ï*¿NÝag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•­î°3–øÙê;‹öYUØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[õ›­òSÖvÖn[UØ´Ÿ³î°³hŸU~ѺÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹öYUØY´­òC×vÆ?uÝagÑ>« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂΠýv‡Eû¬ò+ØvÖ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùqì;c‰ŸÇî°³hŸU…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagÐ~6»Ã΢}Vùåì;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«ü v‡±ÄOjwØY´ÏªÂ΢mUagѶª°³h[UØù‚þ.켚È;ÿüó/«ºüûŸþþëOÇÇO1gaçïË_NÀûaç?}øü^ØùÄ­ÿágaç_FØùÄ­ÿ|ã>ýù’[?ʼn»;ÏáúN˰óiøÖð]?Á®`ן×'=‡ëƒžÃõ9Ïáú˜çp}Ês¸>ä9\Ÿñ®x×'<‡ëžÃõùÎáúxçp}ºs¸>Ü9,ìŒé™oo?Hag°_9]ß,Ø3OÎö®/ì™)gìú^ÁÒ•níÁÒ–ÂÎ`éK7ö`iLag°t¦°3XZSØ,½)ì –ævKwº¥ŸlagLéNag°t§°3XºSØ,Ýér,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy²ÝÅcJwº‰Kw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éN7î“-ìŒ)Ýéº,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;O¶{uLéN·ê`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýéö|²…1¥;]ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçÉvGŽ)Ýé†,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –ît–îvKwº ŸlagLéN×à`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØy²ÝwcJwºíKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éN·Ú“-ìŒ)ÝéJ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;O¶»kLéN7×`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ýé†z²…1¥;]Oƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNaçÉv)Ýé,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°tçÝ)ìŒ t§°3XºSØ,Ý)ì –îvžlagLéNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvžìÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ tçŠîvƺSØ,Ý)ì –îvKw ;ƒ¥;…'{Mw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºsMw ;cݹ¦;…±îvKw ;ƒ¥;…ÁÒkºSØyn(ìŒ)Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎ Ý)ìŒ tç†îvƺSØ,Ý)ì –îvKwnèNa繡°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;·t§°36Ð[ºSØèNag°t§°3XºSØ,Ý)ì –îvžìÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ tçŽîvƺSØ,Ý)ì –îvKwîèNa繡°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;÷t§°36Ð{ºSØèNag°t§°3XºSØ,Ý)ì –îvžìÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ tçîvƺSØ,Ý)ì –îvKwèNa繡°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;t§°36ÐGºSØèNag°t§°3XºSØ,Ý)ì –îvžìÝ)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎÝ)ìŒ tç‰îvƺSØ,Ý)ì –îvKw ;ƒ¥;…'ûLw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºóLw ;cÝy¦;…±îvKw ;ƒ¥;…ÁÒÂÎ`éNaçɾÐÂÎ`éNag°t§°3XºSØ,Ý)ì –î¼ÐÂÎØ@w^èNagl ;…ÁÒÂÎ`éNag°tç…îvž ;cJw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºóJw ;cÝy¥;…±îvKw ;ƒ¥;…ÁÒWºSØynØagiÏ;‹¦?;ì,ší°³h:´Ã΢iÑ;‹¦GljvÖªtvM™vØY4uÚagÑj‡ES©ã S;ì¬%¶ÊOFwØK ;kl« ;‹¶U…EÛªÂ΢mÕN‡_…µÛVvm« ;‹æµÃ΢yJí°³hžSGagѶª°³h[åǤ;ìŒ%~NºÃ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…Eû¬*ì,ÚgUagѶª°³h[UØ´Ÿ™î°³hŸU~iºÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?@Ýag,ñÔví³ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚOSwØY´Ï*¿NÝag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•­î°3–øÙê;‹öYUØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­úÍVù1ëQØ»ýœu‡Eû¬ò‹ÖvÖ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVù¡ë;c‰Ÿºî°³hŸU…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagÐ~»Ã΢}Vùì;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«ü8v‡±ÄÏcwØY´ÏªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°3h?›ÝagÑ>«ürv‡µÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~P»ÃÎXâ'µ;ì,ÚgUagѶª°³h[UØY´­*ì|Avþü„cÎÂÎß–¿|üôð~ØùĽv>qçaçOþpl^ù·þþ¿açwvžÃõ3œ†açÓð­á»~‚9\?À®?ÿ®Oz×=‡ësžÃõ1Ïáú”çp}Ès¸>ã9\ñ®Ox×<‡ëóÃõñÎáútçp}¸sXØÓ3ßÞ~ÂÎ`¿rzfÎÙ†õÉbÃúb1=3ålÃú^ÁÒ•ÂÎ`iKwö`éKag°4¦°3X:SØ,­)ì –ÞvKs ;ƒ¥;ÝÒO¶°3¦t§°3XºSØ,Ý)ì –îvKwºšKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì<Ùîâ1¥;Ýă¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§÷ÉvÆ”îtÝ–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…'Û½:¦t§[u°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –ît{>ÙÂΘҮÎÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°ód»#Ç”îtC–îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;Ý…ƒ¥;Ý„O¶°3¦t§kp°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì<Ùî»1¥;Ývƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§[íÉvÆ”ît¥ –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…'ÛÝ5¦t§›k°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îtC=ÙÂΘҮ§ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°ód»‡Æ”ît –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,ÝùFw ;cÝ)ì –îvKw ;O¶°3¦t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;O¶°3¦tçŠîvƺSØ,Ý)ì –îvKw ;ƒ¥;Wt§°36Ð+ºSØèNag°t§°3XºSØ,Ý)ì<ÙÂΘÒkºSØèNag°t§°3XºSØ,Ý)ì –î\ÓÂÎØ@w®éNagl ;…ÁÒÂÎ`éNag°t§°ódoèNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;7t§°36кSØèNag°t§°3XºSØ,Ý)ì<Ù[ºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎ-Ý)ìŒ tç–îvƺSØ,Ý)ì –îvKw ;O¶°3¦tçŽîvƺSØ,Ý)ì –îvKw ;ƒ¥;wt§°36Ð;ºSØèNag°t§°3XºSØ,Ý)ì<Ù{ºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎ=Ý)ìŒ tçžîvƺSØ,Ý)ì –îvKw ;O¶°3¦tçîvƺSØ,Ý)ì –îvKw ;ƒ¥;t§°36кSØèNag°t§°3XºSØ,Ý)ì<ÙGºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂÎ`éÎ#Ý)ìŒ tç‘îvƺSØ,Ý)ì –îvKw ;O¶°3¦tç‰îvƺSØ,Ý)ì –îvKw ;ƒ¥;Ot§°36Ð'ºSØèNag°t§°3XºSØ,Ý)ì<ÙÂΘÒgºSØèNag°t§°3XºSØ,Ý)ì –î<ÓÂÎØ@wžéNagl ;…ÁÒÂÎ`éNag°t§°ód ;cJw^èNagl ;…ÁÒÂÎ`éNag°t§°3XºóBw ;cÝy¡;…±îvKw ;ƒ¥;…ÁÒÂΓ}¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –î¼ÒÂÎØ@w^éNagl ;…ÁÒÂÎ`éNag°tg‡'|´g‡EÓŸvMƒvØY4ÚagÑ´h‡EÓ£vM“Ž<-ì¬%”i‡ES§vM¡vØY4•ÚagÑ”ê8l•ŸŒî°3vvÖØVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY4ϨvÍSj‡EóœÚagÑ<©ŽÂ΢m•“î°3–ø9é;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVví³ª°³hŸU…Eû¬*ì,ÚVvíg¦;ì,Úg•_šî°³–تÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶÊPwØKüu‡Eû¬*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;ƒöÓÔví³Ê¯SwØYKlUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[åG«;ìŒ%~¶ºÃ΢}Vvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…Aû9ë;‹öYå­;ì¬%¶ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­òC×vÆ?uÝagÑ>« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂΠýv‡Eû¬ò+ØvÖ[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVùqì;c‰ŸÇî°³hŸU…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagÐ~6»Ã΢}Vùåì;k‰­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm«ü v‡±ÄOjwØY´ÏªÂ΢mUagѶª°³h[UØù‚þ.ìü× ìsvþtXþòñÓÀûaç÷^ØùÄ]†¾ü箿ü‰{/ì|â.ÂÎs¸~†Óð"ì|¾5|×O0‡ë˜ÃõçŸÃõIÏáú çp}Îs¸>æ9\Ÿò®y×g<‡ë#žÃõ Ïáú€çp}¾s¸>Þ9\Ÿî®w ;czæÛÛRØìWNÏÌ9Û°>YlX_,¦g¦œmXß+XºRØ,m)ì –¾tc–ÆvKg ;ƒ¥5…ÁÒ›ÂÎ`iNag°t§[úÉvÆ”îvKw ;ƒ¥;…ÁÒÂÎ`éNag°t§°3XºSØ,Ý)ì –îvKw ;ƒ¥;…ÁÒÂΓí.SºÓM«üÒt‡µÄVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U~€ºÃÎXâ'¨;ì,ÚgUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØ´Ÿ¦î°³hŸU~ºÃÎZb« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛ*?ZÝag,ñ³Õví³ª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì ÚÏYwØY´Ï*¿hÝag-±U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢m•ºî°3–ø©ë;‹öYUØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶª°³h[UØY´­*ì,ÚVví'°;ì,Úg•_Áî°³–تÂ΢mUagѶª°³h[UØY´­*ì,ÚVvm« ;‹¶U…EÛªÂ΢mUagѶÊcwØKü—Uþ÷ÿøý?¿ü×ÿüúÓ‡Ÿþö/¿ÿéï¿þt|üÔç,ôüù2¸üå¼zþcчÏï…žOÜeèù/—ÿÜõKœ¸÷BÏ'î"ô<‡ëg9 /Bϧá[Ówý$s¸~9\?Ç®O|×>‡ëóžÃõqÏáú´çp}Øs¸>ë9\õ®Oz×=‡ësžÃõ1Ïáú”çp}ÈsXèÓ3ßÞ~BÏ`¿rzfÎÙ†õ cÃú‚1=3ålÃú~ÁÒ•BÏ`iK¡g°ô¥|°4¦Ð3X:Sè,­)ô –ÞzKs =ƒ¥;ÝÚO¶Ð3¦t§+{°t§Ð3XºSè,Ý)ô –îzKw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô<Ùîæ1¥;Ý̃¥;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô –îzKw =ƒ¥;…žÁÒBÏ`éN¡g°t§øÉzÆ”îtý–îzKw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô –îzKw =ƒ¥;…ž'Û=;¦t§[v°t§Ð3XºSè,Ý)ô –îzKw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô –ît›>ÙBϘҮÒÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô –îzKw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ðód»3Ç”îtc–îzKw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô –îzKw =ƒ¥;…žÁÒnÆ'[èSºÓµ8XºSè,Ý)ô –îzKw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô –îzžl÷ߘÒn¿ÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô –îzKw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ð3XºÓ-÷d =cJwºâKw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô –îzKw =ƒ¥;…žÁÒBÏ“í.SºÓM6XºSè,Ý)ô –îzKw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô –îzKwº±žl¡gLéN×Õ`éN¡g°t§Ð3XºSè,Ý)ô –îzKw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ð3XºSèy²ÝKcJwº•Kw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô –îzKw =ƒ¥;ßèN¡gl ;…ž'[èSºSè,Ý)ô –îzKw =ƒ¥;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ý)ô –îzKw =ƒ¥;…ž'[èSºSè,Ý)ô –î\ÑBÏØ@w =ƒ¥;…žÁÒBÏ`éN¡g°tçŠîzƺsEw =cÝ)ô –îzžl¡gLéN¡g°t§Ð3XºsMw =cÝ)ô –îzKw =ƒ¥;…žÁÒkºSèèÎ5Ý)ôŒ t§Ð3XºSèy²…ž1¥;…žÁÒºSèèN¡g°t§Ð3XºSè,Ý)ô –îzKwnèN¡gl ;7t§Ð36ÐBÏ`éN¡çÉzÆ”îzKwnéN¡gl ;…žÁÒBÏ`éN¡g°t§Ð3XºSè,ݹ¥;…ž±îÜÒBÏØ@w =ƒ¥;…ž'[èSºSè,Ý)ô –îÜÑBÏØ@w =ƒ¥;…žÁÒBÏ`éN¡g°tçŽîzƺsGw =cÝ)ô –îzžl¡gLéN¡g°tçžîzƺSè,Ý)ô –îzKw =ƒ¥;…žÁÒ{ºSèèÎ=Ý)ôŒ t§Ð3XºSèy²…ž1¥;…žÁÒBÏ`éÎÝ)ôŒ t§Ð3XºSè,Ý)ô –îzKwèN¡gl ;t§Ð36ÐBÏ`éN¡çÉzÆ”îzKwéN¡gl ;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ýy¤;…ž±î<ÒBÏØ@w =ƒ¥;…ž'[èSºSè,Ý)ô –î<ÑBÏØ@w =ƒ¥;…žÁÒBÏ`éN¡g°tç‰îzƺóDw =cÝ)ô –îzžl¡gLéN¡g°t§Ð3XºóLw =cÝ)ô –îzKw =ƒ¥;…žÁÒgºSèèÎ3Ý)ôŒ t§Ð3XºSèy²…ž1¥;…žÁÒBÏ`éÎ Ý)ôŒ t§Ð3XºSè,Ý)ô –îzKw^èN¡gl ;/t§Ð36ÐBÏ`éN¡çÉzÆ”îzKw^éN¡gl ;…žÁÒBÏ`éN¡g°t§Ð3XºSè,Ýy¥;…ž±î¼ÒBÏØ@w =ƒ¥;;ô<ázÖ˜úìгh t4h‡žµ„íгhZ´CÏ¢éÑ=‹¦IÇž‰zÖÊ´CÏ¢©Ó=‹¦P;ô,šJíгhJµCÏ ýdt‡žEÛ*¿Ý¡g-±U…žEÛªBÏ¢mU¡gѶªÐ³h[UèY´­*ô,šgÔ=‹æ)µCÏ¢yNíгhžT;ô,Úg•“îÐ3–ø9é=‹öYUèY´­*ô,ÚVzm« =‹¶U…žEÛªBÏ¢mU¡gÑ>« =‹öYUèY´ÏªBÏ¢}Vzíg¦;ô,Úg•_šîг–تBÏ¢mU¡gѶªÐ³h[UèY´­*ô,ÚVzm« =‹¶U…žEÛªBÏ¢mU¡gѶÊPwèKüu‡žEû¬*ô,ÚVzm« =‹¶U…žEÛªBÏ¢mU¡gѶªÐ³èÿ#íÜv£¸¢ ú+?îÁ3‘) äJî7”^€(Nòý©ê¡zïå ©´Üö¯Ó:{†.³U.z&š­rÑ3Ñl•‹ž‰f«\ô 4?šº=Í÷*~:u)z¦‹°U.z&š­rÑ3Ñl•‹ž‰f«\ôL4[å¢g¢Ù*=ÍV¹è™h¶ÊEÏD³U.z&š­rÑ3Ñl?´º=ÃEø±Õ¥è™h¾W¹è™h¶ÊEÏD³U.z&š­rÑ3Ñl•‹ž‰f«\ôL4[å¢g¢Ù*=ÍV¹è™h¶ÊEÏD³U.zšg]Šž‰æ{?Ѻ=ÓEØ*=ÍV¹è™h¶ÊEÏD³U.z&š­rÑ3Ñl•‹ž‰f«\ôL4[å¢g¢Ù*=ÍV¹è™h¶Št]Šžá"ü¨ëRôL4ß«\ôL4[å¢g¢Ù*=ÍV¹è™h¶ÊEÏD³U.z&š­rÑ3Ñl•‹ž‰f«\ôL4[å¢g¢Ù*=ÍÀ.EÏD󽊟‚]Šžé"l•‹ž‰f«\ôL4[å¢g¢Ù*=ÍV¹è™h¶ÊEÏD³U.z&š­rÑ3Ñl•‹ž‰f«\ôL4[ÅÇ.EÏp~/_Û Ÿl‹—¯/ÞóƒmAóÅ–{xw¹å׋œÓqË=.îJUÕŸÞ»Õü÷gÇiWH}S\Õ8?¡ði…Z˜vÅzÅ»UÿǪúkÛªž¶¯N«zæ“~uígW•¹qUÃéßv½Ý÷Õª†;l¸qUÃÝ¿÷ñûrp­êjUö¢ïãtçªêßþþê­Vgþdž²à¿»ê¯­U½š†U=ÿ¾ªÌ«N¯±VuÞ}_­j8ý[¸n³ªc¨UMxת.}í_w¹þž¾¬ð¸†ßTXä·ù}…EþPa‘?WXä/ùk…Eªò{}•…êor¯icÛ7¶­ScŸÕûU¥ýºÒÆ>¯´±ßUÚØ+mìO•6öE¥}Yi±ª¯†u¸Ö}6f4VwÁ¤u]ýÏ‚5m,:£ÿ)@,Z£Oþ‰Eo®QU<¯Wh?/ª£Úf`õIûšÖk{ˆî¨Š™XtGõÊÄ¢;ªL&ÝQ 2±èŽª‰EwTW ¬*ˆ×´Ö÷º£ZabÑU‹î¨þ—XtG•¾Ä¢;ªé%ÝQõ.°úäsMËÇèŽêt‰EwT‘K,º£Ú[bÑUً–XtG•³ÀªFvMËtGÕ°Ä¢;ª{%ÝQ…+±èŽjY‰EwTµJ,º£úT`õIÔš–;OÐU¢‹î¨æ”XtGեĢ;ª#%ÝQÅ(±èŽjCUèš–;OÑÕ{‹î¨²“XtG5œÄ¢;ªÖ$ÝQ]&±èŽ*0Õ'kZîmÇq´bnÂéO-Õá~Þ}_ýÂÂmÇËq´:s‡iZOç²~ õËN¸?Úh•! ß¹6öFÂrM[#a‘Ú ‹ÔÆHX¤öEÂ"µ-©]‘°HmŠ„EzHZ¨‡€¤mkÜØuæScµ)r…ÆjS$m¬6EÒÆjS$m¬6EÒÆjS$m¬6EÒÆê†š´±º¡&-ÖC@Òb=$m¬n¨I»ª5Ÿ«*°(þ~ ±¨þ& ±(އøP#ë! i½6Ik<$m,ºã!XtÇC°èއ`ÑÀ¢;FÖC@ÒZIk<$m,ºã!XtÇC°èއ`ÑÀ¢;FÖC@ÒZIk<$m,ºã!XtÇC°èއ`ÑÀ¢;FÖC@ÒZIk<$m,ºã!XtÇC°èއ`ÑÀ¢;FÖC@ÒZIk<$m,ºã!XtÇC°èއ`ÑÀ¢;FÖC@ÒZIk<$m,ºã!XtÇC°èއ`ÑÀ¢;FÖC@ÒZIk<$m,ºã!XtÇC°èއ`Ñv7è­ìyçºlŸRùkÛ¡ÿ0úÏÀaÒû uHŸÆC?róîzúu„Ó j×?¥BnÞýùRiî¢úÇP¿Ü„›ÏÛæÝ+Ñf8sýЫ½°|ÑVHXji'$,R!a‘Ú ‹Ô6HX¤vAÂ"µ éCÒB}èOÚXm‚¤]ש¿þϵ €Õ&HÚ®«M´]W› icµ ’6V› icµ ’6V7Ð¤Õ 4i±>ô'-Ö‡þ¤]ÍêëàwþEgüÎ?°hßù½ñ;ÿÀ¢9רŽý¹B­ƒýIk|èOÚXtGÁ‹îè¡6bÑ=¤F,º£‡ÎˆEwô±èŽýã:øÐŸ´Ö̇þ¤µfzÆkM‹îè™-bÑ=ƒE,º£gªˆEwôŒ±èŽýyÅõÚ|èOZëàCÒÆ¢;>ô‹îøÐ,ºãC?°èŽýÀ¢;>ô¬ýIk|èOZëàCÒÆ¢;>ô‹îøÐ,ºãC?°èŽýÀ¢;>ô¬ýIk|èOZëàCÒÆ¢;>ô‹îøÐ,ºãC?°èŽýÀ¢;>ô¬ýIk|èOZëàCÒÆ¢;>ô;ºóÿÿœÚërg…á[¡¸‹FÈ:”¤ª>wÏL29Ž“ücd,Q¶… áäögïz¯Z£Øþ×÷­Íéénâ¬oÆÍ÷³óÙxô|3N.ÏÆ'·×w#ßýwì¾ÝŸbWfŽ]™ýOìÊì»Ø•Ù?b7fÛ4vc¶-bWfËØ•Ù&ve¶]™ýWìÊìw±+³?Ä®Ìþ»2ûKìÊ쯱ÛÍž¬WÝ^Û\v~fGäiþèGå*™Lßvèòr<ºûò¼Y}®VëÏó…ãуÿ59ùmoÆ—¶õçíìüôúäÏÛë“»Ý@¶˜Nì^íÆÏÝÜÛÉŒsù sÉ”sv8¶8œãþ.9ghp.9x~UÌ]ô'^=´iw¯$9x%v¸þºø§.ìøÇ˜öXØ »0baçA,ìðÇ®”XØ ;ba§A,슉…](±øM¿ë®œK»£¿¿†ÓîP÷«î€ö«î°õ«îàô«îô«Î¾_uèý ´)lSà¦ÐMÁ›Â7p áÄ)ŒS §PNÁœÂ9t éÔ)¬3Xg°Î`Á:ƒuë Ö¬3Xg°Î`Á:ƒuë Ö¬3Xg°Î`Á:ƒuë Ö¬3Xg°ÎaÃ:‡uëÖ9¬sXç°ÎaÃ:‡uëÖ9¬sXç°ÎaÃ:‡uëÖ9¬sXç°Îaú€uëÖ¬ X°.`]Àº€uëÖ¬ X°.`]Àº€uëÖ¬ X°.`]Àº€uëÖ%¬KX—°.a]º„u ëÖ%¬KX—°.a]º„u ëÖ%¬KX—°.a]º„u ëÖ%¬+XW°®`]Áº‚uë Ö¬+XW°®`]Áº‚uë Ö¬+XW°®`]Áº‚uë Ö¬+XW°®a]ú†u ëÖ5¬kX×°®a]ú†u ëÖ5¬kX×°®a]ú†u ëÖ5¬kX×°®a]úuëÖ ¬X7°n`ÝÀºuëÖ ¬X{댷zÛ”¬X7°n`ÝÀºuëÖ ¬X7°öFϳ…u ko©2 ëÖ-¬[X·°naݺ…u ëÖ-¬[X·°naݺ…u ëvo}Ði½Ä~k§Ýà}§=hxv ¶¯wÚÁ¹N»ŸC§M&Gvxî¸ÓîçÐi7íðï6“É+6>b°ó"vZÄÂΊXØI ;'ba§D,쌈…±°ó!v:ÄÂΆXØÉ ;ba—],쪋…]t±°k.ÞieÕê¾Ú5'™]s²²kNVvÍÉÊ®9Yuèý}Ú5'l½ÓJ]ï´’Á×;­döN+Œ½ÓJeï´’ÁÙ;­döN+¬½ÓFæVV°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;mdÞiekï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓJkï´‘y§•¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN™wZYÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;mdÞiekï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓFæVV°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN™wZYÁÚ;­d°öN+¬½ÓJkï´’ÁÚ;­d°öN+¬X{§•IX{§• ÖÞi%ƒµwZÉ`íV2X{§Ì;­¬`íV2X{§• ÖÞi%ƒµwZÉ`íV2X{§• ÖÞi%ƒµwZÉ`íV2X{§í²ƒNkõðë:íûX`´yXÞ}ÌVݸñ½­ß—|o{Æ®if;0Mì[ßø¶sà{ÛÁ¹Ž»Ÿ›êý% ×óðÜqÇÝÏê÷¶Ç›v:ì7í‡ñJä{Û勯U–oÃý¶¢ú–¯ÎT·Ó Tç’ƒ£d—È~î¯íàqMuxîXu?7SÕãMSÝm&~†õß뿬j_šݹ+ª~[Q=?RݼþyÌàÜ€ê~ÎÎymkªÃsǪû9|s¼iª»ÍÄ>—‘GŽO x®^ØÇ6ߪÚÝVT/Uw¯ªÏ«ösT=xÜröÂÜ‘j?§ª›MWÕÞòzÕíiþÿ~ óò›ì…ß‘üH%›í^}“ž Þ>à4ÁÛKrð¸F<˜ØÛìU¶MNú=ß^?ÍïßÍ×÷ËÇçѧÅ{ÀÉ›ó ÿØÓ_/ïýgNƒÙfõd?€z“ÌNõ†¦ýßÕÆ~)5œ=,æïöC+»Ç3<šÿ¿õÃjµy)´íÏùçÅæËÓèÃróËêÝòýæÁîÉnçËf±{®ãÑj½\x–¦™@ß(=Ù[dÙêÉáa:[øK/=ˆW~„'—q²ô2\&W‡é*ñ½yºðýl?~ü·Ã¥D{b¯£ìdïøñ1ð¬£à?k"oýíøhoü, ÆÏ²ñ[oéæW~öì0?;¤»ù“wÓû³Ê“ç³ ,Ùí_Þ¬ÐÖŸ‹þ»âub·ˆ?Fq&âOöƒI¼\úQ–Ú÷O½Ì›z©/þoí'_짉7óßxÑÚ ë98÷C¦h‡q…˜w%4!‚¥w…ÿ§~Jz²qœC<âu…x©È¾€¦DñϹ¢n$Ò8!Ƨ_„®ÞÔÏ‚™Š8™û¼UîŸÏçâ­ÿY¼‹|=="¬0Ÿ¾0MÇ,^Nãh|TE¿Ï-S–„ªªÌq‹ÅÌ‹f~hñ‹Ÿ­° ˜)6%³Í|ñ9ÈL^~_Iœ‰•Hý¹ ¯À/pF±ˆHÈпŸ@ˆ?¾û_»ÃèÆ»ò‰Æ:õ“‘¸ŠÅÔ›}Ò7?³ Ó’R\V¹±‘”IUNÁXþQ\~8‡4§?67&bM;¨/ÕkÔˆ Ã#ÚI8ÌVèAÕE¸"¸„31gç#º6¿ t$3Š/% 0` È0:©5†‰†_V-r}÷ ’*‹º\Òj[Úô5Ã6½çëiM÷ä0¬ÏNínì<ĉ˜ÄQW5ÂÝwaq 1{†‡Ç£o‰;{ÂËXp>_A†ô›žŸŽŒ\ó{"]ÄëÞ,H*àÀùb¶NثȂ¥¿Šƒ¨2>ÿ“8ÁBgÒ½TÔõ6®4p™3-"ºÎ„êÔü£hò¢¶D&U.¥ÊAª™±¡.ã„\›‰#ÝD3g7E°WijGá—*BÉ]hà v\-BüG‰'K¹ž’|án‘œË¡ xzˆÓ6Ùö7ÜiF¹dÅ)¨j¤UO¡ ªFîú# ,ø$*H%ʪñv¤ë:âÈœ•œU˜ÆU¥¹’XÌXi²]}?oé`¸¹Úуåhy) />°ºŠê+0gþk¤»;‘ÞLÅÚ*Ó!¯r¤åߟˆåÄiy ÙT_  ÑÒì…Ô9Rr5Há ”Òƒ„aÓ3–Ê×,Œ®Ž<'cT¦á;¨š¸Sý˜¡ÕÊ÷ä<䉭‹’=6VštSO¦löÎñçÜÐ49v«ÊTxŒP[ ¨©EBOI-û,ÈÏ;zQåÑ™.Šh2QUý„¼¬KÃÉ¡mË…} ñß‚gAÞ¡J•ˆV•奙» •â*~û\×8äÛ]&˜g5³q5)®{41ó\˜tâÜ¿¢bœWWã£Á#RöÂÚ·¡p± íP•ZAí”e+3Sòx‚V\"Rs…JÉĦ:¹ÛÆP Œ@Úi˜2¡¼gÊu#ÉâLµŽÉÆhvY«k^àÏÀŸÖG’ê`LÜfœ X~J4i§L¡º*M$ú4–5(dÝÒHI)¤`W¨îLB ±’_Òr–Ö!¯x\_\Ë«b¶””yHŠ:—œu`~dæÞ4!·q¼#ÏIó?û²rµ‡ä8* ^ DðU‹Šóx>¯_sõò„WÏe¡…çIåâ¶M ÉÒt*—$¤\ô\”L™ª]v€"l˜RºÔÝ~"ݦ}—RûžÒæ©é7ϸþNUy&ÄKgOzñs9o×ãŹ¯ÆØ¹cŽTYø:ôòØrÝÀ…n…»{^O¡ˆuåú\0OÔh G¹%È+IõE<¥²]eÓoú—™ø7*žðuuQÕ zx oÍßàéIá¹¾/>SÂú¨L Ÿ©^PCßãŸôOqí…X|;Ú;?“ñ#¹šžì½ÂŸÇøC·“WH·d»‰Ó$ »—Þ2@²ËÝéÆ!CÌÆG]°ŽM°ÔK“}Æâ']ÈØ”Ù2ŠekQ¨[»I~S™Œ÷•ÙY§Äïl¬]99Gmfì)¥©Xk|d*_Qx;±Ÿqƒ¨êªä—{$ãáy¨ÕÈï µE5š àìÚ¾u±eãçjõGK"_ê*»k$§>VQÊÕšbž×1¥iÒœ³°P RR*£ »EM¨å61…gn˜ÏÔ/DüÃüD–ð92±"©‹™›enI Wõ©üjZ^ÐŒ¯¸AgÐTADù³v.õ«\Ö( º^¢–ÕeÔüQ†-ÊÍäJ—#ìŠ ùÁ[·b'@mQÂÕ™¯6:Ê{4ÐëÅÃ1UIvõHùÂ¥wóHÞÝÏÓ–¶$;ŒXa¹7• ÌSjVHv`Kœ½Ènü/®›<ï·¹t7vìf¿ß¢¸²ñ;¸ G·t†¦ŽI~)_.»58Tìnñ®á攛ŚÑ#NòRñC˜=ýá*{*/rb¦Õ4ÇÉÚrqwå&$5Ç*u¥w 5{´s¹BMÃè@ 9SdÃ%Û‰šaw–¬èèé•iQ(,(²å£çèLóGÉâ'’ä6_¿|u¡1:z¼/žŸËÜW-mð¨ÎùÌLõ¬FÝÀÆ ÌjÔÅþ»y_‹bã+ ÷Ùc®iâxP¸Æóžt@ùôê6ÃR-kƵ‹4>î‚eÓyDC03þ‚]‰Ó—çñúìÍÙ…8ªI©³ñL¯ÿ§¼Œ¢ÇÌϧ‚÷*4Xú( …š 4Yf§­@åѦíd¤tLú±iÂr†ÔqyÜ¥ûå!•aØjK”8aƒE‰Hm^¨)Ì[« =·¶W©—Ú°!3½7‘h¤;:Ç¡-§¹# gÒ‘¬eÒZ=—p´í;ý¬ú»|h0®MN㛡’ª‚çbÊöeáŒPóŠ|,lñ€„CS>îD<¶ÄÆsÌóïNG¦)'3´Óéâ z.qìd–Þ£'*Ú(»… ¦+Ÿhw*\L(~rÄÍQN†äè1dRI€ñP&÷ $F×ãŠêã8Ô'LV tÁéË÷XžAru6?Ùûï=AóÔ“½(žÄ‘:Ë úºÒˆzi„YZÎÆgtBÀãd§þ¥·³7ñÜÞ¾R?‰ûåå¿ÎÎÏÞ½o}óâå/âù« ü{þ¯·â×÷OÔ¢JŽÿ-è Qæh89«—Õ”mé$eì‰åýâðjÓ2’SŠ=$"óo Þ…*­j*òͯ VÛͱÕa'°¹b´VXZájSÛx„Æ€† žÐ ¨(X·ºí 9¸äu“ǧypÏ‹ ³so§B0MaÁ4 €ðÈL€åmQ#q‰Î{*¯Id–{Ð Ô°CJ¨7¥\Lè7m×Í»Ž‡N‹ù#ZåDäëF¥y³†lªºj»Ë’©ÝîRÌD1l ýº%¡÷~)KòÙQAÚZ½¹^!2³P0 ŸÈ˺sž(Ò­pÖÁáÇpÒMKu÷Hàc„3xc†Z4µ>Ö㬶<þ9®:´ W¨ øgØe¼Ïa–ÿÏ{ðéäVä‡#!sŽr”?Øáí­uè Õæ3[åŒÔ vŠä¹ôœW¹Jã×Fϱÿ1…Nêè¡“C3]µ«÷@j|”Îóy*$høJžKë¡Së;UI†¾(:A žŒ1Hwç]œhÞõ»-¼nö£Æªn”5D<4þ´°M±ìC¥,¥ •¿k=(j¥IV©Zþ<çõEÛWpþ%«UÊÉ•»ÝGÁ°ì§2ß~g€H¢ôäÔÏèÕ˜ŒÈC¦ÈÊÍ ÝFîܶ¡ÃЉÏ'úÕyAëyêêܪݳ/ºªï︅¦å¯Å W­ÎÒªI¢¿ÄkÜŽS;绚øAT}ãÊ-„(•™yð&Ò‘HGBx…7äzF¬Án4ÆqaçcöP#¬ Wµê¹^ î=·—åïq[?¶ªtoÝE–UÈ®²lê¹½,9w¢­½xªª47…ï"Ï:Ø®mî[/S*×ú4 |òF?·ŠécѼWÌÐÅŸ¿ÄƱl|î/ƒŸž¯³oI«¾êÒæÌ¤à&æ™(ˆ°ÙxÒù¶þz¤oØßŒ› û…aÍ-êZãxYSÔ*–¾Þ{Q[ œZ«kbä:—Õ3±Dùìáƒi´ç,BÖF9½Ÿ®³ )=þ*=ؙÂʄ(çÈ%p¤¾rlsœRw6Îá)]öï·n%ÝTƒ†“»‚äé€<Ïìz+ õHèpáÖMþ ²ØU'±o…j§¬g+ƒ¿ù¥Š)ò+y: ßi«U¬ëËøÚl†àúí<ÀûêfwÖ +6ÀÆ0¬¸ ª—Ö\õe.\õ…k½¢áŠ÷•EÃjªOOjjó;¹õÄ©†T´^ « V<;â§/µòÓ Ñ<^ó|:'ä–SôÂò×*Nò°XB“GÇä9šr˜Í]T,àCý¼_ Ë_XúâZÇ`ï@g'E¶Ãë_ެɸ(ðˆÖŒ¯!4ÀC'O!û °°›](ìQŠÂ5¡“I^A²¾çh [âê$úípíV†=1V—; ¥0'\;ä«/…9ñÕ²JÂâ¨-Š+¿ý>¿}äõ=Eމ#bò-â5½rK¤_ðÂ$ŽN 78ÂæÁÓNrOJoE´C%Ô³$µ Ÿé©•ýÖ±’Âôh0‹,£âz1v6ÁVD}YF+"=±¶µÝhk]©&õr4€qºì¤€Ýôà°IÞ <×$KË`>GpÓÆ b'1º@ì&GˆÙ¤Q–‹~®2–£„×9ŒÑ5ŸnEXSk–\©ªV‡p_nœÔë–9‘,N~¿«œ4Øq¢µPþðA‘늾rßi;džÁºµÕ«¦3¶ºp‹.!¢KT©ÊI½ØŠºÕÎ娬±è¢¯ÆÉ&]¢¼Å¢ó„tk‹¶ÐòRIU3 u¶èœðF#¨ŸÅ³ÈGe·Ê*>Ç2„äÐyh7ä[h–ºwó|[«¿™Õ½së¨Ì±|%…40ÑÙ~óPÒ¨ûì7Ç2„¸rèXɳؕҊdœô¢”VN:`©ÉŸ7÷WÀ܅ܬg6ÝI«Y= Êx{þ]…€·¿ ÖOuÅ .{M¬ƒØ\hë®["`Óݰ1½N¦["r÷vˆv(º>Xª Òƒ(É Ñ®8êEINõ‚©’ ¢¡v,}¨§Ë®$Ö3•¨]UŒ;ššàXç4\ õJ[½¹ÐÖ\MDë\¼½ŠPç.:ê:0Û-:U ¯/"np«˜ÜE´%O»”^LÕŽªøúP”¦ñÔ‹¢ÜxêU%V £%4}¨¨Í΄Ö;•Ø;ŒrÐ솛^”ãÀM<5q|%8s¶ ¸Þ™u'¯}EÊ9×kÕUÖJUwXl¾]VÔL^³ÂçbûZ¾ê«Eô]`µÉ« ¬Ö°9°nÙ‡g÷¥«¾Ð8‹y+nÜ5°š^”S—'  4=(ÇMÊq@Ó‹r*¹ØšiÅуZÚpô¡“6½(¤’  V=(¤ G iÃÑA!59ÚÆ‚w€å,àvXî‚l‡ÕA`5Õ$*vX¦Ê#n¬.«T€¹‹Ì…2whÝbqךk.‚-ñ8çvxv'·ª‹ÇC(È ÏŽøéCANüô¨œ‡ÐN;’TÓŠdGâê•J€B)íHvÁIJiçÄKM°ß\ø.Àœ…ì¬g6I« ÷ëˆyv‚Ö+mîrs¢Í\·L` ™n‹ÈYÜ["Ú¡èz`©.J¢$7D»â¨%¹qÔ¦J^0ˆ†°ô žv,»’XÌTÂö ŠqÀ²^úPŒ/îhjò‰-àÍYÐ.ÐúæÔ™¸öu±Ûþ ™NÛ‰ÁÞhrV;w]‰b«ÝhÑŸšÃ»ÉWx›vok›€laxmêØdk ²³[ªÆÛ}]°gl]U°oµ³¶>W—U §8lý)Î[ŠsÀÖ§â*‰ÝpZkEÕŸÊÚPõ¨¯6T}*«’† §¬VTý)« UÊjCÕ]Y5 ã¶JqÙUøí ; ¹dwaÖ¹¨Úa²ý@vYªÜfgqºÐÙh·ô k¹¹"—-Ñu5êíÐí\˜ý±W—" ¨<'t»å®Gå9q×#¾J¾0 æÚqõ§¶V\»•aŒUr†ÖŽk‡|õ¨°v¾:#«É?¶VŒ Ì® p€9 ï] ­É@:—e+)Ð!(í,S'J;Cí–£l/ïmñuUÅ–øv/Ïþ¬K†T ¾ó×£Ýøëa%cR{ÈúS];²‹±?Ö*™ÄJs@¶KÎzTšg±Õd:Û+Ç hW%¸ˆý®¤¶¯ŠÞ¾æ[Íȶ\úí °³ ÛYÞPˆlôîëÁÉøY&n–á“tåÍü“½Uâ§~ríïá³Ö!¾þ*f1Þ“»N‚9>‡qò‡º1ÙÑÁÒOx"ÐÅH\Kÿ}Œ—ëŽ>žóKuù;Ršé'ó —³.&1~ /ÍaBj|” ž§B‚^¦í€ñk:"o锹òcĪ‹XüTÀÓs€„t¾Dƒ“B âû¥þI¹+nsî‡_š6—Üâ½ÁÁÒ»Â7¥ñná_}äfògÐý}Ò?> ~²wt´w8~Æ\ˆäjz²÷ ãÝN^wÙnâ…Á4 è ð%qî~L7ÒÙ‡4ø¸‰ºyÈh²ñ‘ê šû7þüdïï=á­7·}ñü&U­¶c)$βré‘Ô,ÿâìJ©U©…î.¿ë„l«b û4b²cþ ©×°áìXqÃ÷1ý¢Çlwî§3Ë GO-¦ìÿ}w-Ús•ýÃw×¢½Úw×ò ¸ûñ–®åç×’Ÿóæµ÷ؼ†pj¿&tŸdF<_zÑÚ …?ÇG–£+µÍm‚—ûgÈ´'£ïHÐ'(n8ñÎчL÷ÂÞ¸7ñµÏ­–ñ:õ®¾œÆëùË•˜Æ7"¾ä{:Ë\ýýœÚdžE™Ÿ ÕD&@Œ¼‰ç@á§™ùb'õ^y)¾CðaáK"%z|Ú…ähà«D¢z£=þ÷ßR°)2œuÁ•òÚ¿D"ª•J´ˆ‘UI¹”˜ôV+ßKî ¼>hfEif½!þËÄ£ü–éŸü* lÄOö­mYp‘b£§ìKÌ<úxùç`~åW¾kpÇÌù0ËfÙu2ƒ»ÅÝ—{ÍÝÍ}g¯Õ4ñ‘™|HÙm#Õ»òªQùúAâუ4“ó²Z¼ãr‚}›ózøà8𷓇º¶»ËŽ :fáH d ð"|û§êRÀ®ñí{ìX·µÞ¿œ¯½_ »¸ß¯Ä±{ÆBN¶ žn©íd‘ÚÞ5î´Ø¾nʦ©0ÒÙÞÆ•w3¬Ù¬ÎûŰCÖz¿¾»Â¨¢ÇA|kUÆàé(† ÓÑ×ì`ò;wíŽå/Ì‘Z³Ûü sçâ2þÒì >µ¿cž¦},~˜g†‘‘W?iœÛ<<ïÃ.#¶7ŽãUz.Ù§þÕÒ2ùfù–q³óó©HWrgÄWZ„1Fu‡4ðß5>ÛÝÎfQäŽñéàmvʧ¡Ç €~¼ª‹“¹'Œî.Ap³e½(:àzö®«nŒï$ŠëfÐì e¸c¬»Œë¯ž<èXÒ£Os«lª¬¾“ÉÃP|j¸Íãq§±æFÓÓ£:ú{Á§‹“¹'ŒÞõäa K6#¤yÄÞÇ(â8ˆ¿6ë&¿éÑ @‡ ø.ÐÁøÔüy8îÔßŧûuø´ff†š‡[m»6ù†«ôUëýª¹ÒX‹Õ\kûxýÁ®‰<¤'Îe×ê3žémÝØ®ÿ›üªóˆöåáÛebƒ¼ÝáóðÈÿl¶€«ÍÞzÿu®±­9[ðÞwyìPï£ lœO½k\«Éé ñhE§SñC˜=ýá*{*«“Ž8þdºc~7ò Š ê[þ=&‡ ÍøhÎ0Îç9Ž‹À+«Û³x9ÃÛ)iGwNÓ«è8i" ØçâCûBKˆI’[ÇK"KÅ2ò¡³’¼ÇüIY^`ø ,ùÁs”¥üÁÇGÓ‘xƒ³{êBòÓ'•;ʼnO©ÕG­œO‘â¸[÷S¤£×/_](ƒ=Æ™ÅT”©ßèAÓœ)U(꽌àÑ!Í–6•¥wóHÞÝÏŠî·6µõ k)X£r÷á0êîôÖz¬öœW)<|äIóíá¡ØAÊwìà{³…8>uÀz³Œfe™ËžWžBÒn¾—À”ἘÏÇÆË¡I²ÖÌÃìËÊ¥ë©þmµ‡óòHÔUÊŒ¶†qúåB£6Ãe¢éаuè%D¨iQ ¸4ÖØÝâ·ŒÅ$Oôf{¸â(9‘ð‡ ©ü ºQ8]®©¢³¹L®¾qv é‹ýwC:…ƧË-² ˆÂ}©#)wÃ^ùyOjÏBgÔ¹?ß7§×1Ãù¦uׯØ—hðîæô9³Oÿ@@§/Ï'âõÙ›³‹ÚóçÙãôµí‡â¼zÆí^ÛÀ#~¶ð¢Èag]3Ñ.ÞêvNþë®íûxfÿ¨Çé73žëÛ‘ÞVA›^I²Ñá}íHºŽçÃ4ÍÆÿ/ÿÿPK!jLª;ù ~§ xl/styles.xmlä]moã¸þ^ ÿAÐú©»NïÞn/Ρw¨¯®‡bw XÜÙ–¡zImy›Ü¯ïP/%ŠÔ˜Étz6Ž>3óÌ ):¾ýþ)‰½¯áþeéÒ¿~så{aºÉ¶Qz¿ôÿùyõú½ïò Ýq–†Kÿ9<øßßýþw·‡ü9?=„aîˆô°ôòüñO³Ùaó&ÁáMö¦ðvÙ> røu?;<îÃ`{`“’x6¿ºz7K‚(õïnÓc²Jòƒ·ÉŽi¾ôoø[^ùþ¶pï¾WŠû1Û–/ß¼^\}øõ§0 ÷AìÏj1­9o»sÊI¯þøêÕÕ›««ï¾| ·¿þá?Ç,ÿîuùãË7í! ÁïÚ‚+IWlô¬Rçîv—¥V×L-öÎÝíá7ïkƒN×lü&‹³½—ƒÝ@«â4HÂrÄÏÑ´ËÁ=Þ§ =âK§Jú1ˆ£õ>bvAÅÏåsöFá´jÅ$J³=jýýzé¯VWÅlF[·ØLÄ¿†iCP[ädc‘ZâQ”jmg&•c¤QÙ€Ëô§ÍåʘKÏ1sú­O¶‹UÖÒmøBð¿7„Ù±2ë©ê›ÅÈ(˜ÕÁ/"òy!Šcž„ç,[Áw·Až‡ût¿xÕëÏÏ«R¨ Ì1³rÜÀèû}ð|=+L(æÁºël¿…T§ÿÅXº|ïî6w9,±îØÏ<{„×Yžg ¼ØFÁ}–1¼œÕ3êŸl&/¨SK? ·Ñ1±ef‘"kÆW« ç˜ Hè)¿FžS*댮/ÌüùCѨxá˜ñkÒ  î¡ÙÀŒ£ç6;®ãPéŽj:ˆûÿاƒÙûøÔbÆ|l©ùÌ©ºJÎ:k¬HSµ-¡) A"t#/‚o×"ÔF#ZØÒðo™ˆU`H¡ zµFïS–A‹W+ƒÍJµêðɵm´à£çb•G ‚žÓ(POèBOKµÐNžá»c80o"¶vÝ n‰ -ºó,ó¬:D€G7€k›hq fFwU/Ñ=:uúq´IÔrn/QD“ö8 ˜âhK¸t€Óñ› Í1]%âµr9|ž$‹3\DbëLs[‡Vñ=<ìx¨3ë°[¥Ž= g`ãà—÷ŽÕôkñ®#ÞY§P€žÌ%:°=q¢>•CtF‚ìª;ô ÆQ‡Ð€žÌ%úÒ0ál+ÉY@Oæ’3€ÞŽF h…KÄ>{¸®‹£å¢Þ* q,Ö fc6ÿæ|Äu/T¡NÕkÔŠqèe:Èu:Íèpu&È´ëx´3^ðÔ†¡K uù€Ÿ0Q2V+àdZ˜ —)¡ît`p+asYÛM\cûEª›.pqfÆñ'vÃå_;~{æ=$§p ît²wì%{ ·xª—åE™ò€×šTݶ,§ÍÑÓ„µn”“îná*â}š„iî=dûè7@ÇnCnà°¼zø´ëà¡ìåáSþ1Ë‹ë”KÿCyYS·»qеWqÓ´´~š ÜÅ.&ÌÒºf&ò£d‹@”ùµU¼§‚3Ìý¦«æƒºÁãcü¼ï³Sïò·?×Ì`o‰DKÊy´¢ ’¶ÊEEv²lç³»Ò H½¾÷ß}ðøXUÛKdjbw†O²‰aTrõ´óUhÀ¥‡kŸ´=ôCqYá1ÑxUh æÓ;ÊhÓÀ4ð²ŠùIìÚPmCU– 9— 2è:a¥„ l¢w/¡Z¹ÆK ’k¼4ØPÂ:z)@òRLj—ÀW×x)Ar—æ yI‚—8F¼„¾É5^J\ã¥9@B^R€ 䥎/¿u—$×xi— y©£å¥ª_…ÓŠv¾lH •y»w· InË3ÜŸzP‚Ô¨8p¬!n’GÜG™tÂJ BžklbÄKà¿k¼” ¹ÆKs€ %¬÷Q y©cÄËîñR‚ä/ÍòRBK ²pÂats‹ö¡ŠR^ÙB" Dýªzc!8ª¾çZj¤ÎßøÈ˜Ð,š¨ó‘ZSÌºàŒ€É€gª4!£k|j”w¤8:¿è!:@jÎo/zHöR&FªGMÚ¶q SDÅcªÄ(!ãpXX¾¶3jÛ¢ã‚Ò|¢¦âkñǶ[Ÿ{tR¶œ|o¾"m91ä†ÍmmtU±àü¨Ém`ôî]”š§}àE…7¤ýIê-béL¡mSƒí]JÊÞB8]b¾Õ»K©ó<ž_ -.Ïʼ¦] “¥Eç™,?Xw2ÐáÂr²Sˆ…vpõvóøÌîæŒT¸Å‘ò6:äûh}ÌÃmñW¥Ac€òR ƒµMµ‰ÐÂÏmÞa´ðs[·®cX-|*+(5yMÚgêBB)×Ï!évÀZaÒÏêý”XÙ^sØð6œ1zÇØ‰Áå³1ò¬ƒ†¤JÞÓÒÒ¿4Èø:{±¥U£f h8hÈÄcRYvÐEm ìôGóIa£<à(6#ÛN ‹ŸAö×ÀsÁ:o~VZë¼™D ë¼q©„uay´/Ï",;Ö&u Ÿ ŸÊ„#À¾“2Ûµ*ý¾0&ŸžÝ-i¤{Z}òÆGÉ*ž]-ÑŽDzzx#þe4"=¯†–4š†ô¼Ó±D;ééá@ú—Òˆô¼×²¤Ñ4¤.·7ôðF ýËiDzþìù"HO¿ï íééá@ú—ÒˆôÐ>“äNÒLåg×wùtÁ7²«Úgè3°Šô`;íSÕ¶ ©ýFGk׎oð®¥p*aFwJá|+mIäIh#DFWeЂÊc©«D:ã ¥B4‰õTh%ût2¦¤2<’ EƒÑY©)? °$²=mpŸáq Ù¦¨–:õ‘%Ô¾ŠÍýÎw8#AhùB•åOüžó#óVõñ`hqŽs¯äeG𪎧T§L§¤MåçzT>M1ß®A¶ê¥$™ÉÜ©©@j?Q±Æ¾ 9DÉqªC%Ž`’î¨ì¡²˜ (Ne‚I(>@*åÇ4ÿ ,eJ(×œÄ èIÂŒ$æ.ð)ë•ÉRP|Ñ ‚-}à`oŽ“Ý!á8š1éƒiB¼t úÇ”ª=ºá›cËN44¢B3*Ð h$IÇü}ô¡Š.7“KÙÈì"U¦ßË`uíce(PíkhB M¿‘N:vUû Ò($é°Gm © áôç䛉j¸Ržq®Ä…)á_Å _¾,|gwë»ù75{i„Kÿ/OðŽ÷Ã1Šó×QêýÂþ0Q\ïI®ÙÇlQ3<þ„®øS7Ý9 ƒm”Þ×rç}r«1\ÐMß 6>àñš!Òê›Æ7ÇCž%…6QZ}WrËÇðpŒóÊ¢o•r§ÝÛ¾1Ÿƒu߉þstÿsØß²ÁÍbƒ#¶OÍ—¦_žó©Ü5 É6ܬ‘»ô›×·Ñ1zPúGô5ˋ՗~óºDRx`v`_×þé! ó»ÿÿÿPK!°D” Å'xl/printerSettings/printerSettings1.binìVklU¾}HE1ˆ¢ØˆD`‹PE º»3ÛÝewgº3Û">6ÓÝ»ÝÁÙ¹ÃÌí#>ˆJR£"  ‚@|a ü@ ‚´Šâ ÊÃhj0&Z£õÜ»-i! ÆøÇÌ&sçžsî¹ß9ßic£&¤!d¢1( ëF˜CH†1R>»ïÄm͆‘‚„ýJÊÑ/ЖÊ@ïÜŠT‚¾JÎÏÀ| šYZ óÌÒ2£Ü‚rknö¯†’>k6—ÂW ‹^øîTÇ“cÑ‚Š½±eÉ‘²ÓÏîï¸u9|çÁXÖ÷•sÉ@¥þ(Êζþ'ºgóáÉÿkfiABJL°;‡£¹E>$#:*ð:v€)<±Af#ØØÄ%¨ø1¨læåR¿n¢ ”ˆ)R2QBT„h%MÝÆ[…d¤“a%Fªíb$*r"¬*®e›âLQÔšÀªn´, b¸T'&ª©ªÊX:’mݤu®fè´µÖ&®…ä:>§&ƒÿ1ˆ­ä5›"ŸKI^£zz8Å5$‹¹tRb¦ ˆImb 8±óšqåfd)110ÕôÓ4UÜBSqìR[3jm­ÕA~CK?(™Fë`—\ñœ®ÀÜÊéiço¹;¥|N—rŽP2Øß”‰‰ÁÁõNw%Ù:6)@ Y¥„šð…U°+ŠNpõmU(¨€ãZnAq).‚Ï–dú Í)z;1Í„Ô&EeY³°­èmEEU<Óqóظä+ë"†3º¦¶Zù’ª„ z.FRŒâI z6Ôm‡Ê$5Gô4Fj"É£‰Ø’ÆÅ¬u³‹d±jÚã Ó°I±ÕÀXÉ‘æÁgg(GI³hfÎ"®Çö'vÛaÓÁ6‡Pti‘9Qú¢ 5Ä‘B5ËÐÍ&¨N(¼Ü¿—€20¦£˜&&É“ îÛ³ó9¼û$>^e^QLaÂZ¿-ødt ¹ÀaLSJXHM®¹%å‡yjõ”Tˆï§¢SqrbA(@eÙ&c¨k§± Q å¬tÎT'¥µFP‰Zº‚ œæOå/ˆÈb­hjÆOÐ5§µX‰’ ÛXE\˳ÇÃ}J a¿BušÎ¥T`¿ŠŠÝanø§*Cµ1.è¸Y&ôÞbúZBŒ¢R"“‘U±¹pòÖgTðÒi^³bˆ«*;‡gþ,Yˆòêƒ9%¢5L‰Šfšd˜zR Þ¢iô¥ÓÄ5¹ØK~_  ¦øWSµ ))Ç}1týÄ6%€cîý’#K64~c@.:ô·‚W êÆ ¡ˆ?"åpQ‘¡çö½tf,Êj¸a™p!5“Zò¬Sñ©©@´f… ^ûMÙ‘ž†H@ÆÐ?u›ÒlûbξÅ"„$¿3Që/æNÀYÍ5èD$(’€žê@'„\9l‚®aÀ*$@éSh!ÛIÙ,Ÿã„žy˜@¢k â8Ðr¹$+>Co2óÐúiUÿ/¿ã#àoiR]ÿM¶tüðÙžHiݨŠ{w·ç”}c—š³oP§«ŸëšlWß¿J|mcÇõ›[_…Wöëšñæ÷%ƒŸÿxÁ¬ä¡+'®­{uGÕO½£§k9º÷¼ÊíG¦ýÔ5ì‰qõ[*†ÎšQ=´{èC/o^4þpgÏôƒ'Ü‹jæãMsÚ#—¬\_øúc±ûPýœg»••îø›íø]ŸÌ™»ø‰gÞ¿ªcùUnï=šÌ?¸zw[êüç]«ÜÓý»8iéo[ Ê;¡ÅÆ´åë “È£]cGNÿÙ]>ª¾êéºò •¬¿awÝ„“äÆyïVv-zéõêû»ŸzaȪNœœuìâ7âO–$g™?zwÛ—ïçn.ßÿöô·¤¶ Ãö¶¯;¡~WÛ¾®ðˈÕÏïs*{VnêxksÙ•÷¬‰/•VL{䮦mßtu‡Âžn,¿÷Cÿw.™×¾nÓ‰cË{îù¶îöeaüXpÇ·~uÇÒ“£¯ ¿ÎþcÍöè„W6øŸÛ1䓎;W.¸oÅÂÎm×. &ÞëyxøÒE^ÝøàÉ'÷Ú9áBaçþ1#o𙽾³óò–ÝÚXûÚ¾[[ïhÖï?è¾f×Ö¥×]1£ðéÛ¼9ªmþ}ÃŽî"[77/™:zê¸=õË#.忺²Ö²’oxôÿR¤Þ;<<<<<<<<<<<<<<<<þ?ÿÿPK!íñª[docProps/core.xml ¢( Œ’ÁOà Åï&þ g; Ëæ$m—¨ÙiKL¬Ñx#ðm#¶´¶®ÿ½´Ýj=x„÷øñÞñòTäÁŒU¥N€¥Tz— ·l.P`ג祆5`Ñ2½½‰EÅDiàÅ”§Àž¤-U‚öÎU c+öPp;ñíÅmi îüÒìpÅÅߎ™ã—ÜqÜÃj ¢3RŠYLÞ¤ÀCÚYL'ÿx˜Âþy SFÎB¹¦òÎqÇl)zqpŸ¬Œu]OêiÃç§øc³~íª†J·³€ÒX & pWšôµ<ì¹rwÁº‘ b<’Ú1æÜºŸøV|lÒÜÒé<Æ¿…Ökà¨Ú§J)é,ÃÚß×Õë/øÀ¬¯wQÞ§OÏÙ ¥¡$$‹>dtÆ(a³ûÏ6ÔÕù¶@¿Qœ£ýƒ‘,¢ŒR‘ñH»Äן&ýÿÿPK!È-f™NdocProps/app.xml ¢( œ“OoÛ0 Åïö Ý9é0¬¢h;ô°aâ¶gN¦c¡²dˆ¬‘ìÓO¶‘ÆÙŸË|"ùž¢eush]Öc$|!–‹\dèM¨¬ßâ©ürµ1ø \ðXˆ#’¸Ñ?¨m F¶HYŠðTˆ†¹ÛHI¦Áh‘dŸ”:Ä8µq/C][ƒ÷Á¼µèY®òü³Ä£¯°ºêÞÅ”¸éùC«`>z.]Öª ®´-êåz­ä¹U·]ç¬Nç×߬‰BÍÙÃÁ Sr.ªÄ½Có-u®ä¼U;ïÒ+u ŽPÉó@=" ëÜ‚¤UÏ› ‡˜‘ý™ºÙ @ ÑC´à9¶©k×Gýâ+5ˆLJ&Ã4˹w^ÛOúz4¤âÒ8L I¸D,-;¤ïõ"ÿ…øzN<2L¼Înà[ÍùÞIGiùoi"Ÿj\Tâûè«õ¯ôÔ•áO¿ª]«ô‘Núy Ó²£Bîð{¬Nž?…á~ or get_filename_component(FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_DIR} ABSOLUTE) FIND_LIBRARY(FFMPEG_avformat_LIBRARY avformat /usr/local/lib /usr/lib ) FIND_LIBRARY(FFMPEG_avcodec_LIBRARY avcodec /usr/local/lib /usr/lib ) FIND_LIBRARY(FFMPEG_avutil_LIBRARY avutil /usr/local/lib /usr/lib ) FIND_LIBRARY(FFMPEG_vorbis_LIBRARY vorbis /usr/local/lib /usr/lib ) FIND_LIBRARY(FFMPEG_dc1394_LIBRARY dc1394_control /usr/local/lib /usr/lib ) FIND_LIBRARY(FFMPEG_vorbisenc_LIBRARY vorbisenc /usr/local/lib /usr/lib ) FIND_LIBRARY(FFMPEG_theora_LIBRARY theora /usr/local/lib /usr/lib ) FIND_LIBRARY(FFMPEG_dts_LIBRARY dts /usr/local/lib /usr/lib ) FIND_LIBRARY(FFMPEG_gsm_LIBRARY gsm /usr/local/lib /usr/lib ) FIND_LIBRARY(FFMPEG_swscale_LIBRARY swscale /usr/local/lib /usr/lib ) FIND_LIBRARY(FFMPEG_z_LIBRARY z /usr/local/lib /usr/lib ) SET(FFMPEG_LIBRARIES) IF(FFMPEG_INCLUDE_DIR) IF(FFMPEG_avformat_LIBRARY) IF(FFMPEG_avcodec_LIBRARY) IF(FFMPEG_avutil_LIBRARY) SET( FFMPEG_FOUND "YES" ) SET( FFMPEG_BASIC_LIBRARIES ${FFMPEG_avcodec_LIBRARY} ${FFMPEG_avformat_LIBRARY} ${FFMPEG_avutil_LIBRARY} ) # swscale is always a part of newer ffmpeg distros IF(FFMPEG_swscale_LIBRARY) LIST(APPEND FFMPEG_BASIC_LIBRARIES ${FFMPEG_swscale_LIBRARY}) ENDIF(FFMPEG_swscale_LIBRARY) SET(FFMPEG_LIBRARIES ${FFMPEG_BASIC_LIBRARIES}) IF(FFMPEG_vorbis_LIBRARY) LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_vorbis_LIBRARY}) ENDIF(FFMPEG_vorbis_LIBRARY) IF(FFMPEG_dc1394_LIBRARY) LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_dc1394_LIBRARY}) ENDIF(FFMPEG_dc1394_LIBRARY) IF(FFMPEG_vorbisenc_LIBRARY) LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_vorbisenc_LIBRARY}) ENDIF(FFMPEG_vorbisenc_LIBRARY) IF(FFMPEG_theora_LIBRARY) LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_theora_LIBRARY}) ENDIF(FFMPEG_theora_LIBRARY) IF(FFMPEG_dts_LIBRARY) LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_dts_LIBRARY}) ENDIF(FFMPEG_dts_LIBRARY) IF(FFMPEG_gsm_LIBRARY) LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_gsm_LIBRARY}) ENDIF(FFMPEG_gsm_LIBRARY) IF(FFMPEG_z_LIBRARY) LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_z_LIBRARY}) ENDIF(FFMPEG_z_LIBRARY) SET(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} CACHE INTERNAL "All presently found FFMPEG libraries.") ENDIF(FFMPEG_avutil_LIBRARY) ENDIF(FFMPEG_avcodec_LIBRARY) ENDIF(FFMPEG_avformat_LIBRARY) ENDIF(FFMPEG_INCLUDE_DIR) MARK_AS_ADVANCED( FFMPEG_INCLUDE_DIR FFMPEG_avformat_LIBRARY FFMPEG_avcodec_LIBRARY FFMPEG_avutil_LIBRARY FFMPEG_vorbis_LIBRARY FFMPEG_dc1394_LIBRARY FFMPEG_vorbisenc_LIBRARY FFMPEG_theora_LIBRARY FFMPEG_dts_LIBRARY FFMPEG_gsm_LIBRARY FFMPEG_swscale_LIBRARY FFMPEG_z_LIBRARY ) GoFigure2-v0.9.0/CMake/ConfigQT.cmake0000644000175000017500000000235611667757442017036 0ustar mathieumathieu#---------------------------------------------------------- FIND_PACKAGE( Qt4 REQUIRED QtCore QtGui ) IF( QT4_FOUND ) #---------------------------------------------------------- # Check version of QT IF("${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}" VERSION_LESS "${minimum_required_qt_version}") MESSAGE(FATAL_ERROR "error: GoFigure2 requires Qt >= ${minimum_required_qt_version} -- you cannot use Qt ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}.") ENDIF() #---------------------------------------------------------- # How does QT_USE_FILE work?? IF( QT_USE_FILE ) SET( QT_USE_QT3SUPPORT FALSE ) SET( QT_USE_QTCORE TRUE ) SET( QT_USE_QTGUI TRUE ) INCLUDE( ${QT_USE_FILE} ) ELSE( QT_USE_FILE ) SET( QT_LIBRARIES ${QT_QT_LIBRARY} ) ENDIF( QT_USE_FILE ) SET( QT_PLUGIN_LIBS ${QT_LIBRARIES} ) ADD_DEFINITIONS( ${QT_DEFINITIONS} ) # # ADD_DEFINITIONS( -DQT_GUI_LIBS ) # ADD_DEFINITIONS( -DQT_CORE_LIB ) # Try to extract Qt variable from VTK SET( QT_QMAKE_EXECUTABLE ${VTK_QT_QMAKE_EXECUTABLE} CACHE FILEPATH "" ) SET( QT_MOC_EXECUTABLE ${VTK_QT_MOC_EXECUTABLE} CACHE FILEPATH "" ) SET( QT_UIC_EXECUTABLE ${VTK_QT_UIC_EXECUTABLE} CACHE FILEPATH "" ) ENDIF( QT4_FOUND ) GoFigure2-v0.9.0/CMake/FindGoFigure2.cmake0000644000175000017500000000743011667757442017754 0ustar mathieumathieu# - Find an GOFIGURE2 installation or build tree. # When GOFIGURE2 is found, the GOFIGURE2Config.cmake file is sourced to setup the # location and configuration of GOFIGURE2. Please read this file, or # GOFIGURE2Config.cmake.in from the GOFIGURE2 source tree for the full list of # definitions. Of particular interest is GOFIGURE2_USE_FILE, a CMake source file # that can be included to set the include directories, library directories, # and preprocessor macros. In addition to the variables read from # GOFIGURE2Config.cmake, this find module also defines # GOFIGURE2_DIR - The directory containing GOFIGURE2Config.cmake. # This is either the root of the build tree, # or the lib/gofigure2 directory. # This is the only cache entry. # # GOFIGURE2_FOUND - Whether GOFIGURE2 was found. If this is true, # GOFIGURE2_DIR is okay. # # USE_GOFIGURE2_FILE - The full path to the UseGOFIGURE2.cmake file. # This is provided for backward # compatability. Use GOFIGURE2_USE_FILE # instead. SET(GOFIGURE2_DIR_STRING "directory containing GOFIGURE2Config.cmake. This is either the root of the build tree, or PREFIX/lib/gofigure2 for an installation.") # Search only if the location is not already known. IF(NOT GOFIGURE2_DIR) # Get the system search path as a list. IF(UNIX) STRING(REGEX MATCHALL "[^:]+" GOFIGURE2_DIR_SEARCH1 "$ENV{PATH}") ELSE(UNIX) STRING(REGEX REPLACE "\\\\" "/" GOFIGURE2_DIR_SEARCH1 "$ENV{PATH}") ENDIF(UNIX) STRING(REGEX REPLACE "/;" ";" GOFIGURE2_DIR_SEARCH2 ${GOFIGURE2_DIR_SEARCH1}) # Construct a set of paths relative to the system search path. SET(GOFIGURE2_DIR_SEARCH "") FOREACH(dir ${GOFIGURE2_DIR_SEARCH2}) SET(GOFIGURE2_DIR_SEARCH ${GOFIGURE2_DIR_SEARCH} "${dir}/../lib/gofigure2") ENDFOREACH(dir) # # Look for an installation or build tree. # FIND_PATH(GOFIGURE2_DIR GOFIGURE2Config.cmake # Look for an environment variable GOFIGURE2_DIR. $ENV{GOFIGURE2_DIR} # Look in places relative to the system executable search path. ${GOFIGURE2_DIR_SEARCH} # Look in standard UNIX install locations. /usr/local/lib/gofigure2 /usr/lib/gofigure2 # Read from the CMakeSetup registry entries. It is likely that # GOFIGURE2 will have been recently built. [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild1] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild2] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild3] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild4] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild5] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild6] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild7] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild8] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild9] [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild10] # Help the user find it if we cannot. DOC "The ${GOFIGURE2_DIR_STRING}" ) ENDIF(NOT GOFIGURE2_DIR) # If GOFIGURE2 was found, load the configuration file to get the rest of the # settings. IF(GOFIGURE2_DIR) SET(GOFIGURE2_FOUND TRUE) INCLUDE(${GOFIGURE2_DIR}/GOFIGURE2Config.cmake) # Set USE_GOFIGURE2_FILE for backward-compatability. SET(USE_GOFIGURE2_FILE ${GOFIGURE2_USE_FILE}) ELSE(GOFIGURE2_DIR) SET(GOFIGURE2_FOUND FALSE) IF(GOFIGURE2_FIND_REQUIRED) MESSAGE(FATAL_ERROR "Please set GOFIGURE2_DIR to the ${GOFIGURE2_DIR_STRING}") ENDIF(GOFIGURE2_FIND_REQUIRED) ENDIF(GOFIGURE2_DIR) GoFigure2-v0.9.0/CMake/ConfigBoost.cmake0000644000175000017500000000035211667757442017572 0ustar mathieumathieuFIND_PACKAGE( Boost COMPONENTS program_options REQUIRED ) IF( Boost_FOUND ) INCLUDE_DIRECTORIES( BEFORE ${Boost_INCLUDE_DIRS} ) ELSE( Boost_FOUND ) MESSAGE( SEND_ERROR "BOOST NOT FOUND, CMAKE WILL STOP NOW") ENDIF( Boost_FOUND ) GoFigure2-v0.9.0/CMake/SuperBuild/0000755000175000017500000000000011667757442016432 5ustar mathieumathieuGoFigure2-v0.9.0/CMake/SuperBuild/External-ITK.cmake0000644000175000017500000000141611667757442021645 0ustar mathieumathieu#--------------------------------------------------------------------------- # Get and build itk set(proj ITK) #if( WIN32 ) set( ITK_TAG "release" ) #else() # set( ITK_TAG "4c21663d41017824a21f25cbacd9c3bdf00c72a0" ) #endif() ExternalProject_Add(${proj} GIT_REPOSITORY "${git_protocol}://itk.org/ITK.git" GIT_TAG "${ITK_TAG}" UPDATE_COMMAND "" SOURCE_DIR ${proj} BINARY_DIR ${proj}-build CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} -DBUILD_SHARED_LIBS:BOOL=${SUPER_SHARED_LIBS} -DITK_INSTALL_LIB_DIR:PATH=${GOFIGURE2_INSTALL_LIB_DIR} # should change soon -DITK_USE_REVIEW:INTERNAL=ON -DITK_USE_REVIEW_STATISTICS:INTERNAL=ON INSTALL_COMMAND "" DEPENDS ${ITK_DEPENDENCIES} ) set(ITK_DIR ${CMAKE_BINARY_DIR}/${proj}-build) GoFigure2-v0.9.0/CMake/SuperBuild/External-FFMPEG.cmake0000644000175000017500000000506711667757442022170 0ustar mathieumathieu#----------------------------------------------------------------------------- # Get and build FFMPEG # ONLY MAC AND LINUX # TODO BUILD GOOD ARCH ON MAC i386 or x86_64???? #----------------------------------------------------------------------------- set( proj FFMPEG ) set( SHARED_FFMPEG ) IF( SUPER_SHARED_LIBS ) set( SHARED_FFMPEG --enable-shared --disable-static ) ENDIF( SUPER_SHARED_LIBS ) OPTION( FFMPEG_GPL "Use a GPL version of FFMPEG" OFF ) SET(FFMPEG_GPL_FLAG "") IF( FFMPEG_GPL ) SET(FFMPEG_GPL_FLAG "--enable-gpl") SET(msg "ATTENTION: You have enabled the use of GPL components of FFMPEG.") SET(msg "${msg} By enabling this option, the binary of GoFigure2") SET(msg "${msg} that you are going to build will be covered by a GPL license.") MESSAGE("${msg}") ENDIF( FFMPEG_GPL ) SET(FFMPEG_INSTALL_DIR ${CMAKE_BINARY_DIR}/${proj}-install) ExternalProject_Add(${proj} # Set up dirs SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj} INSTALL_DIR ${FFMPEG_INSTALL_DIR} # get the project GIT_REPOSITORY "${git_protocol}://git.videolan.org/ffmpeg.git" GIT_TAG "ffmpeg-0.6.3" # Build the project BUILD_IN_SOURCE 1 # Configure step # DO STH FOR THE ARCHITECTURE... CONFIGURE_COMMAND /configure --prefix=${FFMPEG_INSTALL_DIR} ${SHARED_FFMPEG} ${FFMPEG_GPL_FLAG} --enable-avfilter --disable-yasm --disable-decoders --disable-zlib --disable-demuxer=matroska ) # define the library suffix IF( SUPER_SHARED_LIBS ) IF( APPLE ) SET(LIBRARY_SUFFIX .dylib) ELSE( APPLE ) SET(LIBRARY_SUFFIX .so) ENDIF( APPLE ) ELSE( SUPER_SHARED_LIBS ) SET(LIBRARY_SUFFIX .a) ENDIF( SUPER_SHARED_LIBS ) # ADD DIRECTORIES FOR DEPENDENCIES IN Main/CMakeLists.txt set( FFMPEG_LIBRARY_DIRS ${FFMPEG_INSTALL_DIR}/lib/libavcodec ${FFMPEG_INSTALL_DIR}/lib/libavformat ${FFMPEG_INSTALL_DIR}/lib/libavutil ${FFMPEG_INSTALL_DIR}/lib/libswscale ) set( VIDEO_SUPPORT # turn ON ffmpeg encoder -DVTK_USE_FFMPEG_ENCODER:BOOL=ON # force VTK to use NEW headers #-DVTK_FFMPEG_CACHED_INCLUDE:PATH=${CMAKE_BINARY_DIR}/${proj} #-DVTK_FFMPEG_HAS_OLD_HEADER:BOOL=FALSE # set useful variables -DFFMPEG_INCLUDE_DIR:PATH=${FFMPEG_INSTALL_DIR}/include -DFFMPEG_avcodec_LIBRARY:FILEPATH=${FFMPEG_INSTALL_DIR}/lib/libavcodec${LIBRARY_SUFFIX} -DFFMPEG_avformat_LIBRARY:FILEPATH=${FFMPEG_INSTALL_DIR}/lib/libavformat${LIBRARY_SUFFIX} -DFFMPEG_avutil_LIBRARY:FILEPATH=${FFMPEG_INSTALL_DIR}/lib/libavutil${LIBRARY_SUFFIX} -DFFMPEG_swscale_LIBRARY:FILEPATH=${FFMPEG_INSTALL_DIR}/lib/libswscale${LIBRARY_SUFFIX} ) GoFigure2-v0.9.0/CMake/SuperBuild/External-VTK.cmake0000644000175000017500000000217511667757442021665 0ustar mathieumathieu#----------------------------------------------------------------------------- # Get and build VTK # #----------------------------------------------------------------------------- set(proj VTK) set(proj_DEPENDENCIES) if( SUPER_BOOST ) set( proj_DEPENDENCIES Boost ) endif( SUPER_BOOST ) ExternalProject_Add(${proj} DEPENDS ${VTK_DEPENDENCIES} SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj} BINARY_DIR ${proj}-build GIT_REPOSITORY "${git_protocol}://vtk.org/VTK.git" GIT_TAG "origin/release" CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} -DBUILD_SHARED_LIBS:BOOL=${SUPER_SHARED_LIBS} -DVTK_DEBUG_LEAKS:BOOL=${USE_VTK_DEBUG_LEAKS} -DVTK_INSTALL_LIB_DIR:PATH=${GoFigure2_INSTALL_LIB_DIR} -DVTK_USE_QT:BOOL=ON -DQT_QMAKE_EXECUTABLE:PATH=${QT_QMAKE_EXECUTABLE} -DVTK_USE_QVTK_QTOPENGL:BOOL=ON -DVTK_USE_MYSQL:BOOL=ON -DMYSQL_INCLUDE_DIRECTORIES:PATH=${MYSQL_INCLUDE_DIR} -DMYSQL_LIBRARY:FILEPATH=${MYSQL_LIBRARIES} -DVTK_USE_BOOST:BOOL=ON ${VIDEO_SUPPORT} ${Boost_SUPPORT} #${WINDOWS_FLAGS} INSTALL_COMMAND "" DEPENDS Boost ) set(VTK_DIR ${CMAKE_BINARY_DIR}/${proj}-build) GoFigure2-v0.9.0/CMake/SuperBuild/External-Boost.cmake0000644000175000017500000000167011667757442022306 0ustar mathieumathieu#--------------------------------------------------------------------------- # Get and build boost set( proj Boost ) set( version 1.46.1 ) ExternalProject_Add(${proj} GIT_REPOSITORY "${git_protocol}://github.com/pocb/boost.git" GIT_TAG "origin/cmake-${version}" SOURCE_DIR ${proj} BINARY_DIR ${proj}-build CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} # can generate erros on Mac 10.6 # -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/${proj}-INSTALL -DBUILD_PROJECTS:STRING=program_options -DWITH_PYTHON:BOOL=OFF -DWITH_DOXYGEN:BOOL=OFF -DWITH_EXPAT:BOOL=OFF -DWITH_BZIP2:BOOL=OFF -DWITH_MPI:BOOL=OFF -DWITH_XSLTPROC:BOOL=OFF -DWITH_ICU:BOOL=OFF INSTALL_COMMAND "" DEPENDS ${BOOST_DEPENDENCIES} ) #set(Boost_LIBRARY ${CMAKE_BINARY_DIR}/${proj}-INSTALL/lib ) #set(Boost_INCLUDE_DIR ${CMAKE_BINARY_DIR}/${proj}-INSTALL/include ) set(Boost_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/${proj}) GoFigure2-v0.9.0/CMake/SuperBuild/SuperBuild.cmake0000644000175000017500000001375611667757442021526 0ustar mathieumathieu#--------------------------------------------------------------------------- # Git protocole option #--------------------------------------------------------------------------- option(GoFigure2_USE_GIT_PROTOCOL "If behind a firewall turn this off to use http instead." ON) set(git_protocol "git") if(NOT GoFigure2_USE_GIT_PROTOCOL) set(git_protocol "http") endif() #--------------------------------------------------------------------------- # Enable and setup External project global properties #--------------------------------------------------------------------------- INCLUDE(ExternalProject) set(ep_base "${CMAKE_BINARY_DIR}") #set(ep_install_dir "${ep_base}/Install") # should be preset for user or for developer??? OPTION( SUPER_SHARED_LIBS ON ) IF( SUPER_SHARED_LIBS ) ADD_DEFINITIONS( -DGOFIGURE2_BUILD_SHARED_LIBS ) ELSE( SUPER_SHARED_LIBS ) REMOVE_DEFINITIONS( -DGOFIGURE2_BUILD_SHARED_LIBS ) ENDIF( SUPER_SHARED_LIBS ) SET(ep_install_dir ${CMAKE_INSTALL_PREFIX}) SET(ep_common_c_flags "${CMAKE_C_FLAGS_INIT} ${ADDITIONAL_C_FLAGS}") SET(ep_common_cxx_flags "${CMAKE_CXX_FLAGS_INIT} ${ADDITIONAL_CXX_FLAGS}") SET(ep_common_cxx_compiler "${CMAKE_CXX_COMPILER}" ) SET(ep_common_c_compiler "${CMAKE_C_COMPILER}" ) SET(ep_common_args -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DBUILD_SHARED_LIBS:BOOL=${SUPER_SHARED_LIBS} -DBUILD_TESTING:BOOL=OFF -DBUILD_EXAMPLES:BOOL=OFF -DCMAKE_INSTALL_PREFIX:PATH=${ep_install_dir} -DCMAKE_CXX_COMPILER:FILEPATH=${ep_common_cxx_compiler} -DCMAKE_CXX_FLAGS:STRING=${ep_common_cxx_flags} -DCMAKE_C_COMPILER:FILEPATH=${ep_common_c_compiler} -DCMAKE_C_FLAGS:STRING=${ep_common_c_flags} ) # Compute -G arg for configuring external projects with the same CMake generator: if(CMAKE_EXTRA_GENERATOR) set(gen "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}") else() set(gen "${CMAKE_GENERATOR}") endif() #--------------------------------------------------------------------------- # Conditionnaly include ExternalProject Target #--------------------------------------------------------------------------- set(GoFigure2_DEPENDENCIES) #------------------------- OPTION( SUPER_BOOST "SuperBuild BOOST" ON ) set( Boost_SUPPORT ) IF( SUPER_BOOST ) include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/SuperBuild/External-Boost.cmake") set( Boost_SUPPORT -DBoost_INCLUDE_DIR:PATH=${CMAKE_BINARY_DIR}/Boost -DBoost_LIBRARY_DIRS:PATH=${CMAKE_BINARY_DIR}/Boost-build/lib ) LIST(APPEND GoFigure2_DEPENDENCIES Boost) ELSE( SUPER_BOOST ) include( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/ConfigBoost.cmake" ) ENDIF( SUPER_BOOST ) #------------------------- # REQUIRED MYSQLand QT TO BUILD VTK OPTION( SUPER_VTK "SuperBuild VTK" ON ) IF( SUPER_VTK ) # check if we have MySQL - COMPULSORY include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/ConfigMySQL.cmake") # check if we have QT - COMPULSORY include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/ConfigQT.cmake") OPTION( SUPER_VTK_VIDEO "ENABLE THE VIDEO SUPPORT IN SUPERBUILD" OFF ) IF( SUPER_VTK_VIDEO ) if( NOT WIN32 ) option( SUPER_FFMPEG "SuperBuild FFMPEG" ) # check if we have some video support (FFMPEG or AVI) - OPTIONAL IF( SUPER_FFMPEG ) #add dependency to VTK if we have to build FFMPEG set(VTK_DEPENDENCIES FFMPEG) include( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/SuperBuild/External-FFMPEG.cmake") ELSE( SUPER_FFMPEG ) include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/ConfigVideo.cmake") ENDIF( SUPER_FFMPEG ) ELSE( NOT WIN32 ) include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/ConfigVideo.cmake") ENDIF( NOT WIN32 ) ENDIF( SUPER_VTK_VIDEO) # add the vtk external project include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/SuperBuild/External-VTK.cmake") # add the external projrct "VTK" to the list of dependencies LIST(APPEND GoFigure2_DEPENDENCIES VTK) ELSE( SUPER_VTK ) # check if our vtk is properly configured include( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/ConfigVTK.cmake" ) ENDIF( SUPER_VTK ) #------------------------- OPTION( SUPER_ITK "SuperBuild ITK" ON ) IF( SUPER_ITK ) include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/SuperBuild/External-ITK.cmake") LIST(APPEND GoFigure2_DEPENDENCIES ITK) ELSE( SUPER_ITK ) include( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/ConfigITK.cmake" ) ENDIF( SUPER_ITK ) #--------------------------------------------------------------------------- # Set superbuild boolean args # #SET(GoFigure2_cmake_boolean_args # BUILD_DOCUMENTATION # BUILD_TESTING # BUILD_SHARED_LIBS # WITH_COVERAGE # WITH_MEMCHECK # ) #SET(GoFigure2_superbuild_boolean_args) #FOREACH(GoFigure2_cmake_arg ${GoFigure2_cmake_boolean_args}) # LIST(APPEND GoFigure2_superbuild_boolean_args -D${GoFigure2_cmake_arg}:BOOL=${${GoFigure2_cmake_arg}}) #ENDFOREACH() # MESSAGE("CMake args:") # FOREACH(arg ${GoFigure2_superbuild_boolean_args}) # MESSAGE(" ${arg}") # ENDFOREACH() #--------------------------------------------------------------------------- # Configure and build GoFigure2 #--------------------------------------------------------------------------- set(proj GoFigure2) option( GOFIGURE2_EXAMPLE "Force building GoFigure2's example" OFF ) option( GOFIGURE2_OPENMP "Enable OpenMP support for GoFigure2" ON ) ExternalProject_Add(${proj} DEPENDS ${GoFigure2_DEPENDENCIES} DOWNLOAD_COMMAND "" SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} BINARY_DIR GoFigure2-build CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${GoFigure2_superbuild_boolean_args} -DSUPERBUILD:BOOL=OFF # ITK -DITK_DIR:PATH=${ITK_DIR} # VTK -DVTK_DIR:PATH=${VTK_DIR} # QT (From VTK) -DQT_QMAKE_EXECUTABLE:PATH=${QT_QMAKE_EXECUTABLE} -DBUILD_EXAMPLES:BOOL=${GOFIGURE2_EXAMPLE} -DOPENMP_SUPPORT:BOOL=${GOFIGURE2_OPENMP} ${Boost_SUPPORT} INSTALL_COMMAND "" ) ADD_CUSTOM_TARGET(superinstall COMMAND ${CMAKE_COMMAND} -E chdir GoFigure2-build/ make install DEPENDS GoFigure2) ADD_CUSTOM_TARGET(superpackage COMMAND ${CMAKE_COMMAND} -E chdir GoFigure2-build/ make package DEPENDS GoFigure2) GoFigure2-v0.9.0/CMake/ConfigTests.cmake0000644000175000017500000000135311667757442017610 0ustar mathieumathieu#---------------------------------------------------------- INCLUDE ( CTest ) #---------------------------------------------------------- # Build name SET( BUILDNAME "${BUILDNAME}" CACHE STRING "Name of build on the dashboard" ) MARK_AS_ADVANCED( BUILDNAME ) #---------------------------------------------------------- # Sikuli OPTION( TESTING_USING_SIKULI "Use Sikuli for testing" OFF ) MARK_AS_ADVANCED( TESTING_USING_SIKULI ) IF( TESTING_USING_SIKULI ) FIND_PACKAGE( Sikuli ) ADD_SUBDIRECTORY( Testing ) ENDIF( TESTING_USING_SIKULI ) #---------------------------------------------------------- CONFIGURE_FILE( CMake/CTestCustom.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake @ONLY ) GoFigure2-v0.9.0/CMake/ConfigVTK.cmake0000644000175000017500000000637211667757442017160 0ustar mathieumathieu#---------------------------------------------------------- FIND_PACKAGE( VTK REQUIRED ) IF( VTK_FOUND ) #---------------------------------------------------------- INCLUDE( ${VTK_USE_FILE} ) # check for QQT insta;;er #---------------------------------------------------------- # Check the version of VTK # GoFigure2 requires vtk >= 5.6 IF( ( ${VTK_MAJOR_VERSION} LESS 5 ) OR ( ${VTK_MINOR_VERSION} LESS 6 ) ) MESSAGE( SEND_ERROR "GoFigure2 requires VTK 5.6 (your version of VTK is ${VTK_VERSION})" ) ENDIF( ( ${VTK_MAJOR_VERSION} LESS 5 ) OR ( ${VTK_MINOR_VERSION} LESS 6 ) ) #---------------------------------------------------------- # Check if version of VTK is > 5.6 # Requiered to now if we can use setBitRate() and setBitRateTolerance # in the vtkFFMPEGWriter IF( ( ${VTK_MAJOR_VERSION} EQUAL 5 ) AND ( ${VTK_MINOR_VERSION} GREATER 6 )) ADD_DEFINITIONS( -DVTKTRUNK ) ENDIF( ( ${VTK_MAJOR_VERSION} EQUAL 5 ) AND ( ${VTK_MINOR_VERSION} GREATER 6 )) #---------------------------------------------------------- IF( NOT ${VTK_USE_BOOST} MATCHES "ON" ) MESSAGE( SEND_ERROR "VTK must be compiled with Boost support" ) ENDIF( NOT ${VTK_USE_BOOST} MATCHES "ON" ) #---------------------------------------------------------- # Check if mysql is enabled IF( NOT ${VTK_USE_MYSQL} MATCHES "ON" ) # FIND_PACKAGE( MySQL REQUIRED ) # SET( MYSQL_LIBRARIES ${MYSQL_LIBRARIES} CACHE FILEPATH "" ) # SET( MYSQL_EXTRA_LIBRARIES ${MYSQL_EXTRA_LIBRARIES} CACHE FILEPATH "" ) #ELSE( ${VTK_USE_MYSQL} MATCHES "ON" ) MESSAGE( SEND_ERROR "VTK must be compiled with MySQL support" ) # TODO (arnaudgelas) # Here add a definition to be able to compile and use GoFigure # without any database support # ADD_DEFINITION( -DNODBSUPPORT ) ENDIF( NOT ${VTK_USE_MYSQL} MATCHES "ON" ) #---------------------------------------------------------- # Determine if GoFigure has to be built in shared or static # based on the configuration of VTK IF( VTK_BUILD_SHARED_LIBS ) SET( LIBS_STYLE "SHARED" ) SET( BUILD_SHARED_LIBS "TRUE" ) ADD_DEFINITIONS( -DGOFIGURE2_BUILD_SHARED_LIBS ) ELSE( VTK_BUILD_SHARED_LIBS ) SET( LIBS_STYLE "STATIC" ) SET( BUILD_SHARED_LIBS "FALSE" ) REMOVE_DEFINITIONS( -DGOFIGURE2_BUILD_SHARED_LIBS ) ENDIF( VTK_BUILD_SHARED_LIBS ) #---------------------------------------------------------- # Check if we can enable the video support # FFMPEG: for Linux and Mac (tested and validated) IF( VTK_USE_FFMPEG_ENCODER ) OPTION( ENABLE_VIDEO_RECORD_FFMPEG "VTK must be built with VTK_USE_FFMPEG_ENCODER" ON ) ENDIF( VTK_USE_FFMPEG_ENCODER ) IF( ENABLE_VIDEO_RECORD_FFMPEG ) ADD_DEFINITIONS( -DENABLEFFMPEG ) ELSE( ENABLE_VIDEO_RECORD_FFMPEG ) REMOVE_DEFINITIONS( -DENABLEFFMPEG ) ENDIF( ENABLE_VIDEO_RECORD_FFMPEG ) # AVI: for Windows only IF( VTK_USE_VIDEO_FOR_WINDOWS ) OPTION( ENABLE_VIDEO_RECORD_AVI "VTK must be built with VTK_USE_AVI_ENCODER" ON ) ENDIF( VTK_USE_VIDEO_FOR_WINDOWS ) IF( ENABLE_VIDEO_RECORD_AVI ) ADD_DEFINITIONS( -DENABLEAVI ) ELSE( ENABLE_VIDEO_RECORD_AVI ) REMOVE_DEFINITIONS( -DENABLEAVI ) ENDIF( ENABLE_VIDEO_RECORD_AVI ) ELSE( VTK_FOUND ) MESSAGE( SEND_ERROR "VTK NOT FOUND, CMAKE WILL STOP NOW") ENDIF( VTK_FOUND ) GoFigure2-v0.9.0/CMake/ConfigVideo.cmake0000644000175000017500000000105611667757442017554 0ustar mathieumathieuSET( VIDEO_SUPPORT ) #----------------------------------------------------------------------------- # Is FFMPEG AVAILABLE ( FOR UNIX) MAC?? IF( NOT WIN32 ) FIND_PACKAGE( FFMPEG ) IF( FFMPEG_FOUND ) LIST( APPEND VIDEO_SUPPORT -DVTK_USE_FFMPEG_ENCODER:BOOL=ON ) ELSE( FFMPEG_FOUND ) LIST( APPEND VIDEO_SUPPORT -DVTK_USE_FFMPEG_ENCODER:BOOL=OFF ) ENDIF( FFMPEG_FOUND ) # DO STH FOR WINDOWS # turn on video by default ELSE( NOT WIN32 ) LIST( APPEND VIDEO_SUPPORT -DVTK_USE_AVI_ENCODER:BOOL=ON ) ENDIF( NOT WIN32 ) GoFigure2-v0.9.0/CMake/GoFigure2Valgrind.supp0000644000175000017500000345262611667757442020567 0ustar mathieumathieu{ Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:* obj:* obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:* obj:* obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:* obj:* obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:* obj:* obj:* } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Param open(filename) obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Param open(filename) obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Param stat(file_name) obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond fun:calloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:* obj:* obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/lib/libglib-2.0.so.0.2200.3 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/lib/libglib-2.0.so.0.2200.3 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateLC fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc obj:/usr/lib/libgthread-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc obj:/usr/lib/libgthread-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/lib/libc-2.10.1.so obj:* obj:/lib/libc-2.10.1.so obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_charset fun:g_get_filename_charsets obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/lib/libc-2.10.1.so obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_charset fun:g_get_filename_charsets obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/lib/libc-2.10.1.so obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_filename_charsets obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_filename_charsets obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc0 fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN19QApplicationPrivate21createEventDispatcherEv } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:FcBlanksCreate obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:FcFontSetCreate fun:FcConfigBuildFonts fun:FcInitLoadConfigAndFonts fun:FcInit obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN19QApplicationPrivate9constructEP9_XDisplaymm } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:realloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcDefaultLoader fun:_XOpenLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrCopyFilename fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrCopyFilename fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrCopyFilename fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 fun:_ZN7vtkMath20LUFactorLinearSystemEPPdPiiS0_ obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 fun:_ZN7vtkMath20LUFactorLinearSystemEPPdPiiS0_ obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcDefaultSubstitute obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/lib/libglib-2.0.so.0.2200.3 obj:* obj:/lib/libglib-2.0.so.0.2200.3 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/lib/libexpat.so.1.5.2 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:FcPatternCreate obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase obj:/usr/lib/libX11.so.6.2.0 fun:XGetDefault } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XextCreateExtension fun:XInput_find_display fun:XListInputDevices obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN19QApplicationPrivate9constructEP9_XDisplaymm fun:_ZN12QApplicationC1ERiPPci } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libGLcore.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontRenderPrepare fun:FcFontSetMatch fun:FcFontMatch obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontRenderPrepare fun:FcFontSetMatch fun:FcFontMatch obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcObjectSetAdd obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi fun:_ZNK13QFontMetricsF7leadingEv } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:calloc obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* fun:_ZN12vtkPNGReaderD1Ev obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* fun:_ZN5vtkgl13LoadExtensionEPKcP25vtkOpenGLExtensionManager obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* fun:_ZN13vtkGLSLShader18GetUniformLocationEPKc obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* fun:_ZN13vtkTIFFReader21OriginSpecifiedFlagOnEv obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* fun:_Z21vtkImageReaderUpdate2IisEvP14vtkImageReaderP12vtkImageDataPT_PT0_ obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* fun:_Z21vtkImageReaderUpdate2IamEvP14vtkImageReaderP12vtkImageDataPT_PT0_ obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* fun:_ZSt4copyIN9__gnu_cxx17__normal_iteratorIPKSt6vectorIdSaIdEES2_IS4_SaIS4_EEEENS1_IPS4_S8_EEET0_T_SD_SC_ fun:_ZSt4copyIN9__gnu_cxx17__normal_iteratorIPKSt6vectorIdSaIdEES2_IS4_SaIS4_EEEENS1_IPS4_S8_EEET0_T_SD_SC_ obj:* obj:* obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc obj:/usr/lib/libgthread-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc obj:/usr/lib/libgthread-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc obj:/usr/lib/libgthread-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc obj:/usr/lib/libgthread-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc obj:/usr/lib/libgthread-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcDefaultLoader fun:_XOpenLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libavutil.so.49.15.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libavutil.so.49.15.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libQtSql.so.4.5.2 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libICE.so.6.3.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libGLcore.so.185.18.36 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libvorbisenc.so.2.0.3 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libvorbisenc.so.2.0.3 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libvorbisenc.so.2.0.3 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libXau.so.6.0.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libxcb.so.1.1.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-x86-64.cache-2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigBuildFonts } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc obj:/usr/lib/libgthread-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN19QApplicationPrivate21createEventDispatcherEv fun:_ZN16QCoreApplication4initEv fun:_ZN16QCoreApplicationC2ER23QCoreApplicationPrivate fun:_ZN12QApplicationC1ERiPPci fun:main } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcConfigSubstituteWithPat obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei fun:_ZNK12QFontPrivate15engineForScriptEi } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/lib/libglib-2.0.so.0.2200.3 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAddFilename obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:XCreateOC fun:XCreateFontSet obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libXdmcp.so.6.0.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libXdmcp.so.6.0.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:realloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_realloc obj:/lib/libglib-2.0.so.0.2200.3 fun:g_array_set_size fun:g_static_private_set fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/var/cache/fontconfig/865f88548240fee46819705c6468c165-x86-64.cache-2 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcDirCacheLoad fun:FcDirCacheRead } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/var/cache/fontconfig/e13b20fdb08344e0e664864cc2ede53d-x86-64.cache-2 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcDirCacheLoad fun:FcDirCacheRead } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/var/cache/fontconfig/4794a0821666d79190d59a36cb4f44b5-x86-64.cache-2 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcDirCacheLoad fun:FcDirCacheRead } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/var/cache/fontconfig/4c73fe0c47614734b17d736dbde7580a-x86-64.cache-2 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcDirCacheLoad fun:FcDirCacheRead } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XrmInternalStringToQuark fun:XrmInitialize obj:/usr/lib/libX11.so.6.2.0 fun:XGetDefault obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcAddUtf8Converters fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcAddUtf8Converters fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcAddUtf8Converters fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcAddUtf8Converters fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcAddUtf8Converters fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcAddUtf8Converters fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcSetConverter fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:calloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Leak fun:calloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Leak fun:calloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 fun:_ZN7vtkMath20LUFactorLinearSystemEPPdPiiS0_ obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 fun:_ZN7vtkMath20LUFactorLinearSystemEPPdPiiS0_ obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateDefaultCharSet fun:_XlcAddCT fun:_XlcInitCTInfo obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:calloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc0 fun:g_source_new obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN19QApplicationPrivate21createEventDispatcherEv fun:_ZN16QCoreApplication4initEv } { Memcheck:Leak fun:malloc fun:realloc obj:/usr/lib/libGL.so.185.18.36 obj:/lib/libc-2.10.1.so obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:FcConfigCreate fun:FcInitLoadConfig fun:FcInitLoadConfigAndFonts fun:FcInit obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN19QApplicationPrivate9constructEP9_XDisplaymm } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:calloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* fun:__pthread_mutex_lock_full fun:g_main_context_new fun:g_main_context_default fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN19QApplicationPrivate21createEventDispatcherEv fun:_ZN16QCoreApplication4initEv fun:_ZN16QCoreApplicationC2ER23QCoreApplicationPrivate } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend fun:g_strsplit fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN19QApplicationPrivate21createEventDispatcherEv fun:_ZN16QCoreApplication4initEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/lib/libglib-2.0.so.0.2200.3 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc0 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:FcFontSetAdd obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:realloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:FcBlanksAdd obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcStrSetAdd fun:FcConfigParseAndLoad fun:FcConfigParseAndLoad obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 fun:FcFontSetList fun:FcFontList obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc fun:g_strdup fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XimOpenIM fun:_XimRegisterIMInstantiateCallback fun:XRegisterIMInstantiateCallback obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN20QInputContextFactory6createERK7QStringP7QObject fun:_ZNK12QApplication12inputContextEv } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcDefaultLoader fun:_XOpenLC } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_array_sized_new fun:g_static_private_set fun:g_get_filename_charsets obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_array_sized_new fun:g_static_private_set fun:g_get_filename_charsets obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/lib/libglib-2.0.so.0.2200.3 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc0 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/lib/libglib-2.0.so.0.2200.3 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc0 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend fun:g_strsplit fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN19QApplicationPrivate21createEventDispatcherEv fun:_ZN16QCoreApplication4initEv } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_array_sized_new fun:g_static_private_set fun:g_get_filename_charsets obj:/lib/libglib-2.0.so.0.2200.3 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN19QApplicationPrivate21createEventDispatcherEv fun:_ZN16QCoreApplication4initEv fun:_ZN16QCoreApplicationC2ER23QCoreApplicationPrivate } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN19QApplicationPrivate21createEventDispatcherEv fun:_ZN16QCoreApplication4initEv fun:_ZN16QCoreApplicationC2ER23QCoreApplicationPrivate } { Memcheck:Leak fun:realloc obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/usr/lib/libfontconfig.so.1.3.0 obj:/lib/libexpat.so.1.5.2 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc0 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_language_names fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:/lib/libglib-2.0.so.0.2200.3 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_malloc0 fun:g_slice_alloc fun:g_array_sized_new fun:g_static_private_set fun:g_get_filename_charsets obj:/lib/libglib-2.0.so.0.2200.3 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XlcCreateLocaleDataBase obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/libX11.so.6.2.0 fun:_XlcCreateLC fun:_XlcUtf8Loader fun:_XOpenLC } { Memcheck:Leak fun:realloc obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 obj:* obj:/usr/lib/libX11.so.6.2.0 obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XrmInternalStringToQuark fun:XrmInitialize obj:/usr/lib/libX11.so.6.2.0 fun:XGetDefault obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:calloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libxcb.so.1.1.0 obj:/usr/lib/libxcb.so.1.1.0 obj:/usr/lib/libxcb.so.1.1.0 fun:xcb_wait_for_reply fun:_XReply fun:XInternAtoms } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:malloc obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:* obj:* obj:* obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:* obj:* obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:* obj:* obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:* obj:* obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:* obj:* obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond fun:calloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Param stat(file_name) obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libc-2.10.1.so } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Param open(filename) obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Param open(filename) obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Value8 obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:* obj:* obj:* obj:* obj:/dev/zero obj:* obj:* obj:* obj:* obj:* } { Memcheck:Addr8 obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* } { Memcheck:Addr8 obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* } { Memcheck:Addr8 obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XtCalloc obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv fun:_ZN22vtkXOpenGLRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XtCalloc obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv fun:_ZN22vtkXOpenGLRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XtCalloc obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv fun:_ZN22vtkXOpenGLRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XtCalloc obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv fun:_ZN22vtkXOpenGLRenderWindow6RenderEv } { Memcheck:Leak fun:malloc fun:realloc obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* fun:_ZNK11QToolButton15initStyleOptionEP22QStyleOptionToolButton obj:* obj:* fun:XCreateColormap fun:_ZN22vtkXOpenGLRenderWindow18GetDesiredColormapEv fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv fun:_ZN22vtkXOpenGLRenderWindow6RenderEv fun:_ZN12vtkViewImage6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libQtGui.so.4.5.2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XcmsAddCmapRec fun:XCreateColormap fun:_ZN22vtkXOpenGLRenderWindow18GetDesiredColormapEv fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv fun:_ZN22vtkXOpenGLRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libQtSql.so.4.5.2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XcmsAddCmapRec fun:XCreateColormap fun:_ZN22vtkXOpenGLRenderWindow18GetDesiredColormapEv fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv fun:_ZN22vtkXOpenGLRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libQtCore.so.4.5.2 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:_XcmsAddCmapRec fun:XCreateColormap fun:_ZN22vtkXOpenGLRenderWindow18GetDesiredColormapEv fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv fun:_ZN22vtkXOpenGLRenderWindow6RenderEv } { Memcheck:Leak fun:malloc fun:realloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libXext.so.6.4.0 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libXext.so.6.4.0 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libXext.so.6.4.0 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libXext.so.6.4.0 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XInitExtension fun:XextAddDisplay obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XInitExtension fun:XextAddDisplay obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XInitExtension fun:XextAddDisplay obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libX11.so.6.2.0 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XInitExtension fun:XextAddDisplay obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libXt.so.6.0.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 fun:XInternAtom obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libXt.so.6.0.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 fun:XInternAtom obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libXt.so.6.0.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 fun:XInternAtom obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/libXt.so.6.0.0 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libX11.so.6.2.0 fun:XInternAtom obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XtCalloc fun:_XtAllocWWTable obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XtCalloc fun:_XtAllocWWTable obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XtCalloc fun:_XtAllocWWTable obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:XtCalloc fun:_XtAllocWWTable obj:/usr/lib/libXt.so.6.0.0 fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv fun:_ZN15vtkRenderWindow6RenderEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 fun:_ZN15vtkRenderWindow6RenderEv fun:_ZN22vtkXOpenGLRenderWindow6RenderEv fun:_ZN12vtkViewImage6RenderEv fun:_ZN15vtkImageViewer219SetSliceOrientationEi fun:_ZN14vtkViewImage2D18SetViewOrientationEi fun:main } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:xcb_connect_to_fd fun:xcb_connect_to_display_with_auth_info fun:_XConnectXCB fun:XOpenDisplay fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:xcb_connect_to_fd fun:xcb_connect_to_display_with_auth_info fun:_XConnectXCB fun:XOpenDisplay fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:xcb_connect_to_fd fun:xcb_connect_to_display_with_auth_info fun:_XConnectXCB fun:XOpenDisplay fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:xcb_connect_to_fd fun:xcb_connect_to_display_with_auth_info fun:_XConnectXCB fun:XOpenDisplay fun:XtOpenDisplay fun:_ZN26vtkXRenderWindowInteractor10InitializeEv } { Memcheck:Addr8 obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* } { Memcheck:Addr8 obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* } { Memcheck:Addr8 obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:/usr/lib/libGL.so.185.18.36 obj:* obj:* obj:* } { Memcheck:Value8 obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:* obj:* obj:* obj:* obj:* obj:* obj:* obj:* obj:* obj:* } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 fun:_ZN8QLibrary7resolveEPKc } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:malloc fun:__nss_lookup_function obj:* obj:* fun:getpwnam_r obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_home_dir fun:ORBit_option_parse fun:CORBA_ORB_init fun:gconf_orb_get obj:/usr/lib/libgconf-2.so.4.1.5 fun:gconf_activate_server } { Memcheck:Leak fun:malloc fun:__nss_lookup_function obj:* obj:* fun:getpwnam_r obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_home_dir fun:ORBit_option_parse fun:CORBA_ORB_init fun:gconf_orb_get obj:/usr/lib/libgconf-2.so.4.1.5 fun:gconf_activate_server } { Memcheck:Leak fun:malloc fun:__nss_lookup_function obj:* obj:* fun:getpwnam_r obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_home_dir fun:ORBit_option_parse fun:CORBA_ORB_init fun:gconf_orb_get obj:/usr/lib/libgconf-2.so.4.1.5 fun:gconf_activate_server } { Memcheck:Leak fun:malloc fun:__nss_lookup_function obj:* obj:* fun:getpwnam_r obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_home_dir fun:ORBit_option_parse fun:CORBA_ORB_init fun:gconf_orb_get obj:/usr/lib/libgconf-2.so.4.1.5 fun:gconf_activate_server } { Memcheck:Leak fun:malloc fun:__nss_lookup_function obj:* obj:* fun:getpwnam_r obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_home_dir fun:ORBit_option_parse fun:CORBA_ORB_init fun:gconf_orb_get obj:/usr/lib/libgconf-2.so.4.1.5 fun:gconf_activate_server } { Memcheck:Leak fun:malloc fun:tsearch fun:__nss_lookup_function obj:* obj:* fun:getpwnam_r obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_home_dir fun:ORBit_option_parse fun:CORBA_ORB_init fun:gconf_orb_get obj:/usr/lib/libgconf-2.so.4.1.5 } { Memcheck:Leak fun:malloc fun:tsearch fun:__nss_lookup_function obj:* obj:* fun:getpwnam_r obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_home_dir fun:ORBit_option_parse fun:CORBA_ORB_init fun:gconf_orb_get obj:/usr/lib/libgconf-2.so.4.1.5 } { Memcheck:Leak fun:malloc fun:tsearch fun:__nss_lookup_function obj:* obj:* fun:getpwnam_r obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_home_dir fun:ORBit_option_parse fun:CORBA_ORB_init fun:gconf_orb_get obj:/usr/lib/libgconf-2.so.4.1.5 } { Memcheck:Leak fun:malloc fun:tsearch fun:__nss_lookup_function obj:* obj:* fun:getpwnam_r obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_home_dir fun:ORBit_option_parse fun:CORBA_ORB_init fun:gconf_orb_get obj:/usr/lib/libgconf-2.so.4.1.5 } { Memcheck:Leak fun:malloc fun:tsearch fun:__nss_lookup_function obj:* obj:* fun:getpwnam_r obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_home_dir fun:ORBit_option_parse fun:CORBA_ORB_init fun:gconf_orb_get obj:/usr/lib/libgconf-2.so.4.1.5 } { Memcheck:Leak fun:malloc fun:strdup obj:/usr/lib/libcairo.so.2.10800.8 obj:/usr/lib/libcairo.so.2.10800.8 fun:cairo_ft_font_face_create_for_pattern obj:/usr/lib/libpangocairo-1.0.so.0.2600.0 obj:/usr/lib/libpangocairo-1.0.so.0.2600.0 obj:/usr/lib/pango/1.6.0/modules/pango-basic-fc.so fun:pango_shape obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlclose obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libgmodule-2.0.so.0.2200.3 fun:g_module_close obj:/usr/lib/libgio-2.0.so.0.2200.3 fun:g_type_module_unuse obj:/usr/lib/libgio-2.0.so.0.2200.3 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so } { Memcheck:Leak fun:malloc fun:getdelim obj:/lib/libselinux.so.1 obj:/lib/libselinux.so.1 obj:/lib/libselinux.so.1 obj:* obj:* obj:* obj:* obj:* obj:* obj:* } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend obj:/usr/lib/libgobject-2.0.so.0.2200.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_fc_font_create_metrics_for_context obj:/usr/lib/libpangocairo-1.0.so.0.2600.0 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_copy obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/gtk-2.0/2.10.0/engines/libclearlooks.so obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_get_style obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_widget_realize fun:gtk_widget_set_parent } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/lib/libc-2.10.1.so fun:__nss_database_lookup obj:* obj:* fun:getpwnam_r obj:/lib/libglib-2.0.so.0.2200.3 fun:g_get_home_dir fun:ORBit_option_parse fun:CORBA_ORB_init fun:gconf_orb_get obj:/usr/lib/libgconf-2.so.4.1.5 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlclose obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libgmodule-2.0.so.0.2200.3 fun:g_module_close obj:/usr/lib/libgio-2.0.so.0.2200.3 fun:g_type_module_unuse obj:/usr/lib/libgio-2.0.so.0.2200.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend fun:pango_attr_iterator_get_font obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_layout_get_unknown_glyphs_count obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend fun:pango_attr_iterator_get_font obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_layout_get_unknown_glyphs_count obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_fc_font_create_metrics_for_context obj:/usr/lib/libpangocairo-1.0.so.0.2600.0 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_connect_data obj:/usr/lib/libORBit-2.so.0.1.0 obj:/usr/lib/libORBit-2.so.0.1.0 fun:g_main_context_dispatch obj:/lib/libglib-2.0.so.0.2200.3 fun:g_main_context_iteration fun:giop_recv_buffer_get fun:ORBit_small_invoke_stub } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gtk_window_new obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN9QGtkStyleC1Ev } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_connect_data obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:pango_font_metrics_new fun:pango_fc_font_create_metrics_for_context obj:/usr/lib/libpangocairo-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_layout_line_get_extents obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_ptr_array_sized_new obj:/usr/lib/libpangoft2-1.0.so.0.2600.0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libpangoft2-1.0.so.0.2600.0 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_emit_valist fun:g_signal_emit obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_widget_set_parent fun:gtk_fixed_put fun:g_closure_invoke obj:/usr/lib/libgobject-2.0.so.0.2200.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_emit_valist fun:g_signal_emit obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN9QGtkStyleC1Ev fun:_ZN13QStyleFactory6createERK7QString fun:_ZN12QApplication5styleEv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_log2vis_get_embedding_levels obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_layout_get_unknown_glyphs_count obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon fun:gtk_icon_set_render_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_connect_data obj:/usr/lib/libORBit-2.so.0.1.0 obj:/usr/lib/libORBit-2.so.0.1.0 fun:g_main_context_dispatch obj:/lib/libglib-2.0.so.0.2200.3 fun:g_main_context_iteration fun:giop_recv_buffer_get fun:ORBit_small_invoke_stub } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon fun:gtk_icon_set_render_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:gdk_region_new fun:gdk_region_copy obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 fun:gdk_window_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_closure_invoke obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_signal_emit_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon fun:gtk_icon_set_render_icon } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so } { Memcheck:Leak fun:calloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend fun:gdk_pixbuf_get_formats obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend obj:/usr/lib/libgobject-2.0.so.0.2200.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_copy obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/gtk-2.0/2.10.0/engines/libclearlooks.so obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_get_style obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_widget_realize fun:gtk_widget_set_parent } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_hash_table_foreach fun:g_param_spec_pool_list fun:g_object_class_list_properties obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_find_map obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_layout_get_unknown_glyphs_count obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_find_map obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_layout_get_unknown_glyphs_count } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend fun:g_object_notify fun:gtk_entry_set_buffer obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend fun:g_strsplit fun:pango_font_description_from_string obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_copy obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_get_style obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_widget_realize fun:gtk_widget_set_parent fun:gtk_fixed_put } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_copy obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/gtk-2.0/2.10.0/engines/libclearlooks.so obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_get_style obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_widget_realize obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_copy obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_get_style obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_widget_realize fun:gtk_widget_set_parent obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_copy obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_get_style obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_widget_realize fun:gtk_widget_set_parent fun:gtk_fixed_put } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:pango_layout_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend fun:g_object_notify obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_widget_realize obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_copy obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:_ZNK9QGtkStyle15standardPaletteEv fun:_ZN12QApplication5styleEv fun:_ZN19QApplicationPrivate10initializeEv fun:_ZN19QApplicationPrivate9constructEP9_XDisplaymm fun:_ZN12QApplicationC1ERiPPci } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/lib/libglib-2.0.so.0.2200.3 fun:gtk_icon_set_add_source obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_factory_lookup_default obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZNK9QGtkStyle14standardPixmapEN6QStyle14StandardPixmapEPK12QStyleOptionPK7QWidget fun:_ZNK16QCleanlooksStyle26standardIconImplementationEN6QStyle14StandardPixmapEPK12QStyleOptionPK7QWidget } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/lib/libglib-2.0.so.0.2200.3 fun:gtk_icon_set_add_source obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_factory_lookup_default obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZNK9QGtkStyle14standardPixmapEN6QStyle14StandardPixmapEPK12QStyleOptionPK7QWidget fun:_ZNK16QCleanlooksStyle26standardIconImplementationEN6QStyle14StandardPixmapEPK12QStyleOptionPK7QWidget } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon fun:gtk_icon_set_render_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_connect_data obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_string_sized_new obj:/lib/libglib-2.0.so.0.2200.3 fun:g_build_filename obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_connect_data obj:/usr/lib/libORBit-2.so.0.1.0 obj:/usr/lib/libORBit-2.so.0.1.0 fun:g_main_context_dispatch obj:/lib/libglib-2.0.so.0.2200.3 fun:g_main_context_iteration fun:giop_recv_buffer_get fun:ORBit_small_invoke_stub } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_connect_data obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_connect_data obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_emit_valist fun:g_signal_emit obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN9QGtkStyleC1Ev fun:_ZN13QStyleFactory6createERK7QString fun:_ZN12QApplication5styleEv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gconf_client_get_default obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon fun:gtk_icon_set_render_icon obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_type_class_ref } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_string obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_int obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_string obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gtk_settings_get_for_screen obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_reparse_all_for_settings fun:gtk_settings_get_for_screen obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_object obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgobject-2.0.so.0.2200.3 obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_type_class_ref } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_int obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_object_newv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_int obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_object obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_pointer obj:/usr/lib/libpangoft2-1.0.so.0.2600.0 fun:g_type_class_ref fun:g_type_class_ref fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_double obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_new obj:/usr/lib/gio/modules/libgioremote-volume-monitor.so obj:/usr/lib/libgio-2.0.so.0.2200.3 fun:g_type_module_use fun:g_io_modules_load_all_in_directory obj:/usr/lib/libgio-2.0.so.0.2200.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_enum obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_enum obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_float obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_type_class_ref } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_override fun:g_object_class_override_property obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_object obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_enum obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_object_newv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon fun:gtk_icon_set_render_icon obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gconf_client_get_default obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_double obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_object_newv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_double obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_object_newv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_string obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_string obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gtk_settings_get_for_screen obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_reparse_all_for_settings } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_reparse_all_for_settings } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_object obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgobject-2.0.so.0.2200.3 obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_type_class_ref } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_int obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_string obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_object obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_find_map } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_find_map } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_pointer obj:/usr/lib/libpangoft2-1.0.so.0.2600.0 fun:g_type_class_ref fun:g_type_class_ref fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:pango_coverage_set obj:/usr/lib/libpangoft2-1.0.so.0.2600.0 obj:/usr/lib/libpangoft2-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_double obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_enum obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_new obj:/usr/lib/gio/modules/libgioremote-volume-monitor.so obj:/usr/lib/libgio-2.0.so.0.2200.3 fun:g_type_module_use fun:g_io_modules_load_all_in_directory obj:/usr/lib/libgio-2.0.so.0.2200.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_float obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_type_class_ref } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_int obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_object obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_enum obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_double obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_object_newv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_key_file_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_key_file_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_int obj:/usr/lib/libgdk_pixbuf-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gtk_window_new obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN9QGtkStyleC1Ev } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:pango_font_metrics_new fun:pango_fc_font_create_metrics_for_context obj:/usr/lib/libpangocairo-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_layout_line_get_extents obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_ptr_array_sized_new obj:/usr/lib/libpangoft2-1.0.so.0.2600.0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libpangoft2-1.0.so.0.2600.0 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_emit_valist fun:g_signal_emit obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_widget_set_parent fun:gtk_fixed_put fun:g_closure_invoke obj:/usr/lib/libgobject-2.0.so.0.2200.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_datalist_id_set_data_full fun:gtk_widget_get_pango_context fun:gtk_widget_create_pango_layout obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:gdk_region_new fun:gdk_region_copy obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 fun:gdk_window_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_closure_invoke obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_signal_emit_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_log2vis_get_embedding_levels obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_layout_get_unknown_glyphs_count obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_datalist_id_set_data_full fun:g_object_freeze_notify obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_widget_realize fun:gtk_widget_set_parent fun:gtk_fixed_put fun:g_closure_invoke obj:/usr/lib/libgobject-2.0.so.0.2200.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:gdk_region_new fun:gdk_region_copy obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 fun:gdk_window_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_closure_invoke obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_signal_emit_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_append obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_reparse_all_for_settings fun:gtk_settings_get_for_screen } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_reparse_all_for_settings fun:gtk_settings_get_for_screen } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_string_sized_new obj:/lib/libglib-2.0.so.0.2200.3 fun:g_build_filename obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_find_map obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_layout_get_unknown_glyphs_count obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_datalist_id_set_data_full obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gdk_window_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_emit_valist fun:g_signal_emit obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN9QGtkStyleC1Ev fun:_ZN13QStyleFactory6createERK7QString fun:_ZN12QApplication5styleEv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:pango_ot_buffer_new obj:/usr/lib/pango/1.6.0/modules/pango-basic-fc.so fun:pango_shape obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_layout_get_unknown_glyphs_count obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_signal_emit_valist fun:g_signal_emit fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_string_sized_new obj:/lib/libglib-2.0.so.0.2200.3 fun:g_build_filename obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:giop_server_new fun:ORBit_ORB_start_servers } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_int obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_type_class_ref } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_enum obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_float obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_object_newv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_boolean obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_type_class_ref } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_int obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_int obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_type_class_ref fun:g_object_newv } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_find_map obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_layout_get_unknown_glyphs_count obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:pango_coverage_set obj:/usr/lib/libpangoft2-1.0.so.0.2600.0 obj:/usr/lib/libpangoft2-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 obj:/usr/lib/libpango-1.0.so.0.2600.0 fun:pango_itemize_with_base_dir } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_double obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_new_valist fun:g_object_new } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance fun:g_param_spec_internal fun:g_param_spec_enum obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_binding_entry_add_signal obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_class_ref fun:g_object_newv fun:g_object_new_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon fun:gtk_icon_set_render_icon obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:link_connection_initiate fun:giop_connection_initiate fun:ORBit_object_get_connection } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gdk_screen_get_system_colormap obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_cache_insert fun:gtk_gc_get obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/gtk-2.0/2.10.0/engines/libclearlooks.so fun:g_closure_invoke obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_signal_emit_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_cache_insert fun:gtk_gc_get obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/gtk-2.0/2.10.0/engines/libclearlooks.so fun:g_closure_invoke obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_signal_emit_valist } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gtk_arrow_new obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN9QGtkStyleC1Ev } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libpangocairo-1.0.so.0.2600.0 obj:/usr/lib/libpangoft2-1.0.so.0.2600.0 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gtk_label_new fun:gtk_expander_set_label } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gtk_label_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:malloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon fun:gtk_icon_set_render_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon fun:gtk_icon_set_render_icon obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:calloc obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon fun:gtk_icon_set_render_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gdk_display_open fun:gdk_display_open_default_libgtk_only } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:theme_create_rc_style obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN9QGtkStyleC1Ev } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN9QGtkStyleC1Ev } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN9QGtkStyleC1Ev } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_create_instance } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gdk_window_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN9QGtkStyleC1Ev } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:g_type_create_instance } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gdk_window_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slist_prepend obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_get_string_list obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon fun:gtk_icon_set_render_icon obj:/usr/lib/libQtGui.so.4.5.2 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_hash_table_new_full obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:theme_create_rc_style obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libQtGui.so.4.5.2 fun:_ZN9QGtkStyleC1Ev } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new fun:gtk_widget_get_default_style obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_string_sized_new obj:/lib/libglib-2.0.so.0.2200.3 fun:g_build_filename obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_icon_theme_lookup_icon fun:gtk_icon_theme_load_icon } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 fun:gtk_rc_get_style } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_slice_alloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.so.0.2200.3 fun:g_object_newv fun:g_object_new_valist fun:g_object_new obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgdk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2200.3 fun:g_slice_alloc fun:g_list_prepend obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 obj:/lib/libglib-2.0.so.0.2200.3 fun:g_key_file_load_from_file obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 obj:/usr/lib/libgtk-x11-2.0.so.0.1800.3 } { Memcheck:Leak fun:calloc obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 obj:* obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 obj:/usr/lib/libQtCore.so.4.5.2 fun:_ZN8QLibrary7resolveEPKc } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so } { Memcheck:Value8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlopen obj:/usr/lib/libGL.so.185.18.36 } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Addr8 obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/libdl-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libdl-2.10.1.so fun:dlsym obj:/usr/lib/tls/libnvidia-tls.so.185.18.36 fun:g_module_symbol fun:g_module_open } { Memcheck:Cond fun:floorf obj:/usr/lib/libGLcore.so.185.18.36 obj:* } { Memcheck:Cond fun:floorf obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:* obj:* obj:* obj:* obj:* obj:* obj:* obj:* obj:* } { Memcheck:Cond fun:floorf obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:* obj:* obj:* obj:* obj:* obj:* obj:* obj:* obj:* } { Memcheck:Cond fun:floorf obj:/usr/lib/libGLcore.so.185.18.36 } { Memcheck:Cond obj:/usr/lib/libGLcore.so.185.18.36 obj:* } { Memcheck:Cond obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:* obj:* obj:* } { Memcheck:Cond obj:/usr/lib/libGLcore.so.185.18.36 obj:* obj:* obj:* } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode fun:__nss_lookup_function obj:/lib/libc-2.10.1.so fun:getservbyname_r fun:getservbyname fun:mysql_server_init fun:mysql_init } { Memcheck:Leak fun:_Znwm fun:_ZN11QThreadData7currentEv fun:_ZN7QThread13currentThreadEv fun:_ZN23QCoreApplicationPrivateC2ERiPPc fun:_ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeE fun:_ZN12QApplicationC1ERiPPci fun:main } { Memcheck:Leak fun:_Znwm fun:_ZN14QWaitConditionC1Ev fun:_ZN14QThreadPrivateC1EP11QThreadData fun:_ZN14QAdoptedThreadC1EP11QThreadData fun:_ZN11QThreadData7currentEv fun:_ZN7QThread13currentThreadEv fun:_ZN23QCoreApplicationPrivateC2ERiPPc fun:_ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeE fun:_ZN12QApplicationC1ERiPPci fun:main } { Memcheck:Leak fun:_Znwm fun:_ZN6QMutexC1ENS_13RecursionModeE fun:_ZN11QThreadDataC1Ei fun:_ZN11QThreadData7currentEv fun:_ZN7QThread13currentThreadEv fun:_ZN23QCoreApplicationPrivateC2ERiPPc fun:_ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeE fun:_ZN12QApplicationC1ERiPPci fun:main } { Memcheck:Leak fun:_Znwm fun:_ZN7QObjectC2EPS_ fun:_ZN14QImageIOPluginC2EP7QObject fun:_ZN10QGifPluginC1Ev fun:qt_plugin_instance fun:_ZNK14QFactoryLoader8instanceERK7QString fun:_ZN12QImageReader21supportedImageFormatsEv fun:_ZN19QImageReaderPrivate11initHandlerEv fun:_ZN12QImageReader4readEP6QImage fun:_ZN12QImageReader4readEv fun:_ZN7QPixmap4loadERK7QStringPKc6QFlagsIN2Qt19ImageConversionFlagEE fun:_ZN7QPixmapC1ERK7QStringPKc6QFlagsIN2Qt19ImageConversionFlagEE } { Memcheck:Leak fun:_Znwm fun:_ZN14QAdoptedThreadC1EP11QThreadData fun:_ZN11QThreadData7currentEv fun:_ZN7QThread13currentThreadEv fun:_ZN23QCoreApplicationPrivateC2ERiPPc fun:_ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeE fun:_ZN12QApplicationC1ERiPPci fun:main } { Memcheck:Cond obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/ld-2.10.1.so obj:/lib/libc-2.10.1.so obj:/lib/ld-2.10.1.so fun:__libc_dlopen_mode fun:__nss_lookup_function obj:/lib/libc-2.10.1.so fun:getservbyname_r fun:getservbyname fun:mysql_server_init fun:mysql_init } { Memcheck:Cond obj:/lib/libc-2.11.1.so obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Value8 obj:/lib/libc-2.11.1.so obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Value8 obj:/lib/libc-2.11.1.so obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 obj:/lib/libexpat.so.1.5.2 fun:XML_ParseBuffer fun:FcConfigParseAndLoad } { Memcheck:Leak fun:malloc obj:/lib/ld-2.11.1.so obj:/lib/ld-2.11.1.so obj:/lib/ld-2.11.1.so obj:/lib/ld-2.11.1.so obj:/lib/libdl-2.11.1.so obj:/lib/ld-2.11.1.so obj:/lib/libdl-2.11.1.so fun:dlopen fun:_ZN15QLibraryPrivate8load_sysEv fun:_Z7qt_initP19QApplicationPrivateiP9_XDisplaymm fun:_ZN19QApplicationPrivate9constructEP9_XDisplaymm } { Memcheck:Leak fun:malloc obj:/usr/lib/libX11.so.6.3.0 obj:/usr/lib/libX11.so.6.3.0 obj:/usr/lib/libX11.so.6.3.0 fun:_XlcCreateLC fun:_XlcDefaultLoader fun:_XOpenLC fun:_XrmInitParseInfo obj:/usr/lib/libX11.so.6.3.0 fun:XrmGetStringDatabase obj:/usr/lib/libX11.so.6.3.0 fun:XGetDefault } { Memcheck:Value8 obj:/lib/libc-2.11.1.so fun:_ZL21normalizeTypeInternalPKcS0_bb fun:_ZL21normalizeTypeInternalPKcS0_bb fun:_ZL14qNormalizeTypePcRiR10QByteArray fun:_ZN11QMetaObject14normalizedTypeEPKc fun:_ZN9QMetaType12registerTypeEPKcPFvPvEPFS2_PKvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Value8 obj:/lib/libc-2.11.1.so fun:_ZL21normalizeTypeInternalPKcS0_bb fun:_ZL21normalizeTypeInternalPKcS0_bb fun:_ZL14qNormalizeTypePcRiR10QByteArray fun:_ZN11QMetaObject14normalizedTypeEPKc fun:_ZN9QMetaType12registerTypeEPKcPFvPvEPFS2_PKvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Cond obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType12registerTypeEPKcPFvPvEPFS2_PKvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Value8 obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType12registerTypeEPKcPFvPvEPFS2_PKvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Value8 obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType12registerTypeEPKcPFvPvEPFS2_PKvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Addr8 obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType12registerTypeEPKcPFvPvEPFS2_PKvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Cond obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType12registerTypeEPKcPFvPvEPFS2_PKvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Addr8 obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType12registerTypeEPKcPFvPvEPFS2_PKvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Cond obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType12registerTypeEPKcPFvPvEPFS2_PKvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Value8 obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType12registerTypeEPKcPFvPvEPFS2_PKvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Value8 obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType12registerTypeEPKcPFvPvEPFS2_PKvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Cond obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType4typeEPKc fun:_ZN9QMetaType23registerStreamOperatorsEPKcPFvR11QDataStreamPKvEPFvS3_PvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Value8 obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType4typeEPKc fun:_ZN9QMetaType23registerStreamOperatorsEPKcPFvR11QDataStreamPKvEPFvS3_PvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Value8 obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType4typeEPKc fun:_ZN9QMetaType23registerStreamOperatorsEPKcPFvR11QDataStreamPKvEPFvS3_PvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Addr8 obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType4typeEPKc fun:_ZN9QMetaType23registerStreamOperatorsEPKcPFvR11QDataStreamPKvEPFvS3_PvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Cond obj:/lib/libc-2.11.1.so fun:_ZL22qMetaTypeType_unlockedRK10QByteArray fun:_ZN9QMetaType4typeEPKc fun:_ZN9QMetaType23registerStreamOperatorsEPKcPFvR11QDataStreamPKvEPFvS3_PvE obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 obj:/usr/lib/libphonon.so.4.4.0 } { Memcheck:Leak fun:calloc fun:_dlerror_run fun:dlopen@@GLIBC_2.2.5 obj:/usr/lib/nvidia-current/libGL.so.260.19.06 } { Memcheck:Leak fun:calloc fun:_dlerror_run fun:dlclose obj:/usr/lib/nvidia-current/libGL.so.260.19.06 obj:* obj:* obj:* } { Memcheck:Cond obj:/usr/lib/nvidia-current/libnvidia-glcore.so.260.19.06 obj:* obj:* obj:* obj:* obj:* obj:/dev/zero obj:/dev/nvidia0 obj:* obj:* obj:* obj:* } { Memcheck:Value8 obj:/usr/lib/nvidia-current/libnvidia-glcore.so.260.19.06 obj:* obj:* obj:* obj:* obj:* obj:/dev/zero obj:/dev/nvidia0 obj:* obj:* obj:* obj:* } { Memcheck:Cond obj:/usr/lib/nvidia-current/libnvidia-glcore.so.260.19.06 obj:* obj:* obj:* obj:* obj:* obj:/dev/zero obj:* obj:* obj:* obj:* obj:* } { Memcheck:Leak fun:malloc fun:g_malloc fun:g_strdup fun:g_get_language_names fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.7.0 obj:/usr/lib/libQtGui.so.4.7.0 fun:_ZN19QApplicationPrivate21createEventDispatcherEv fun:_ZN16QCoreApplication4initEv fun:_ZN16QCoreApplicationC2ER23QCoreApplicationPrivate fun:_ZN12QApplicationC1ERiPPci } { Memcheck:Leak fun:malloc obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 fun:doContent fun:contentProcessor fun:doProlog fun:prologProcessor fun:prologInitProcessor fun:XML_ParseBuffer } { Memcheck:Leak fun:memalign fun:posix_memalign obj:/lib/libglib-2.0.so.0.2600.0 fun:g_slice_alloc fun:g_array_sized_new fun:g_static_private_set fun:g_get_filename_charsets obj:/lib/libglib-2.0.so.0.2600.0 fun:g_thread_init_glib fun:_ZN27QEventDispatcherGlibPrivateC2EP13_GMainContext obj:/usr/lib/libQtGui.so.4.7.0 obj:/usr/lib/libQtGui.so.4.7.0 } { Memcheck:Leak fun:malloc obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 obj:/usr/lib/libfontconfig.so.1.4.4 fun:doContent fun:contentProcessor fun:doProlog fun:prologProcessor fun:prologInitProcessor fun:XML_ParseBuffer fun:FcConfigParseAndLoad fun:FcConfigParseAndLoad } GoFigure2-v0.9.0/CMake/ConfigDoxygen.cmake0000644000175000017500000000113511667757442020121 0ustar mathieumathieu#---------------------------------------------------------- # FIND DOXYGEN FIND_PACKAGE( Doxygen ) IF( DOXYGEN_FOUND ) IF( DOXYGEN_DOT_FOUND ) OPTION( LINK_EXTERNAL_DOC "Should the doc be linked with external sources (VTK, ITK...)?" OFF ) ADD_SUBDIRECTORY( Documentation ) ELSE( DOXYGEN_DOT_FOUND ) MESSAGE( STATUS "Warning: Dot (from GraphViz) not found - Documentation will not ce generated" ) ENDIF( DOXYGEN_DOT_FOUND ) ELSE( DOXYGEN_FOUND ) MESSAGE( STATUS "Warning: Doxygen not found - Documentation will not be created" ) ENDIF( DOXYGEN_FOUND ) GoFigure2-v0.9.0/CMake/FindSikuli.cmake0000644000175000017500000000333411667757442017422 0ustar mathieumathieu# - Find SIKULI IF( UNIX ) FIND_PROGRAM( SH_EXECUTABLE NAMES bash ) FIND_FILE( SIKULI_EXECUTABLE NAMES sikuli-ide.sh PATHS "$ENV{ProgramFiles}/Sikuli-IDE/" "$ENV{SystemDrive}/Sikuli-IDE/" "$ENV{HOME}/Sikuli-IDE/" "$ENV{HOME}/Sikuli-IDE/Sikuli-IDE" "/Applications/Sikuli-IDE.app" PATH_SUFFIXES "bin" DOC "Specify the path to sikuli" ) ELSE( UNIX ) # Windows FIND_PROGRAM( SIKULI_EXECUTABLE NAMES sikuli-ide.exe PATHS "$ENV{ProgramFiles}/Sikuli-IDE/" "$ENV{SystemDrive}/Sikuli-IDE/" PATH_SUFFIXES "bin" DOC "Specify the path to Sikuli" ) ENDIF( UNIX ) INCLUDE( FindPackageHandleStandardArgs ) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Sikuli DEFAULT_MSG Sikuli_EXECUTABLE) MARK_AS_ADVANCED( SIKULI_EXECUTABLE ) FUNCTION( add_sikuli_test testname sikuli_test ) SET( SIKULI_RUNNING_DIR ) # MESSAGE( "argv2: " ${ARGV2} ) SET( image_lib_dir ${ARGV2} ) IF( image_lib_dir ) EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/${image_lib_dir}/ ${CMAKE_CURRENT_BINARY_DIR}/${sikuli_test}/ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/${sikuli_test} ${CMAKE_CURRENT_BINARY_DIR}/${sikuli_test} ) SET( SIKULI_RUNNING_DIR ${CMAKE_CURRENT_BINARY_DIR} ) ELSE( image_lib_dir ) SET( SIKULI_RUNNING_DIR ${CMAKE_CURRENT_SOURCE_DIR} ) ENDIF( image_lib_dir ) IF( UNIX ) add_test( ${testname} ${SH_EXECUTABLE} ${SIKULI_EXECUTABLE} -t ${SIKULI_RUNNING_DIR}/${sikuli_test} ) ELSE( UNIX ) add_test( ${testname} ${SIKULI_EXECUTABLE} -t ${SIKULI_RUNNING_DIR}/${sikuli_test} ) ENDIF( UNIX ) ENDFUNCTION( add_sikuli_test ) GoFigure2-v0.9.0/CMake/CTestCustom.cmake.in0000644000175000017500000000471511667757442020207 0ustar mathieumathieu#SET( CTEST_CUSTOM_POST_TEST ${CTEST_CUSTOM_POST_TEST} # "${CMAKE_COMMAND} -E remove_directory # ${GOFIGURE2_BINARY_DIR}/Testing/earpax2isl11" #) SET(CTEST_CUSTOM_COVERAGE_EXCLUDE ${CTEST_CUSTOM_COVERAGE_EXCLUDE} # Exclude try_compile sources from coverage results: "/CMakeFiles/CMakeTmp/" # Exclude files generated by the moc pre-compiler ".*/moc_.*" # Exclude files generated by the uic pre-compiler ".*/ui_.*" # Exclude files from the Testing directories ".*/Testing/.*" # Exclude files from the Example directory "/Examples/.*" # Exclude files from Attic directories "${GOFIGURE2_SOURCE_DIR}/Code/Attic/*" "${GOFIGURE2_SOURCE_DIR}/Examples/Attic/*" ".*/CMakeExternals/.*" ) # The following tests should not be run under valgrind SET(CTEST_CUSTOM_MEMCHECK_IGNORE ) SET(CTEST_CUSTOM_ERROR_MATCH ${CTEST_CUSTOM_ERROR_MATCH} "CMake Error[ :]" ) SET(CTEST_CUSTOM_WARNING_MATCH ${CTEST_CUSTOM_WARNING_MATCH} "CMake Warning[ :]" ) SET(CTEST_CUSTOM_WARNING_EXCEPTION ${CTEST_CUSTOM_WARNING_EXCEPTION} # cmake suppressions # kwstyle suppressions # vtk suppressions # boost suppressions "index_matcher.hpp.*warning.*declaration of .* shadows a member of .this" "multi_index_container.hpp.*warning.*declaration of .* shadows a member of .this" "bucket_array.hpp.*warning.*declaration of .* shadows a member of .this" "hashed_index.hpp.*warning.*declaration of .* shadows a member of .this" "ordered_index.hpp.*warning.*declaration of .* shadows a member of .this" # qt suppressions from vtk... # Some VTK dashboards include building bits of Qt which produce lots of # the following warnings when built with the MS compilers. Qt guys should # fix their code. Until they do, keep the Qt chatter off the VTK dashboard # results: "include.[Qq]t([Cc]ore|[Gg]ui).*warning C4127: conditional expression is constant" "[Qq]t.*h.*warning.*declaration of .* shadows a member of .this" "[Qq]t.*h.*warning.*(copy constructor|assignment operator) could not be generated" # Suppress warning caused when QT 'foreach' loops are combined ".*warning: declaration of '_container_' shadows a previous local" # Suppressing warnings about duplicate libraries in Darwin # At some point this may be addressed by CMake feature request: # http://public.kitware.com/Bug/view.php?id=10179 "ld: warning: duplicate dylib.*" # Visual studio spurious warnings... "The following environment variables were not found" ) GoFigure2-v0.9.0/CMake/GoFigure2MacroEmptyExternalProject.cmake0000644000175000017500000000250611667757442024205 0ustar mathieumathieu########################################################################### # # Library: CTK # # Copyright (c) Kitware Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.commontk.org/LICENSE # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ########################################################################### # See http://github.com/commontk/CTK/blob/master/CMake/ctkMacroEmptyExternalProject.cmake # # Convenient macro allowing to define a "empty" project in case an external one is provided # using for example _DIR. # Doing so allows to keep the external project dependency system happy. # MACRO(GoFigure2MacroEmptyExternalProject proj dependencies) ExternalProject_Add(${proj} SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj} BINARY_DIR ${proj}-build DOWNLOAD_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" DEPENDS ${dependencies} ) ENDMACRO() GoFigure2-v0.9.0/ReadMe.rst0000644000175000017500000000240011667757442015257 0ustar mathieumathieu=========== GoFigure2 =========== 1. Introduction =============== The prime goal of **GoFigure2** is the automatic segmentation of nuclei and cell membranes and in temporally tracking them amidst cell division to create lineages. 2. Installation =============== 2.1. From Package ----------------- 2.2. From Sources ----------------- Please refer to * http://sourceforge.net/apps/trac/gofigure2/wiki/DeveloperSetUp * http://sourceforge.net/apps/trac/gofigure2/wiki/Compilation * http://sourceforge.net/apps/trac/gofigure2/wiki/VideoSupport 2.2.1. Prerequites ~~~~~~~~~~~~~~~~~~ User or developpers should first install the following libraries and softwares: * CMake (>=2.8.2) visit http://www.cmake.org * Qt (>=4.5) visit http://www.qtsoftware.com * MySQL (=5.1) visit http://www.mysql.com * FFMPEG (optional Linux or Mac) visit visit http://www.ffmpeg.org * VTK with Qt and MYSQL (>=5.6) visit http://www.vtk.org * ITK (>=3.20) visit http://www.itk.org * Boost (>=1.38) visit http://www.boost.org 2.2.2. Configuration ~~~~~~~~~~~~~~~~~~~~ * On Linux and Mac: Create a build directory (where **GoFigure2** will be compiled):: $ mkdir BUILD Launch cmake:: $ cd BUILD $ ccmake path/to/source/directory Build:: $ make -j8 Install:: # make install GoFigure2-v0.9.0/Scripts/0000755000175000017500000000000011667757442015023 5ustar mathieumathieuGoFigure2-v0.9.0/Resources/0000755000175000017500000000000011667757442015346 5ustar mathieumathieuGoFigure2-v0.9.0/Resources/fig/0000755000175000017500000000000011667757442016113 5ustar mathieumathieuGoFigure2-v0.9.0/Resources/fig/Angle.png0000755000175000017500000000147211667757442017656 0ustar mathieumathieu‰PNG  IHDR€Š(ÉgAMA± üatIMEÚ:Mn®vÞIDAT8O¥TÛNAf€PÁªÝ]ö8{^p匸তñDÚhµ!£½ð«j¼7>I½ò!¼ïÃôaì?D<á…“?“™?ó}óý‡êÈ;P,Í.½fžàÝÝ è¬î3~‹m¹®‹Ö‘êªXÁd —w½; Æè2Ý#æ¨mµ/†¤KoPT¬Êþ×}À—2à•˜âÇýÓ»f®·¹mÁø4ÿE³ÐüáÞ!‘`%,/íåÙü:³¾ÅnÙQœ“( jð½NΑ@ʱ²w,ÚºŒ^^Å®štS¢&B`¾â °ÍGò6mÅyìü–½]‹­MR1ÊߨRâF•­’í*»2¡Ïú˽È8ž´“뜴NDŽÀY öˆÂËx£°ÇÛ0¿.`îæº§ƒSXä¸dÎØ”ýXEv˜¶'øÝöîÙÚ 5Z»ù}‹Z­–Igà¢ÐŨŸdlaÍæãÁqÿ{_Vd4ƒÀ/³ò#„«ø<‘p4Kg¡ìô0êœj¤ 'ê<«ˆ‹Ó3znÙ5 7uÏ@½b¬ÀÂÑ]c5‡vÐôX ãñKsRg³ƒ1Í9%;³¬ëf½*U…ˆ0ìTÊ‚…Zxå™)¼² /4”‰Ëÿä/ÛËÁBPRKR1´ˆ²¨,)/ô…3íØìÆL£–¬å’9”BÀr°wÐÿÙ91Pƒ …kALŸ©@I”ŸÏ“Å0šq“ñ;Ÿwzí‘Ó.µIi ž£¹§éÔÍâ¬J´²H/šS¦Q4Ì–)dÿàþ5`8)\b%<â%¼€ ÀkQ–J©&oê›:ú†¸¾ ÌýQïÔ´x$Z“â¢ÈÃt^—uZÐ(,U^”¥¢$»²H‹„e>2,bD$IU¦ɺì%¦TOÔ½¸§P Oñ@ÿ1¾'.iQLGb?î‹ÿà;R²T¹§1ï±i"ææ¡•™lIEND®B`‚GoFigure2-v0.9.0/Resources/fig/2D_VIEWS_INFOS.png0000755000175000017500000000707711667757442021017 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA± üa AiCCPICC Profilex–wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû¥ò&" pHYs  :èݙޔIDAT8µUI(va=ß`žçYHfòIYˆ(eaMYÙ()6²aEØH)eÈWv2mÌ2%™‡Ì‘yÿßytïê¿ýõ{ëûnï}ßç¼ïsžsž«ûõ5ðè…Éó±¹¹‰øøx„……a~~'''pwwGBB,,,´Â¡×ZùøøÀññ1lmmÑØØ(€¸¹¹ÁÄÄêêêðöö¦® l4‘››‹œœçAŽŽŽÈÏÏGyy¹°»»ûïÀŒøüüDkk+ÒÒÒàïï‚+%! ïïïšÀ帾¾^(HIIÁãã#îïï1;;‹óós¡!88XX“cÞÖ××XZZ ÌÌLlllÀ`0 ªª 666šÀºŸ’›žœ)¼)Çó¶Ê»ççg<<<àõõUYþã“|ßÝÝI]¸ÁÈÀöövIõ;;;áìì,\]]ÑÝÝ oooÑíÑÑ „gê»´´mmm0™L‚N§Cbb"ÒÓÓa$O···b†èèh,//#++ +++Rõ˜˜‘˜ZZZ°ººŠõõulmma’qJJJ`ii)ª¿†••ÆÆÆðôôI€““pzz*ï™UA///ìììÈû¼¼< Ãl6ƒX¡¡¡ß‰‹‹ÃÙÙúúúD³tyæAB 0˜ÙqTT”R[[‹²²2ôôôˆ‚DÇÜHžÄ´­‡‡‡pÍཽ=ððŒŒ á›…„„€˜q£££b äädеªÜx;:‹Žâ“sƒüsÎôíííE Ôëõxyy‘Ûs¦¡’|||„cXfÿñO¨ Ym¦833ƒÔÔTÑîåå%¬­­1>>.7dš...’6 M«³…noocnnnnnˬÅÒL‰úeõ+++122"ªÄôô´È‹)2 ©©IöñÀ††Ό¹"5¥1©½‚œ‘+ÞbrrßEøâùúúWWW`‡‡‡(..–vJΙ)¹e?ñôôTû‡ LzY0???ùbô÷÷«Àt^`` :WJÁâ²G×ÔÔˆšØüùÕáPy*¤…Îcã ù.<<±±±N“ôöö ï\§ì ®±Epˆ*È ¹ä"{@RR¦¦¦¤=²8'MWW—< ¥µÒqkkkâ…ììl)ôo*»õ² ¹‰IEND®B`‚GoFigure2-v0.9.0/Resources/fig/LineageView.png0000644000175000017500000000252211667757442021021 0ustar mathieumathieu‰PNG  IHDRÄ´l;sRGB®ÎébKGDÿÿÿ ½§“ pHYsÄÄ•+tIMEÛ  ƒ‹Ï…iTXtCommentCreated with GIMPd.e©IDAT8Ë­•mLdÇϽWÞ®†É‹‚‚h@J\Ò!¾`¢2•ÖÔ5(m LZ«–½ÌVó¥È׿jêÔ³Üb.E  b¸ ܸ^áJDAE^Lä^¸÷ôá¶;ê—<Ûóé9çÿœÿyþçD„§uŽ0É{™§EDÐñÊ5J™© û›WO°µ;ʤ»«›øÙS0ÖXñu‚S‰+àÀ©zù`s‘ÔÛðô’bƒyÆ¡8^pEž<72€½ýhµâg†‘•™¬WÆm]}.Ç9“X¶4B”[¤ðO Ë–F¸ÖlÈ—À°±<ï§ÇT× À¾­Éd¥DÔž_ëäÎ};±þ#)©þ›ÀÐn5߯áp¢Óiˆ1„°&9Räæ™¤Ü| ƒ!˜Ú+^.1vÈñüZ¼8è÷Öbˆuýò›IΟ·7‘fÓu·O`hw¬ÌŽ úy[E]+¨Lò'ý­énºo®˜¦*ÌmRfj' l ¶þAfL "måËCKò(Ùlû±RŽžk’ÿ#=wƧJåp±‰ç"'PWƒÑㇱ0ÒÒÒ‚Ýn'&&†ðððÇÊQý^wKæüA—=Z!"*˜QÏxSe¾IÖ§óÀÀÀYYYb2™ÐéthµZl6AAA¤§§2ìµéç òRØ.[{˜=yS†9eggKCCƒÈÈHôz=V«•Ë—/ÓÝÝÍ‚ HHH—wþšˆ›Š$ccþ°º¾±j«ìÚ½Wz{{ÚÛÛ¥¹¹Ùíg6›%;;[JKK‡Äê::º€PÆS]{¼Sõ²ü?}DNC³øñÅÞ\kkÅ|É„Ã~ŸqAÁ2=no§­VQQQ9rDŒF£ÄÄÄ(MYÉ5R–OSv½Ž‚JËF¯­Hdnˆ—NçPPñÑKVsuòÇœ¼Á·Ù¹¬JY.gËË%55U566ÒÕÕµ€zË7…ƒ…Wdó¡ê!”**/JròRIÉX'ûÏu‹ˆðÙ±6™à„m¹!†w~Ä9qR\\,"ÂéÓ®é6¬óÞß|FìÛ¸D¤²I<úÚù|ë~,NüÔ]JórÁj£gÖ×xÙ{x7¸Šý{¾gýú DGG+‹Å"ša+*ÿ ¸'›VIKKÃ['œhÐðUN%' бœ?JÈhpˆ"6þV§¥±}ûvšššÄÏÏ7pÎáY»£LJj¯ã=Š¢*WíìÚ¦ Î]¤¿ÓÊô >g¢ŸOxb:}ð¬§ì;B½ž’ª/^ÌÎ;Ñh4®R䮕³—nâé9Ç „ÇScl#qþ’MVçÊÅ®ó¥¦?œêÛô z sôóÑŒA§x«žÞÞ…6›­$33“¸¸8WK;N”Òâí¥á»u®ùZe¹-ÇÊêI^4€9 óTkK³¨¶«ŒôBÃ_ @±!#Õ½{÷°Z­%­­­$%%a0PóEoœ¾^ìþr‘[¿?^‘]}lXûÄõd±X¤³³Æ§|||\n)’Â3ò4—ªˆð/ÜÔýûRÀ7IEND®B`‚GoFigure2-v0.9.0/Resources/fig/cube.png0000644000175000017500000000743411667757442017547 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA± üa AiCCPICC Profilex–wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû¥ò&" pHYsÄÄ•+qIDAT8ÅTYoU=w<×3c÷Øqb;1ŽK²@醵T}Bbi…„T$/ñ€xàT/<ð€š>!b‘"ITU•’B’R'±²8‹íf±“ØžñÌp'‹•&ªè â“fæÞùîwîÑùνÀÿÆoŸð£« o÷ý=ñŽ1ôý7>ä~ 6 £z©”– ¹ÒÇ¿ŽÍ<:~sÔBõp»ÜP8}ì\[³Òo½\“ ã¤…(‡qŽ'²Ù—3ù|p.›ý`:›‰Oü¹Š[×Y™°½L°‘jD°5‰cN<ÖTƒˆK¾ÚÝÔq=*Ò>"Љý *À-/Ÿ˜\\üìÎÒÒ‰d>OÒó˜ù]ÂZ2„æ' º%ÆØ^VF‚Èg¬#YÄ:ÎöÚª©GjkÚÃáË„M~‡‚¢¼òËèèÉÛ©l‚‹Eƒ(Z¡mD›[…Õ¹ e`agÝ4oPL~wêÊ0 Æ´ZC§ÛÚ_Í 7æàÙtúŠ›Ò÷9ÃÛÄ ¨~"Á5‚µD‹ÃÏ@sÜSŒm'œ1´½ÑÑkÀîqƒm˜ÝÚBbmm‡kØírÙ$Q_,€ßÞDÙíá¼MwáŠq(®ß„¡èLgþöan¢‡ƒ z@J_¦’¥ëÆƶ!à/»Ñ¡à”" ÙaÚÆÐup”‡Õfa–õ@ÍåÊ< §…š¸ÆÈ(¨÷zÐèóí`2í… $UUýPàßȱg:c¼fCÍÐõ2Ö⠨󕺡ñ ‰ÀZöBäȆsÏË•JV¨Ë‚P”«ªØÁÒa+–À$­„¦ª»s†oÑ)¬inIãG4L? Ó\)nMùíöŸÍ¢ŠæÄ!‚Ûë…¥Xdº²fœQóßŽÖæ“¹®+˜¶ü‡­‘­3Ù—ò<üNg…he°ÜûËug«.ŠÍ|†¦2pÌÓ»ÜM1ÊcÎëð¢ÑíspÓ4–÷:ðI’nâ˜qpC 8Y[{¾õõ‹3žX ßU˜†´6ˆÆ,GáÓ[À̵Ó4— ”ƒý›íÒ.ì!)ÌŸ]õõ3F±xöŠ•iöjϧdjJ¼¢Àî 3LòcÎäOpº>j¸áÍ·ºº®íä÷^»­>øgol¤Óò÷KK#ßöÇæï®B’lƒA¨å–r£8uì,Â6oÏ©HíGOÇãó‡!îiÞÁ$ Ø•lœQ ¹ðÃàà•T.ÇY5 µãâñKxª>üuÇÈÈ»$gÇóhÜ—ñÁ¥Ÿ÷ö¾6”J}SUWÇ?îó%_èè¸à™˜¸MZZŽ\ðëhüe_ßóËËï …èüW‹þ_\œwŠªšêIEND®B`‚GoFigure2-v0.9.0/Resources/fig/MeshEditing.png0000644000175000017500000000341211667757442021021 0ustar mathieumathieu‰PNG  IHDRÄ´l;sRGB®ÎébKGD66·® pHYs  šœtIMEÚ 2†.¾b"tEXtCommentCreated with GIMP on a Mac‡¨wC\IDAT8Ë•kL›÷ÆŸÿÿ}_Û€m|áâ`Œ¹Ø`.!$¥ÌKBCšDIÙXYÆ*­Ú¥]»Kµ“Ö­RÕF«ªMÚ¤¦K·I])k·UE¶®k—[»$ ln%lpŒÁÛ`l|{ßÿ¾„nšú¡?éHç9:zt>=¸ó2ì;xŒ€çŸûIÚ‹K,¯<úø™Ùlq<öÈ'vw­Ö: OµvÎvvQüª:º0wáÀáS_;¯Ñç}™r\¾\­FëñîDÀ³ Ø^ócÞyóݱ†žñEBãÍŽ“ÄXhfo½¼ë%œ«®üAÈÀ‹‘HWd,•yœÿ>Øs¦©ãä¤L­&õmGîø–îXa.×´ Vf#MŒ•5A©î]¼5¼àþ$`š¾ ãg³m«;÷¿ðÂÏÓÙRó¤Åç:ª¹1ð+>OŠ_¦wúsešÉá×^ê<ÐÞ‘Ù‰oóæ¢|h‹JYÍx™œ¦3•N£›’ÖêοùÊôÃî™ÇÝí?»¯óNRä&ÅÍŒ\èoã>å×™Ë ûGŸ7•V<³æõ´VÖÔ³‡¾ÔÍK¢„d2Ñ Y™Ÿd&K5d¼ÀtåV2³²ômOÕ)·9̺윌$*òqýW±0¦\Qý—Ýßú>Òà©øÂë« ”’ªÊJl'ÒÆ3Èßc‚ÉRCÖ¼žÌ•¡?I”ã$YNnëá†æÒ¦2ÅÕöiMn“4jN௿Hæþõ×ÕkÕ,¾…RƹýK ºÂ"’N¦°º•–BÑPB ¥‰kÀñOÁÆÚ]>+“dGªµ¤¹JE…KN’œÎ‘'%úká~}dÍ÷çՠã"Øj íÇ{ÉÄè‡ßË!ø½oÖ©¸4ÔÏô½œe(,äÒ›~¥¢\¹Õ su#²6Ü8ä(£àìúp&óvü­¾b ãq°Ž}7à€FmY½õ]ô³s§»Ùi Xœ‘²{»<>7å­7°÷”ÕÛÙnÐÀ)bøôáóšæï¸×uíŽxº]Qbn¡@.  ´ÿµþÇØÅZ/šZIEND®B`‚GoFigure2-v0.9.0/Resources/fig/PlaneSelection.png0000755000175000017500000000114211667757442021527 0ustar mathieumathieu‰PNG  IHDRKÖûlsRGB®Îé pHYsÃÃÇo¨dtIMEÚ 1/ÎD~ôIDAT8Ë•”½K#AÆŸÝÍj’Ã;8;¯¸C8T°½h•"J„”Vi³9Pãã¢(zKI)DÔÆn=É_°[yp—Q‹÷¡›ìNv,²gvb2ÕÌû>ï÷cf„üB®õy}€èÿßÅ]ù&öÖ¶u´.6[³hý<½Å€^¹Ë3òôì4™L6ö0ÿú$1»¹·b[žˆÐ—P4å"L¬§íZÍ4Í„——2>:‰DZ! @´-0v°¹»ë²|!„¨ªz}{ýlôFh³,A~[ÔÈÔÌ”ªªÏÇÀ§¡s[9(Í"„Fþîxæ“‹hÔBm*tv¹ÖÿJ!†Á‡?’,;Á îçxJ_‹k3™Y½¿»+—ËšºX®y2±ÂJ¥RÍЃ „ñe\!D.ŽÎ.ÞVzÞ"!¹ýœÈßÖ IŽmi!!'¹“b¥ r·è03µÊÚlç‹áÀGJþnÇ©¯"Ró©ªY}1üa€Í*Û;uIÒZ‡J"4òœ û÷È€¾euý\D,+ W߯<ß‹œ^c¿Þ¼ÕqÃ-$ó®:pÞå·)ÍvzµÜ™[úú¾úèߨÑ=³È·ñ͵Ì4€¡&ýØ™Å()2F¥IEND®B`‚GoFigure2-v0.9.0/Resources/fig/ObjectPicking.png0000644000175000017500000000244311667757442021337 0ustar mathieumathieu‰PNG  IHDRÄ´l;sRGB®ÎébKGD66·® pHYs  šœtIMEÚ 51”Ór˜£IDAT8Ë}”[lTEÇ3ç쥻ë–v[ º€m)—T{AJ¸ŒÁ@0!!b4j"Ä(>ÐI0Àñ#ÏÞB ! "jh4ÖFжµ ]Z\º´Ûn/çìî™ñaKK áÿ2ç;sæ7ÿïûfŽÐ 6ü°ž¾-}ܯ¤Âm(žõfè&–I¥\Îv{;{œ½¬ñÔ3Ì0.íÂ2-üÊ7íEhÐKd9ÕÉfóÇKøE_$%î°‰%ÝÊÃ. W)àT滽/ò¥õÕòI’$Èõåb “D:1ˆ¨NîÅ3QÓæfÆEÞ"âé8J+$@ÌLI^6Ѝ:\GDuòšê$¢:yºÞ!2ñ¼Õý µîrv²Š§Œ<áL‚3V† D)… °Ö±˜“y€  hklàóænVm¥üý~Âõ“N—‘wI ? È\r´C\ÜEkÎ:ŽZ:¹kë‘sT®›ößàÏ<‡æƒ~;#ž®áÆÁQÊt/Ž!”˜p\s`Ó4轘 ×'K|SïfÈ#ô㘠@‚Vš,øðQj=rŽš›øÖU]ˆµÀ"pÊÆT)–|<‡?òJÔ~(´æÀ¦IÇ3w°¼gj×ôN4O×’ÞÜĵ7·ñÆ7—ùcFÊ(ps#m~´Ð8†ƒ½È΂J^$ômŒ_3î.ñPÇÓ6hláÒð0/5Y{}Œó††L(Ík( vÉ|­ÊZ¢´ /©ÜsÔ÷~9@ àÕ3gø`ËN|f Q¤–¸qgk|[ÅèW,HÏeŽXÌsï<²‘퀂††>üõq'6qÜ@Œ ¬ ¹D–Ówö?`ZüóÉM†z†¨­ªeEÕ Ž?Îî]»éý±—[£·°¤…ÙK/Œ€¶¶1”ù·‰êUÔäU“ó¯1ÃÀø4ôh¤Ç‹¸“=뱿bDÿ‹âr¹ð=æc4g”Yã³È˜L{ÌÆ-Ü(­H‘ÂÐ8 “Ùæ¥Å® ˆ>cZy„T{«)«/# Ç1M“zêq 7²”R6‘J¢µÎÞ 4ˆìb‰D PB¡¤ L˜e,CZ’öÓí,ô.äìÙ³455Ñ£{5F‘I™äºë:Eá"Ü»Q^…ÇôñdˆæDéóöa{lf›³ žg“*N¡V(b`0x{ŽŽÖ­[GÒH¢<ŠÿbÄb!¡IEND®B`‚GoFigure2-v0.9.0/Resources/fig/C_M_L_Border.png0000644000175000017500000000664611667757442021043 0ustar mathieumathieu‰PNG  IHDRÄ´l; CiCCPICC ProfilexÚSwX“÷>ß÷eVBØð±—l"#¬ÈY¢’a„@Å…ˆ VœHUÄ‚Õ Hˆâ (¸gAŠˆZ‹U\8îܧµ}zïííû×û¼çœçüÎyÏ€&‘æ¢j9R…<:ØOHÄɽ€Hà æËÂgÅðyx~t°?ü¯opÕ.$ÇáÿƒºP&W ‘à"ç RÈ.TÈȰS³d ”ly|B"ª ìôI>Ø©“ÜØ¢©™(G$@»`UR,À ¬@".À®€Y¶2G€½vŽX@`€™B,Ì 8CÍ L 0Ò¿à©_p…¸HÀ˕͗KÒ3¸•Ðwòðàâ!âÂl±Ba)f ä"œ—›#HçLÎ ùÑÁþ8?çæäáæfçlïôÅ¢þkðo">!ñßþ¼ŒNÏïÚ_ååÖpǰu¿k©[ÚVhßù]3Û  Z Ðzù‹y8ü@ž¡PÈ< í%b¡½0ã‹>ÿ3áoà‹~öü@þÛzðqš@™­À£ƒýqanv®RŽçËB1n÷ç#þÇ…ýŽ)Ñâ4±\,ŠñX‰¸P"MÇy¹R‘D!É•âé2ñ–ý “w ¬†OÀN¶µËlÀ~î‹XÒv@~ó-Œ ‘g42y÷“¿ù@+Í—¤ã¼è\¨”LÆD *°A Á¬ÀœÁ¼ÀaD@ $À<Bä€ ¡–ATÀ:ص° šá´Á18 çà\ëp`žÂ¼† AÈa!:ˆbŽØ"ΙŽ"aH4’€¤ éˆQ"ÅÈr¤©Bj‘]H#ò-r9\@úÛÈ 2ŠüмG1”²QÔu@¹¨ŠÆ sÑt4]€–¢kÑ´=€¶¢§ÑKèut}ŠŽc€Ñ1fŒÙa\Œ‡E`‰X&ÇcåX5V5cX7vÀžaï$‹€ì^„Âl‚GXLXC¨%ì#´ºW ƒ„1Â'"“¨O´%zùÄxb:±XF¬&î!!ž%^'_“H$É’äN !%2I IkHÛH-¤S¤>ÒiœL&ëmÉÞä²€¬ —‘·O’ûÉÃä·:ňâL ¢$R¤”J5e?奟2B™ ªQÍ©žÔªˆ:ŸZIm vP/S‡©4uš%Í›Cˤ-£ÕКigi÷h/étº ݃E—ЗÒkèéçéƒôw † ƒÇHb(k{§·/™L¦Ó—™ÈT0×2™g˜˜oUX*ö*|‘Ê•:•V•~•çªTUsU?Õyª T«U«^V}¦FU³Pã© Ô«Õ©U»©6®ÎRwRPÏQ_£¾_ý‚úc ²†…F †H£Tc·Æ!Æ2eñXBÖrVë,k˜Mb[²ùìLvûv/{LSCsªf¬f‘fæqÍƱàð9ÙœJÎ!Î Î{--?-±Öj­f­~­7ÚzÚ¾ÚbírííëÚïup@,õ:m:÷u º6ºQº…ºÛuÏê>Ócëyé õÊõéÝÑGõmô£õêïÖïÑ7046l18cðÌcèk˜i¸Ñð„á¨Ëhº‘Äh£ÑI£'¸&î‡gã5x>f¬ob¬4ÞeÜkVyVõV׬IÖ\ë,ëmÖWlPW› ›:›Ë¶¨­›­Äv›mßâ)Ò)õSnÚ1ìüì ìšìí9öaö%ömöÏÌÖ;t;|rtuÌvlp¼ë¤á4éĩÃéWgg¡só5¦KË—v—Sm§Š§nŸzË•åîºÒµÓõ£›»›Ü­ÙmÔÝÌ=Å}«ûM.›É]Ã=ïAôð÷XâqÌã§›§Âóç/^v^Y^û½O³œ&žÖ0mÈÛÄ[à½Ë{`:>=eúÎé>Æ>ŸzŸ‡¾¦¾"ß=¾#~Ö~™~üžû;úËýø¿áyòñN`Áå½³k™¥5»/ >B Yr“oÀòùc3Üg,šÑÊZú0Ì&LÖކÏß~o¦ùLé̶ˆàGlˆ¸i™ù})*2ª.êQ´Stqt÷,Ö¬äYûg½Žñ©Œ¹;Ûj¶rvg¬jlRlc웸€¸ª¸x‡øEñ—t$ í‰äÄØÄ=‰ãsçlš3œäšT–tc®åÜ¢¹æéÎËžwç|þü/÷„óûÜÄ7„bKGDùC» pHYs  :èÝ™ÞtIMEÛ %q°‡5äIDAT8ËÝ•[HÓqÇÿ™mdËK³KÔ,KòE'–+©ÅÂ_ Ô.`DRÐc¢áSP=kK¥+-òB—™¦Ût›¸)“P[+‡—ÄM»{æÖfzë<óý߇ÃáüÎÿÚ ÄGšK '¢¦††µµ´Ÿ±V‹m êÜn2&•¢ð¯+ŸOGUÕ7¼{së¬;ÛÛñvap8µ¶®®uøˆŠ âF†6ÉÉ38’ïU7 füærƒ}Xiü*}\ ;fáØ8W"7–3´ÛàFíõj/R;³ÀÑqÒ~üBDÐâbDuw{ÄöK7½~RN0> 7|àÏóÁäoÐ1P:wýÆ¡*ÒÛÚðlnðÙ–ƒª´ä³Q­(Ђô~ý’¹ù)Îl ‹Á–É0o6ܲ¯ùÝ×$iÕŠ2¿æ„ðj5–…Bœ 8,“aÖéDˆ Yûz/Ʋ^HkBó†`«­/ÜÑA‹%ÚbiK´+ô ý  Ñ„È ¬uus®Tâ€BÉÀ6ÍB0 lj))€J"÷öÂ%‘ Û×é°o`Ÿ¿¯'©Š‚.¸à<¿VžÌÎúѸúûÑ Õ‚Ô’‰ dÈå˜Z4…J^øJ}¾ ŸÉ¦p{€áaxêëQvWdfR†D&)ÔO¸  \btO†ŽEmø±1dÕÁ$r%™¶ZÉùŠ êù¦Kè›2F³Ç‹ì+qKž™ôßÎýâí‡D%µkäJRÀãQ¯"xÓ„÷>öKnKŒ3á;¢ï6áSÉ]8{J#^›¤sOÞþ¼¹§ðRþÁwßdÚ8óz ÑB«ªôfèÈÖ¤„èpŒ-áDa™/ï-/¹(æ(©«Qަ&€Ë%•‰‰„ÈdİJ‘;ç²ìfâËë åý§ß£µzzð‘χ¿ñH²16ÿO`€PSSˆ4ÿ³ÀÝFöÄëIEND®B`‚GoFigure2-v0.9.0/Resources/fig/transferFunction.png0000644000175000017500000000066311667757442022160 0ustar mathieumathieu‰PNG  IHDRÄ´l;sRGB®ÎébKGD×ÿ×d¹k¬ pHYsÃÃÇo¨dtIMEÛ *©®ü3IDAT8Ë­”1nƒ0Fßš©k%:#‘¡½Ž½ö&íл´—i%RÉHÝ9@–dû;€âØŸ„Œ <=>lÄ©«*ªgÖˆˆd¬”ï/h¥;oQÉûù²¡™mîA@Ag{“ñÊÚ¢²BOó=´Ðà÷·ë9o[hw$Ábä úò@}«ª7g1h*Q¨œ?ØP(—W;ºµý_'h`;ëã¥*°j$ö–Ù­;,•|ì¢ JoSÄØŠ˜Ä³IãùôFÒ¢‡(bÕȘT\ÉöÉY5ñåÄb§UѨÛ9¨ïeÙ_/OÙÆò¨‚ÁLgtÓÛýºÞkSﵩçg¡i£n—²]\ÅÀ”ØŽزԹ8u‡AG`“~GÆs#¶‹’yÛµóXÀyÎU%÷¨IEND®B`‚GoFigure2-v0.9.0/Resources/fig/scalarbar.png0000755000175000017500000000031411667757442020554 0ustar mathieumathieu‰PNG  IHDR¯:psRGB®Îé pHYs  šœtIMEÙ ëg.Ë^IDAT(ϵÒ] À àYÞÿ ÚEAÄî Ö>BšÎ9v¯»£tïÒµJçœ(c Ǫ̂ª¢TDPÊÌ(-¥¤ÖZj]Ћ Zk(í½ÿÿ„)çŒR"éÿG9•SL÷IEND®B`‚GoFigure2-v0.9.0/Resources/fig/TableWidget.png0000755000175000017500000000471211667757442021023 0ustar mathieumathieu‰PNG  IHDRP3gAMA± üatIMEÚ#¬?Þ nIDAThCíZIoÇn9‹c#Aâ ±äƒÏ‚ø”Ÿ —œr0’ r HŽAŒä–À‰³X–,YrbS¢Ê”ˆ¢d'G%Sâ&.³ïCq–ž}ã ‡œ}át¾êG÷ôt÷ ‡T@Ó” BõW¯^Õ«÷ê½ªêæ¸/Ò1džï^²œ¶œ¹bê¶Bæ¿´§^´Ø2™Ô›šƒb$ê×NMx›"ïßÕ™-sV›ÔÙìFö8Œ§Éé¶±;L@ã9T9 3ØE2DЈø0Äé29]f"p‚›Ë,ò70Î2Üå¶ –غ=‰^Â].3ÂÁ4àl;ŽWଠ— c ®Å“‚ÆÖJFã\$âI% ‚€>¯)à·8ìÓÓS·?þèýü'ÈMÆx5ÆP~8}Çbžø­VËäÜì½ o#¼zÜs.çŒwÑdlìÚèfgFƒ¼}b\wûÖU€á°kvæîí[W¦&oáubüÆå¡É‰›Ävp°ú«W>ס<22tCwµáÓfúðâ©÷Gü>6}##—. öañøÂØØuƒ~Ì»ÈæÎlš°Z'ö‡Ñ[+9{&rBZ¤´(ðµÿ œ={ôø;>Ùwèý÷þ¤ÿÔaä§N½%Žã¿È‡†Î £áò?ýñ÷Èï]—øž>}B˜Mã·n“TwG?nCÿ‰÷þźs ‚¾÷ßF>|ùü?ße”†/ ?Ýù¥Ÿ!Ðnˆ¼¿ÿx_ßQB.žDXä}qç?ày[,âHÄ}ñDu…ü¯Ë¥ƒµêÁJ™=@Ê¥WËÅ•ÒAàù•ß©–såR¶XÈ,gã(ת+bÃ¥R1S­ä*¥år1+"éJy” ˯¦€D¹X`”¨Êfb(×k«Ä¡˜_ªWWñJ4(€ðR!³Ö(€f5—\]I¡ÇVU‘UUNì}Q/à#Þ&ð¹s6ÛL:µ {ø$êšÍ=kkœÏ÷ìÊ 'Œy.ÇU*¬ {,z½Õj Mêõz(Î "™P«Õx>Øh¬¡LˆÝnGNÄÏÀJµŠr (—Ë• ÞjSSÓ^¯Uõzcbbd…B4f³%‹Ng6›ÑZ¸Ý«6œ *½ÞÉdóù|³Ù¤1¯Õê(À`Ú¾ðá Ë5³ÙUÂŒ¶&pM&ÞºÀÍ&IË­­½ ŽŒ±C ‡ÃÔ õMS@Bª¢x¥Riuu•†!—––pŸÏGµk˜c‘¾X,¢ Ó2(ÁœpÈC¯‘H|P–ºÀÄ¡FÁDÞ5•õz›ÀwFoú}–ˆ¸²= l ï´°¤Ò†‘LѤMà{÷Fm6¶Ü—2 fÓÉ,,s¥š¨T2éJåKШá}@²Ù,Íͽ¤ ”ë\¡XÒ°œŒÊËËlá©qض&J²u2 ²; ó!æ¨`ÒÈÉ4c!ʹÄUÚæ VÑh|SÝ ŒPJ¦¨P§ÑkNÚ>{ä†^$óVšôì< ˜Ñ°y$ÆÜ@ô諱Ãû“Gö#Ú$ž~;?‹ŽFß …NhZ öH&ÉÐi.Ž”k˜‰*[Ãî?¼áyíu÷k¯#_øÝ¨}äûŽÇ³—‡ãû=JÒ#Ùv Œ5L&½©5¬^9;GÃ=­aRzïk8“ÉÈeîq §ÓÌGPQ¤ý&‚™¢ …:ò ›Xû<,én\§°‹ñ—…Wö%~þ­øþ‚¿øvìågÙn$—OK A|B)ÅãlûJHLÜ!!ÉÉh;Åó¼ZË‹,L€¢* jâ £ —H$M¨k‰U½Î¢W+ÍÏ3iÓ)6”Y—ù/¿&¼Ì ¿únîg_iüt=·ñìÑõH¶ÝNëØñc¼t4â§iøÉžø¹õçGÛ]÷ý¶L¶ÝŸdG­xÌÝŤÿ_“I«í¹ûãñ›´™ôàÅÁM™49}ÅÊÁaC Ãcß2:N(Ò§§¥õƒ‡TÛÉ{w™#òÒ·–ÇÞa&M‰ïr/­×ψkØŽÜ !ŸñÅù矟ۻ¹þ¹ç€„“IiÊ5=m(Ä"—Èü~æäªàŸºÝnµ†É#×ôÒtZT$êT]E½H± V«¶™´Á0‡w‡å”„§ŸÆ©¼oÒžÔê·L¶ÝNË`˜ÅX‰Û¼lšKÏpå=ÜÊ×¹â—9šœ]%p/&½«†I;]L½é¥Ä´“9­ÝoÒn×\w“Ζ[wHjoD§ÜZH¶J±=©‘œ®ÁÔ{UУ•¢Šö‰òM«"b)v¯¨¥®%Vuñb¤•>5i[gWŠH»<,‘ÓòzM™LÒæï´® Â<+_l¢ N €Èï´0©ê㡦ßîr§•L²=¬tã)©±Ë–f78JFZÉ»Æi 8r©J–˜À›žÝ–°†ƒAäL%Ã^?ÛKÿÐäüÑñÒ¼õ%½í{&—è~Û ŠË'Š7ò«LÚŸ(.7i¡>A¥D¯ÞxP¸B®^D`®ÙD±ñPž–ð€É41öÉ54v{Yþª(ß7øÀS0ËõcR࿆å#Ô0éhę˭.U+T­áϵÀë›2éV˜t§½qSo]ºã½7iÓ0Lï;Ĥ5¿¤všˆNÓgTÉo+¿’g†I3ßf?ZôbÒÒY§¡ô¹TiÔŒ1½"’IR)z$¶Z©f&M ïÝ–èNËh¸/›ýŒ@¥ª/ÑWè›ÑCÆÐ(‚4G£ñŒgþÏÿœ9ÆènŠÖ53ù ˜b+z3ÇKì¾Aýy¿ã“%^~JYŠàæ[SjÄDWv‡oý\Bg’ ÅSk)#¤2™ £}Ø ¡Ÿ &0õ<¯åïu*Ž˜W"..󦡘 ˜N§A=ð¼÷¯}',„0…—–j5·›Zyž—Ç.0byœÕ,£ÊU‰žD{£z•M-¦°ä¨Î™ö¦J5fFæ:†$Ë– ÿ~ßY.žUÄœÂÍÓ/­½ß¿~À¸-„Eæ3‡Ó"‰6Ó8 Mfe¢×iÝlERô´Nüog·Ý¶´:¯ŒrG7—ßó1=B¤p– ˆ^ŠI™DFb¥Mzsá¿’.}à”îeöœ O ¿_h´!h$ ÁÆ ¥‚Aüš£ZÁŠÒYµ FàýíÇ[»h/r…è ¨nÖ¡o¥³OÁñ»ã…À N˧÷—÷×»_ ¢õJ ÌN¥ë«ë»ow 7ÒÆÛþYÜ:8 ˆ»Öh™­p<ª²8þøF¢2áD±ÄT·”­Å7ÏÏÎGýèkjÍìý·®õúALâIuÒq:ošŠPPE(G»GäPƒÂÀiw+ÅÆ°òô¬öW"…0‡cT²(™î¡ëõÔlƒ™µù¡ù¡é´rùÁú­™ôL)K7!4Pä10EPðžçáyûŸs÷5Mt®Îv¶sß®sŸëºîûÀÿ\"ò@ÜÔÔ€ù_À*++ïµÖ“ŽÿuÃòe%G Šå|ëÅØ'®¯¯¿?´{<ÞÊ¢¢’55ö™¦y=77gOyyùR´ƒºº£aOÜÛÛ[°víko;VÿIuuõ§gÎ4¯jhhNëîîßÑÞI0ä½ÜÑñço-gOï««;üà} ""â.oq"²EDŽ®YS)qq‰2-v¦Þ¶íc¼% ee«O¤§gîòXÀöØê¦NÙöbù*Ñ …DD¤ªêõáE‹–´Î™3ÿs ˜ŒyŽñïDlì¤%¹9+V:ÀìÙӿܾý£Z ¸ü¤â&$$=,ÞÕ«ý¿ôô]¥§÷š ¹U•ˆÜ»÷óî””9’0[\.—X–%{÷|&£åRSÓ¥½ýÂè7.È.ªõ›DD¤³ó’,ÈÊ—üçWÊ߈ˆHw÷Yœ[$ùeÿä._‘¼Å%R¸ü%• €yóJ à#²ÈšŸAÞ³yìÛ·˲°, ›- §Ó‰Öß°@0€i8œv|>?íí.cT%ív;Q‘‘¦ÉÒeËÉÉYÈwßÖ2vÜ8 D@D£”…¥4Z…°, ¥,ì6<Ê"åØlv,K“••AtôDJV®À¸ó@-‚Ò‚Ö­–Rh­i×í¡éô©Ñ©ÈÌX$áácñ‚ÔÖä§#õ¸.tÐÒÜŠišˆÖ(­°”…²Bx½^Ü7^¥,.u_4FmiÃ4Á0‰‰™ÂµëýüÑ|ŽÌ̹¦‰¼°¢ @À`pÈß œÎ1Øà¾Y±nÝ:vïÞUª´& 2sæ Οk£¥¹•Ì̹¸‡Ü¤¤&ñò+«III& Þ£œr÷€l7n<ÙßßÿujJ2>¿Ÿøøgh9ÛÊÀ@?"ŸÏÏúõ¯òþ{5lÞ¼¯Ç‹Rþ€÷›Á¡!‚ÁÐpqqñ_¥¥¥„DdÏ„ OOÎÊÊàæ$%ÅÓÒ| 8yâomÙ@WW7ÇêÓÓÓCvv–²Ø¹s¿7Àåj¦°pÙ£[rëÖdAÖbik;/3¦'KZÚ|Ùôæñù†¥¨°\æ¦gKqq¹¸Ú\ÒÕÕ)ï¼ý®DOœ&Q‘“eRt¬À#Æf^ÞsÕ+ÊJ3m„”&))ǘp”¥¹í&.~‘‘<Áá~äÖà0É©)$&§1+1‰æ35£Ú-*j²ìßÿ­­mìÚµ§Ãa`6 C#Z°¬‚RzÄzJ¡Tˆþþ¾Ñ;ÏawpèÐ÷ܼy»-lDyà Ì0ÁD 0Óf¢µÆ0 L”d¤Ö‡*Ž™2¾k=w3„Î;ÔÝ¥OÝÙÀÇȯáttôþ3J¦³þ%tEXtcreate-date2009-11-15T17:03:05-07:00qÝé{%tEXtdate:create2010-01-11T09:25:31-07:00Þó*Û%tEXtdate:modify2010-01-11T09:25:31-07:00¯®’ggtEXtLicensehttp://creativecommons.org/licenses/by-sa/3.0/ or http://creativecommons.org/licenses/LGPL/2.1/["K7Rª/E1 ÁÚ@ÓP³³(КÀ2”lpa¼<Èeò ÿÙ¤ꔀ⠃™˜†_ÞÕµIEND®B`‚GoFigure2-v0.9.0/Resources/fig/LeftView.png0000755000175000017500000000553311667757442020357 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA± üa AiCCPICC Profilex–wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû¥ò&" pHYs  šœ°IDAT8c` 'øÏÀà Ä ÿõôlþÿg¤šÝ@C¯ñÿÿ::+$393áÐô*þ‡\ê&è±IEND®B`‚GoFigure2-v0.9.0/Resources/fig/yz.png0000755000175000017500000000071011667757442017264 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA± üatIMEØ "rnlIDATHKcŒ5eø¿ç:Ã÷ Œ ÔŠÂ@s$yþ?{öŒªX^„á?ƒÂ`††ÿ ³èÂ…çÿ{zŽ¡`!‡(‹ ÄcðÇþïÝ{Œ}}—-½yó iÃ\‹îjë–/¿ 6”ׂԣ¸—Á¤Š0˜аE§7mº – ¦¾“ MèÁŠ8tË@áMqä2—<ÁTÏà…[¶ü¯›=ûÿÍ;wÀ>è^²Œ1"[Pà3øÒõëÿÀ†¯Ú½ÌÞ|ð åƒ,…èZT¶æŠ‚fH\K ص° ¡8(`ƒ\ 29بâbšŒ-‚©âbô`€‡173¢Øl``ø¤d ÁXÃXÖƒ ‚ £aH¥AfIH€Ê,2˜XºÁ¼N­ P¬ 4]Qìt8²5Õ (vqa¼<Èeò ÿÙ¤ꔀ⠃¥ù'Ì‹|µIEND®B`‚GoFigure2-v0.9.0/Resources/fig/splash2.png0000644000175000017500000042122311667757442020201 0ustar mathieumathieu‰PNG  IHDRô°v sRGB®Îé pHYsÄÄ•+tIMEÚ-‚T< IDATxÚ¼¼ËŽ,Ë–-4æœfæî‘õÚ{íשSÔ½ºÐà@üBt®D“ +è@‡¿ EÖ•]$Ÿ:ºÔ¡j¿×Z™w7³9 \{Õ¹ç¨ØõÀ Efdf¸[š9æÃ\²àõ$ <œ àú" …NHÀ@Ð…HI…AŽ_ÿ,Àö)¥ä¶6òã§A$2·¿B~ò;¡òËO*®a„nç/Ü®‚¢_Ïîã!ÏWóÿýpV"é" Ã@ý÷ÿƒþŸþ‹ÿò?ûÿÕÿõüÞn¿ðU (ð†b°ZGša†Ö`ØÐ;¤#g)Êp͉$×Ña´!Rº€a€Þ‘‰|ÑìÑyD8zǘá+¼øòåí›ýCx<ÿ„~B_@ƒðgÁ“â¢X ]0ìA;¤A:P+B€=´@ $ @ 0H‚;˜`Â…eðUp¹·õ¿þÏÿã¸üôßý·ÿÍP¨¯+ˆÉtjÞwÀ„ôæå«ŸÎOßÕyÀP»@À‹,“Îð¨H+î{`°%-~ªóCG$ À-P€Ønد†õò®÷ Ћ¢ :q`fEù/þiÞìuou]:÷còʵ{Q|¹ß¿Iýq~úîéò7¬ MŒÑqï2)oÃÎýÛÒ« ÎYþútd.íâsçSðßúwÿþ_ü'ÿÞøU P`@0A€ò|z>y±=@Q¤‚¼·ãâÌÈ£2TU-ô².‡[¬!ŠÅÑjˆÀº"V˜ +@CZq×´0-Ò/KPÐ 4À€j° 1UU¯½VHAW<žq\00¸DˆˆT ${¬@17t€Àÿô¿þÿóÿò¿ýËÿá¿o­¯µ®Ý‹ém™‚¥–L‰Ê&¦yL»a¼9Œ òÓw}s;˜þðí_ÿù«·û#“åCJ;ˆvGíýx>¼žÂÏ‚£b6Ä›†¤’ ;±ƒÚ­–=e æCˆ ‹%B"®L.å‚0ˆU€Â$Ò! ÕÅWHÿdäŠS€äö¼.h)wpû~ú‡qUýSï<#_\ñïE®X(È`Ð1 µ®=ªIÊCCõêíú»$”ˆÒ=©3ñ Äum%'ù8Û’áè¾!°ˆŠB!"B@ï#¨üå$•ð­œp›¿ (n—«Ÿ`¹øëŠ¥†*I˜ƒª  (©ã8îv»Ýn'ûÝ4MglÚNÀ’˜¤p¸#&¢ª= –DÁˆîÑE˜‹ålÍ»*ܽ‚ÁÌ$ØÚš-Y’–KDŸ†dk-eÎ}Ê^&¥%Mymk_/’…š õ±~8==¶²àUÂxº¢)V+Ò¨·“¦„Å4rïA )P¨ˆ‚BBlT)" œ¤ˆ˜J!ယePÜP¤–Ãmt”$Ã00vã8ŽLè¦J "#¥ôtÛc†!ÆQ%6p+‡”Ô‹EйôQxˆ´“d’YRS¤OÖÜĈÔxƒ²ƒò®ŒƒÂg]_D£ “`ÑÜC,trÙõYÇ]ä„|ƒišl(V,™ò^ŸæU©Tß•¼ÛíFQ¼”$7áRÒ!>öÈÎÌpqdH9‹9k’o§Þ4Õî6XožÌ2Ã'“–%È" ‘‰IdM&Õ,–@éëDŠÄ LË R̦<ì{ÞOy(½…ˆšhë‹æZc&Ts‚è )—R©÷ÞÖîÕ£“&2yNÎ"aÆ1Ñ)AºÂ¢6ÖPÕRŠXHw¯N&פÙ,ömaÎsï•tŠœ @“€ •Km¹”‚ºôHƒº€  ¢¤T†4•!ç\†a"†d‡2Ôum^C*S.Ó~œ»?ûú«û»›¢òþ‹/vCao7»ý—·/çßÿp#ån_îv7še]ÛñR—ËÝÝ͹­u~ìµô儈’Ò04 2©NËjÙ2LÔ „ˆ@I ’D ˆP6¼nH,¢ š „ ba ùSXÿî  "è O©C@™ðÿÇ¡gòÌ×cƒØ ‡À2Ü*0Pè ®` ¥$EÕLRŽˆ¨d  *–MU£»»×Úgð& *@˜ÚV%D”>Ë'¨,"Wz!B…\ûÐ.[Gò7ø»þÊ‘ ‡à¹É^+”™åœË8à9©Ãr1ËÞ*€ P¨ª!Å ¨@T• L`¦Ñ#0Uª¦œ3‰¸ˆ#  •1§!•ÜAIæÒ©)í°{±{hïÂæ¸ yS^ÿöõðzês[~¨¿Ÿ0BM„A¹±’kõ„@…bªB "¨ DÐAAˆ‚ªÐ”Jgm+%Qô$Ò $µ±äioÍ»“ˆˆªXƒ"\‚ôB¦šaY¡átxD Y4%d¦b¹ä¢ªÑ›»+D]©U5Ñ$šA¥hˆ;ò‡ÛiÜï˜Ô…±‘)x‡¢”<ŽCm@!Û;*úǤ–p?)Dý ÍŠÐí<œ ǵè¶Öz8ÉáN ="œÜä) b“œ"ÂDɸ¶C ƒ©¤ˆðn †¸‡³µNšwzxDŽØ°HÇéP†±³¯ë½"÷ᇗiz•.À^vwÿ/î~s—î‹_zý˸¿{õóþ§Ó_>Äsõ¬=ËZ%²Hˆi`+­fkN»ÊtÆVi=œt!) w!Z ¤FÀÝ w§ £+]‰ˆM)iVÃù|:¯K wƒ™¢ª&Ö·QkîAmÊY DÍÝqÕûz­1˜3jóy™×º6‰u† "”p„ÑIŠ_f^`³ßÝ–\[¬ó•’P"¢µÖZ£;YvšŸTÍ˺öšS(½£•aÈ»aqÑèCÎlnI›htg¬.&d!%I¢p¶äa¦pë­fj‚ *0ÀˆJR[R,*LZœñ”D|TK ½SÄ!Nv_»*BÕ`ôÚŽí|>·V—yV°/ó® %§!åËÓ1G;÷çõCo³•WÃ§ˆ]ÎwÓþ3;¼ß•ŸŸìi»èÄ|·Îè—`Õjó8fÊ@Ä&‘,6@Õ@:ÍXB„CÁm2 ÍD„j4\!€<ÔlBñ/À’ÛóÆÕU@ë$™þe™¿Ä®|VŸvˆ>7,@P P´[Ï&a ÌD®´™)))tª„ÔT5Z@ J´ŠvïBÈ™î`@„ z Ï„GÇsÇ ¼RÈÌ]ÿwë'µLÿuÁœ¿qŸŸ¨ö=<"(*š u Ì9‡¸{0ªÞ‡C ‘ç~â:L*@J…ÐHßzÀ`â ±BVÐrJe°xæþËÛÏî¿÷Óÿ½¬Ëû VLš…»H’m‹Ð 3UU•d–¨J8HQª™áº–”“Z(W“¦)ÁÌÌ’ YˆDØ$›‰ Thj"’ÔT” QQËV<"ƒ7E%1Uµ¡Ô^¥KR-$1QÍÌ̺wE$%C2óf*&j$•l4 gL¦Û]Ù •ш¢ÙíÆRÎÕÝEFqÙZH3 #d‚ß#+Suo-œ×ðÜ9QÏŽ˜UÆd·»ÝÛ»Ûo¤ì;¬Þ[ï­y´ ØÀ. ’¢L„Î> F…©„ ‘`Sžµ£HÓ(*Ó!c^W>]ÎbÙˆ¶Ôå²z‹EªêÙÝ5YÕf ²öµ¶åâµÂ‡–) $C¯n Éæáð.†2Œ6”c=S"½{3"˵»'·VN·–M»oÀØ3£ :Œ¦Â”ÄlÊ©˜•&¢L÷PµdÉÚá½×¶›&3kkuâtžÃÛ4M½wéó$˜¨åb±²ikržïò âÓ†4ì¦Ý!üRJ‡žMªÇÅ}övaŸ½ÍÞ–ðVi’ uÔ´"ªX“C[¢dA fa jødɈ´édD£”dÉ  \åõØÄS~•×e“e(WƼaÈ?sÿ[4w(  º1w€€t*!€(GâÚ#|Ú@;à°â¨ µ@Ö­hm­†U”¬QD€€*Ê`"²,Þ*ÖÚ®æ* ²=6)@ƒÜD’'¼’âoJ]ÜÌUµÍü”gÛõlþu¢û³Ó«@˜b=ࢲi ÉÒP†i\IZFA3 [³¤š’‰„|ü ÓÕfAôÆpdµÑ{_AQMD8 Š(¸ÈRÆâšk´¥žZ‡Ã"oÃWc¼Æ)/?×÷‹·—ÂaXšF±b½¹ÁDU@ 10p½êköH¤T›Ÿj«çãP×ã¼pÌaEa dM ‚ÎZëéäÓ °TÝç”ê‚N„tà •Uj3…­!9RGjÏ®R4¶Ë<7OÐ’RJ]šv¤ŒiHE1næY¥Ç5û!â¡\ÑC»ª‚d†(’ò.?¬…#o¥E›LŒ=fY!³%êÚÚ0DëçóL±Ë|º¹ÛU34_×QGê0î’YmmóºH0eˆpW÷›žÖUK'Õ‰’£êSo]" +¹ŒU‚dÍb±ƒÞˆuj„h@¯R!“ )B£I4 RF„NQ:CßЉ½‹·×ÀIýžÙ à Üÿ”æ~}sk(×è£DJj" „4(ÉxóåøæóÏj]~øùÇÚðæ³›/¿üòÇDZ S™ÅÒ~·Û•wï¿§…)¥ÃáFU¿ýëï/Ë;•(»]~ñz(e”¼®-,"àŽÞÑ;¼¡;H˜å&Y)P€PùšÌ3¯gÂ+m\%zlßÿ5Èeú„8(膈Pè ÔðÀªœ›Ún¡šÝû³(·ð ¤o:ž™E¤®*ª¥ä&Lá–écRäA†±@ ËšŠöA°K‡·/÷¯ï.^çÓ²»9äaZì)Ýç÷O$êá~Ü}>^¾}DŸ[¨rJt†F€î@ 4ä*©ªÈ&ºB@U°ióYdëDT,‡+˜DL4‰Ùvñ"L&’!2d²E÷Ê6wV÷àÕMV‘d¹äÒæËÆe2X-'5˜vÐD$«)a"–s63B‚ôy0ªSÓÖ‹P XȈAZ$M¦û’u\çNrmFÁn?îÆat\ Iae|:-5à€fVRš„;e[«B;d¥#Y.)Ü—õ’rrÔ<%ÇꉕíØf/» èdoÑ›w’&Ðc˜tH:’@Ã-©1T”v‚ ©çÖus‰XÎëZûBž[ÌKU­ÒÉ1ÐQ+" €&›;ŽTH¤˜†I£hI’ƒŽý€ôí· Ž8Õ¹µy|9¤!YÒÞ°)êÄ rS¬²ö5Ø6l15BÑ3ZGFfˆ is)iÈiÊét£IÍb+i¦"„ƒâµWoÃTzïµÖpŠh†›»;ËéérL·7Ó8%ÉlýLýù4?-ë_¼~²‚¡ˆ%ÖeY:–ËTöbŠlšÕ’•l<ô\æSU™5¸’Í{—X‰ÓS•„hÕÔa VÉ]àn È*j n\<4˜4©o¾_rã–=2$* z±Ä6ê2ýZùåã·Ÿ™¥|”qxMõ\%š+ÄÉ4›yge¿×…A¨¢³¢#íñúóÝÍ¡„6›øÛòÍ«7¯/—Óç—[3iáçóû»·¥µuî =Ê0ìon©çßÿð¯vûRëZRÞÝÞ—‘ËrÞÝÉ?ùg_¾{÷áûoEüÒðÃûó·ß®þ›Ã´êË—¯"Pçåtº\΋;àBʺDJå|¬Ë )±e_€?û§ÛäP´îŒgZ¤ïüµ²ûs"ôY)‚Qʆ1çA5¹Ó;¡ ´zx."š5Zto"¢¦›ÃÁؤuH …o™¤K×Þ=\¨0¢G‚<$°.ç÷’‡aœ›ûz–Wåæë7‘ðt™å$òÓϧÈÌ»{„`š™[%íƒà&>ÔÖCÂLUE¤ A€PUI€naÇ”2‰Þ£Õ QqwÕm³º»¯ 2Úe^Ë8œšGë½[Ω¨±õ讪+ÛÓ¹÷¢bª=¶æÊL#b©+HzÀQ„ðîJLÓ8Mï>|è L…D0«Yã0ÔÖæÚ.½º"Db‚ Òš+}(¥tGɸ{QÆÛaéËãÃñÉçÖšGŒ#zÅt‹›Ã(äå|ism3–Ë"¦B–¬*¬Ý]TamYµì©òþrT$Ôùt»?¼yóæé|¹´µÒ=%WYП–ÓÏ s9[†¥ôôÔoîóñèªP U¼Ücº)šÓ0¤»ý> ôréËÜz0P=¢Vq„ÞìVG}:¯l-éÚ£-î®P…>o7IYE‹GàÈðºœ-ãö³Û4Ž>|8¹¿¸¿[Ú M¯?s9==üøôâ®Ìs5À’`¿ÓÖcmЂãº×A+p9zëï_ݽȥtiÆîLŽF’ItÊÃ Ž—yx9î¦ÃB\NËåxöõðu>+ûaÐ"Ö@g˜¥AFz¶²È("hnª¯^¼ ÙšÊû‡'™ÆÛe/ëD*å(¡Ä•ï/óà|y³ûü˯¦2üþ/ÿÕ¿¼yy×Ý M ìD,¥C²9?ÔõØ×šåí¸pf˜±ÀÒäªq6Û‰z¤µœ,H„ `²¥Ÿù¸ü‚´W2­ru n¼DÈ?š,³}öGÐßM¥ÖºÖ€i.cVUgŸçKÃ^¦CzóÙíW_¿½½#ÕÛÏFæ>/ïÏqÔ½nn α.Í/ëa8ôµ?~øpúé݆ÝnzÿøÝ{ûùï~÷»ÓE¡+ì»×åõííÝnLÑšÌïÚºúZƒAHx°U¦ÞkpU®l=دÂ694ÓzwV5ªIÄ#H)Ñ;½Y Mœv½Õ9Ù±r^Ö¸œøNc?´Þnovû×fwžÇE±»ÉÓ~zzzz:Ç Øß‰vžÏxü«o_hÞ«oj„%ICòÉã¼N˜cIL•vF•ÝP¥7tU f7)o].(+ù$TU'•¢º¹7*Ü¢*²µlYÕ¯¶™º%å‚ÞM¤Bf£9½k}ùöû!åó¼^u9ßdMìBX¨ê H¢‡q7c8õõiÇK¯OK혥öÖè~4“³b…gå¹³tPKts "dl„ø*;bëEH…C6±BޜɿCZæS¢ÿ)ë&°ò_®KÝÜUˆõÖ[k€àÅgc碙o>ßÿ³ó·_ýæóÖÖ>ü?—SÅ9È2•Ûûýáf"9ìe½¬Oíåí͇wrlCIÑ×<Ž7éàÕYOõ±?-§Óér¹¨êë7/#¢d«ÁÀ«/n¦‹}ûþ§Ãëòòþ°,«ío¿°ÏvÃÁ,Göœ­W¾Üß¼Ö|:^¾ÿþi=byÞX« fPôµýdûR|yù5¢;?Jí°I¡»»÷Þ¯‘ª¨)ÏÝʤ °‡ƒîá"ªºÅÃ…æÁB“…ìÞ+è"©&APl+O„^-ˆ€o 3íÍ+¹bÝÝþðÙ½ójçÖ›/¡,I,–´b/wùpw¸íÇt|5­ß÷Þ*† óêL¨˜fQ †\U:£ ¸%k¶™²yoˆl¦‘€pЯgÈ­5ôFòP4å¹×¹6WøV( šEEÕÓ5WLÕC€l¶ÇÈvjke8THJ§€šsJéÙ£"ªÐaB²Jl{Ÿd«BÉ0í0Žå)êÜØF øÒª÷0Án‡»›ý˜sœêr<÷ÚÄ%‚Í£L'œ×B7ä1—‚ *pbKC%|wá}]}V¯ òÝ«—_þfxùÕx¼ÿü€Ë|nò7_¿5~üîço÷]WWêP¦é¤•ÇãÈ刾nÙ#PÑ£3:Ã.°ˆ˜ ®ôÐ_î”M#ÿーõ@ðˆRÔÏCM Ûöª¢I5"tHÜ’A"|»$eˆÄ!zMPf•P*,+S  $‰.á }EÑñ~ò,={KDÞBåÐ »SW¤N¥å®L¯ëÍ+ò@ ÝŒÍp‡Èßèl¨¼ºÓEÄ6.¿±‚«€pxDO(¡ÜnA¡*¢ArÎbV×zq†¡“J(%‰dQ@}»ËIQ%(bã8Îô¹­]SˆBœ*’-•ap†3VDCtDqª„I4‹¤#†„Ã^mPg_{íúÜš4dÅX†]ŠØy^—ÓrÅ2£Aº ÃÑ·Z5`´œ†¡ ãêKÛ’m¤ëyn˺™,Ð$w/ïóg_|ý۱㰶þðôÞÛðù›rÿæt~º=\(™nç5|¥ø8íêª-¢¶%S•ö±%rݲ§(ª¢TÂ5"%-YÔ4T`î±@^su“°¡,—󬹉êen:DhÑA†HÁ§Þîïo—ÚÏgUŒûm·ž/U¢ ùé²<õy’4C>°>ÎïŽm—’eK›."ú\×EðâfË‘9ÑUò0,íñtA¯‹ `Iº%¬£ ¨DjPQªˆ‰vˆ (¢ 4zDjˆè”a[ZKÐSÊ´ –"I¿„¬ÁPÀ¤¬ABY—Zä2”4‘·9gÉ-éͤ=Æsòw͆°Äö(þ ½Õ›öº…˜ÂA&[`œ€P?y?îøçuÉpÛ”yCþjpWÕ?*>lô\žðÇ/ÇA oÝIhÂË|ýÍ«·ß¼•ä-ÖÇã·–PÆœÄN§~xüü7¯ØYçÞ×ó²^æe1Ëûi·.íÃuNï,³BÝ‚òö‹—ã~p÷ÞµµŠª¨®­æœ­;™0íG(˘»´oþ·’lžç|ƒ¤<õmæÃòÁöéæp'’–Ëz:žNþ0¾ÔW_ÜßÍÇÇùø€ÞÑзІ_òûW§Õ}¥$@yv2䣥t¸‡WgHW¿Ô%zÛø~åJo"ÌYÛ\!¶õš0|{pÝ^€S5 -D`PhÎ9 ‘K¶2¸ë`ÒÕj É÷Ó¬uÎ=&Ñ)§œLµ­õ„a… öeñ2•2½Ø=ÜÈGDw¡š¨ZÚð $‰¨[J湌móJ~™YÔ­-òÚÎDUÝòˆ!±•7UŠ%KÙU–ˆ „ÊvÓƒ Ü-®ûÔ61g»ãE&JÊI-¼/½¹ ÛXŠŠnñöêÞÑ„~Mû!6ûŠ”íï30&ì÷»œM˜Y¤+jrJJ*âµùJ®ˆŠîU‡Ä&/=à"€®ç‹&»†)a†–6·Éò4öK–^¹, Õ󼊩$[[—4Û˜)z™½9Ñ{x½½½ FËšRò)·Ì*!ëŠÞµƒF@šS§œs[ïÕûÚÚÓêrƒaÆñ2 BsvÕä¾y¼‘(*ÈŒ" åJÏm›€ýêGdJjq…‰4""` ›9´‰˜.Ñ+˜ÔNuT¬$±ÔjkNvÐ.Jd%!kh ÐÃXß/—©¥ÃPr×8Î&q/†,{KC‘òí=ÛèýèíR[oQ#žúÚWI«•½ê´¥žåö-À'Ü¢ãÅö¡mç•¿ÿÀý_×^þ€l^ƒ†×wEUçÅ)8Üàöe9Ü»[ ?¼ÿ) š†Ô»?=¬$-¥ûû›õR«·#.¥”T¬ÈD—åØà”†ÞñõÛ¯ÑùáÝC±ñæv÷—ßþÕË·¯o»ýÍ ¹åííí´ØûÏï~|ûÕ&úýßVúx3ݾ¸“w­çõ˜ÇüÛϾ®µýðÃO¾òÅ7Nï¨ìiÂÝ븿»yéŸÛß=üôýO§Ç¾ÌèªPbÛæ´ÝL)¿2éþ‰£úÌåŸ7qÐÝѺ÷ŽF(F­`Û¶ªtQXÒf!&ª±¨Õ<ÌwŸ!"&ThbJè½UHˆ„¨XV%#R*6x Ñ L0¥|S|/>Á'ǚѣ¯­_^{e°<ÜMÓ‹›y¿ A…Š8D$HE?Í–êócc'¶©À nsÉD}#+*nÐí~K€Ãš!¥‚t‘.p 1H‚šª$;b“Ë…(–SJ±´Z=˜%îÁˆ²eq’µ÷Nw*¡ À¯óm—X@©BS ûÝ8÷Kd§JßRwÀ¶ãê0íŒhkõÖ¥ÃÑq½÷‚ 7qŸ×ø:‚ÞºLUˆ-** gëâa„Š(éÑ1X:ÿü­Ç9Oöæ`ÓáðWß½ë˜óÎjkM"*ìÊHê=P—ž’—èˆ5”×@ªª$+³I6•@Ð…,ÃÈem^ :µ6?-u©H—-ÖÜp¹Ôµ…€‡éña–¼ÊÎL c1³þû‡ý®äÃ.åT3Žk=£—\Úé|_‡Ã^×~þñýòä{ŋ۱ε4z…»au6b—E:vã>§!\¦2´Ö²*I-™šB…ÉDRz3nB ‹-—+ÛFt³MÈtÒéjWJLŽè¨l§ËñÒ£¨Ž¹ôµF÷±¬+E¶8K%:8@û]¿,® kC­䜇ìTÔ0ظ‹²kõIÒ‡Š‹D÷VÙÀ*~N¼}é(ôër€èö#¹ª3ôC`‰"ð­ýMd—Omþ‰®µ™áîEùê›×÷¯¡sõãñ|úò«WŽïŽçG1Lû)•¼®õt:ÝÞÞg&wPw!y>žO§µ$´¬sõEúâËS¿yõòýO¹ìŽç¥µnfîýÝû§îáÓnxõF¬XP‚\ÖöðôøóãûSÿ ‰¯_½JC¨Ê°OñÔÿ_ÖÞìYÒãÈò;îß’™w«ÈÞHÚ¨m¤ÿÿ]f2™ÉFšn±Õ .`Ôr·\¾%"Ü]‘·Jl΀ÓõPVO×nå_øñs~çq¾[NKŠýÍÍó‹°Õj]ìKÀvÕ¯w—¾žôáîxÚT039Ãü#nŒ©?ryJç)ç‡ù'§ó“ò E K” 1U­2 $9DÈD`FPx2÷¹Ô5ST+ ªð NèÈGαf?¡®™%°¦P˜Ý"$ĨÁNVI¹“nÛÏÛ“ÃIÝXIÍܕɸ]Û?úFÿäZðý*ž˜™Y‡äŠÔìéXo®$31³ªf³vó­n,ÌFÁ%âïo!DM-ìB‘\ËZ²ƒÃݬ4ƒ„³ ¯j pÁÉÍÝI€ªˆ #÷}zX÷6º„ÎÉT•!H¡ëººV=ä2eË(+X!`"08Å[Ξ€8: }L–fl¦j«E5¯ð`L,‘%ÏSA·¢„m=ôó¤ªÛCqq¸ÔI‚T÷².ÉÁl TáíšÌ0 xu˦ ¹±v ªWõªÕtU?Í˼¢ÔëZPj „¼*ˆxÍG:Œ’¥ W˜¶£=òrZëÚ÷aØ £F¶*aûýÝñ~Þo‚\ãt¾ŸÞ|»<»”ªn^—’‹+Å@1E_úËqéB²êdž8.Kº>`bf&sre'fˆp$«(p&wÄÆ{œ8 QŒ'"’RqÎfjí±k„Rr ‘Õl­\+Üã,NlP'¬ìU¸°-T8múbµVÍ9Õ|Š+܉IÒ{qª_VÚY|4ßÃòEì$~ü$Ê›b¸áŒÎßq í¬ÇG2yC²0‚ã¯rËØ“Ag“®Ÿ‡h(<8‘¹©µ9A,öØ\àÓŸl?ûb;\ k5–n¼7Ý%½ªšÞŸïfalú‹Ãý$)²ójk¡ïû‹íÕ¶«o¾¾ýâï>}÷îÃrZ…Â'/?ýô“Ï~û¿ý¯¯þþ³»éAs¹ºbê×ùý0ï¦×ø&tbV‡~÷áÃÛwû‡ÃܼH§ƒNÇ·'„µ–ßÿñfæÒ¶‘LËZg·ÃÛ»÷+—ñZúxa'[YçlQàæp¨»89“0Qý‘Ú ÿ .ü”ve€„càYDR ‘(¥®“˜:¡eZމR ÄÕ­:ª¸¹´Ä¬5îÃÜC┢ˆ4°šknŽjh)ŠªfÕmY'gË\‹#0zYA¦ÀUg,{Ì+úXÇÀ‘˜‚Yí8Ä$&X¨†&G/Šê¬Ž¢0s''an~°Ÿ_¦ã|z¤˜atÞ£±ƒhˆ½÷°XÅ9tì¸"$&¢ªž­Ú[(tÉ#!1±’Á‰¨acE„™­‹ÕJH)¡V!öÈ„%1ª•Â02%8“ùÁ/0ª±AàA„Vƒ‰7=E§¢)…‘ÓÈiôX§²ì×r¬eÁº‚à ÂD@Œ4paÞ[Þ¨Át0fÂNø²·ÉÈóT€ZAq7]sÎkÑ«q êoïî+u)Žüñx’®ƒp®u͵†4Rê´ø¿|±Û>»Þ¥à›/ÿíõq¯F —’•½Åp `#ûï?Ù¿©>¡ˆáªN$9—(!Ï‹¤Xæ æÃ™’Aº^$‰ùZ”Ôw”Ë2ͳåÜt %ä ê^‡%&w×fýQ5£”F…®¹‚É8Ne¥è^ª-ý(7s•Z8m’£ Ͳǩ©ß\ow;ï]Þ<Ýïku®\$ÀÆÈà‚Ó©de'ÜÍžaì±óy&!ÂÇÖÒU,dqwUsɪºk1-Z²–ÅÝÌ»Ê#Sï:XH†U˜‘E!!ÐH ¦E뺈Yd浪›aä ˺dƒ–Ã)J Õ-¤0˜öË´h΄ 6:ƒg òbDÆ€nÕäxö< ×ÃÛåq¿¥ƒ«Á Ѳ,¬6ôýÎÓ®vë©.äÒâ&PݪJ,©ÖÎm']„°í¶î|¯KÏ!“lŸ^Ž×¦i2‰›g/vóáÀ%¨2¨–eÑex~óþôþzÜ<ÿÉÏnï$¤í0L§uÛoˬو…”N{Uuwa63ƒGÁfÄáÕtò ØvÜÅþp˜>¬ÛJêºûi^õRêZP ÕᎲ M­Ö2¤7Ž)ƒSâêåþnq‚04ãtÔ…ØuLÂkšû«4F^×¥‹|8œ¬K»‹í›¯¿=ÜÚO®{Ëkx] Š}ì8d×Rª7 ;„š ÂTêRP ºª&dJÆ]Hƒ8Q.䄳;ªU8B(ð¹VQëˆP×1ˆ Ø8Ä„.ÞÏG=­IºÓ2ã¸ß«Y7ûy¹Ú]Ìu/ÔÙºä:͹–Ý˜Ì Ä¹æ`Ú·…—rpï£q99ty Dîļ WKu«[u@#—.ÈeˆTZب‹ã,ä¥îWŸ n&‘¢Ðy³ãº 1”j @b Ìfjf}ß7ü_ssÿS•ÝÎn kîÂRZ5# Ûâù'é³/¶¯>ï6;WÌÏãåËqs®Ÿ]••Ë:l7—Ót>Ä.ß¿ÃÝdµXYKÍ8ïß~ ¢Rj”Ô÷ÝØõ———Ì|:œÐ ])µ®kYë'7/ûù¯¿yûÍü«xÙqüða½¾î¯Çø³—ŸèñðÇåPYKæýž?ßõ±?Ü—¼ŒÛ1lÓ2ëæâ’ˆj­uÊë¦ï)IÆ\y.ÓËŸ¦Û‹®p Χä&¡w,€B @ã‘H®E~Œ]Æâ?|Iélýnû|´°š»U­UÕ‰hÂZuK0Ö¢k©Kµ£˜;!ŽdDä !‚¤¨Õ‹)æ¹”êŠu)X CÄÔü;w¸¯Ðjŵ :a'ÎB­ëZ˜Vé(%I¥«iˆõôXKž™s²Êµ¨¢"è J±zprãÙ´ٰÄDÍuÖh¾LdöÑÀîd ¨ªYÕðÙU$Æb6@E‡X›¢ÝáNT'²¦ë1næî€(„‹éj5“)<°ЙdC@µ«ÞD66‡5«¹»Â.n‘1Dt‘9‰&ÄËQ6ð.º×sÇŒjñ¥Ø>ë±Úì^`@%Q"fA3Q¡0ø)Ï!\‹tFHUÙL³–…¨ÅÕJe]7Ï[Ò©”:/¹h„úR–Ó"¢æÙ›ÄüÄ}·ÐËÈqk²’ÕØiGžBŒ†4ä~ÇŠàÔM¹f¥R(«›¢ª¢Ú¥íU÷óÁ2ª€»*ÎQ'sòˆ„2|qËÊ0!ŒÛî¸?×¼©óx³Ûìt×ïî¾ùܪ››ˆ‚0(„!Têc!ÌU§Šl\ÍP¥zÉš‹Jµ–y‚„Þ\µ²“º˜B ;)qˆjÞ"¹Ö`ˆNCHÕÁÒU”©˜tãÜÂÄX——‚Q¶Èòàž@Ú¹§ÀB.̉D@VÍá¥qN(:©¢¶ð“GAuM  ±Š0ÉBB†l’aîLÄ™‚P'A£[rM'V¦ö³vŽÜàÇîdtθۓç£xjjKÑ Œíž½Š?ùüægsóê‹! ¥z¾¼‰ãU ½î¶>F«Ûë‹›y–€|³Ûüчw«‰H?N‡ý±]kUušVæð¬ë—Ó|{û°Ý\춦¼1~¸¿Ÿ§éøø0fÄënØüâç//..º~øû_ýò´¬¹Ø·ï?Ló¼t7Œcº`°•“g À3ôø¸H¤‹›mJiš÷›¸‰ˆï¾½ÏË.bÁŒ§Y+y"Wln6s=N'¯Z &ÌþªÓ÷^™?·Û 33su/VÕ‰¹XEacçbe]·ê€LH Lt&#¸{!¶’µ”ZÖÂÎns`&‡ZQ=#$…`®ºÔ†ÕU¯ŒÈ©ˆ$]ŠR:Q-e]c¬ºî—:ñàÒIýT9»-ŠŘf. uEµ¦§ØÌð”j¶§øÑ“©¥ðFÙŠž °ˆÉ¹©‰ð@™•Ý>³Q Î¶ææ†æww7ƒ“b— \Ö¼–¬¢îß'«™@ÂN-.[Æn"ÒÇåUóôĈ¾©ï)´!_ÔkÉ(T|La3ŒC¦·Ë|Z§ã2O0=[?Ý,0ƒˆ›}­yûÍ̵”R™, bU³ùªZs)‹qqç ¬0 ”²®kÎÒÀëR¦iɱS€ÍÐ8ËFTkYêªh\”ć˜,™ÎFA¼f-ºÖÖ›µT]í¸–µbUÏõ¼ÝÕ3»«m˜ÿÂìç”&»›S;“ñ”ru_s!rI`ÃZÀÅ%zŒÑ PVœæSDZ†S#£5dUeƒ±P”À2ıˆ­¥L³MÙŠIÕ`Ùªb]×yžçi¢uSvswЉÜÝÔ•@"Ì)Ęƒ³99 d L}ßÙRb €³ ’£KÅȼ,K$ Â5Ïă¬ÓÜÇ †@žß91YäÀä%4ˆ)$ #!"TkZy$Fd΋0LKBUw_Ìú‘ê¹›…ŒLK¦½#H ÿx üøÃ­ýîN÷vKÔ1öÙ&º ~þ‹ËŸüâæêYìwõÙg›Ë›a­¹Úáþñýá›Û¾[2_n>Ågº»^èn˜"—(T_\lGißÌyÍó„Ÿýôù8\>ÞŠÖÓ²ÔÃá šu}d·Ï?{>Ãg¯>I,"²,Ëétúú÷¯ïö§7x{\–µºš>¿Ù|øöQ½2sn9©iMct«ë´ôi¶)x7¦]/›‡ãã:ûÊȳŸÊ2í׎‡°é¬Ê‹/^ZJr{ZuY­j Üÿ1<÷¿tæ{ãšœÿv×fÖÌÍ Z+Ä©Zià­’+1¤µq˜“ûSˈy;ï ÂÂQÄj.ªêìæ†@! 3³‹® eaS7tŽ] ž³•Dº®¶¡K$ö¸¿[öË&Þ„¡TK‘£Sž×Ãd3V‡±œÅL @=÷…€˜Y½]ÑÏyÕ'âÿŸ<êj­ç—ô¼^>£)ˆ3¹»¶ky³]:.$R¸º™[Ã.¸{ H)9a©eÉESk§kd^oIWÕMÝ`ØØ²#8áD®B; CäÄ•­z‹ZÉÙªW2ïcbŠ•—i™ë<¡®ç?roZÞV6O D!gæ"‡À%/X¬v®™yÖrrY­*uó™®úøxpSPµuU3RJ¥çÖdµÖ²ÀP4s™ˆøGwî<¯“Z¥ØÍÅ‹—ŠS…2’¾9ì ·§|þ·Þ*ßÎ'¹=µ!øÎj†ÖIÐ`‰µz.2@R Óaw su[ŽÇUÍÁİ5«^”8°9£˜®«.‹åŒbVj-«Ë2·ªZKÖªª›^¡nP2Š:Ì™DaEhU%1„Í6pÈ¥(QûõKŒ$B¦¥xúa“âr,)HœçI$DxõB"¹€]Ý™õ<3QàÀ¨f#“9Áµ²#°âÀ{Ñ-˜³{%ÍîY `%­d ÿ^Ñœµ&³ìÁÉ(°Id¨¹4 ~¼,óä?hùÓw/Ç„8âåO»¿û‡—Ÿýâº3e÷,Å?~8½{ÿ퇻ïŽ'°=Þ½ÇõöþxøÙOv»] TK4_˜»4ÀÙÌZ¤¾lFt²9=.“¼Êýáp<ÚõubxõüY ôìújìÓ'/Ÿß~÷îþîýõ³O¾úýÿø‡7ÇuòÍŶëÀ¿û—݀ݮßîú.u»ËÝó/.ŸíþðúËïÞ¿yÿæ6$é¦ß]1Ù¦f¯[ Ü $UúNb¿fl/íÂöæjÿþôN߯÷ÊbÂZ–ÿñƒ½áª>æÂ˜Øˆ\@OŸ«–UT×þ$r’£°À™¹”•‰˜…HZ[‡ƒ©èjfçdÄÕ Õ{ ’Bµ°á¹¦òv¥+ï“sÉë ëãRRN\…ÖÐmÓèÔN3°_Q˜µý g™‰¿ŽðD ûþâ|Fµú¤ó)zf°©Ã„üœÞ8'J¾§ïZ;¬‰E„,N®žÕŠj¶'WS`& ê˜KÉmŠ`˜ª+¸áï¹µ25“ œZCX£Š@ j"£p’"V uØ]ôl…j5eG$ çõTÊ©älšÏEÂü”5t­`"(™¶õ—s ñàÂ&‚ £F‡io'÷Ikñ`B !…®3ŸÍiΫ™‡ Z=çlNëš)Qì"¹;3BD"¢šXpfßEá.ŠÇf,Nä¼ÏU׊EAFÕHÕü©¯¬ÍQg^Ã`|ÆføÇ^‰'_¯=O‹Ö\ ûêXk¬)R”È›ÝH‘–9+#ךµRhW @¡µ…¨ Œ|ÁšÙT¿ß ºš ÷)ŽýÐC)/™ÈE„•`Nk-š ÔˆDh˜Kõ¼Ô U¢nÜp ó¼"PQ[òÂ@3ä (D½Eÿ($ ðÜ'–蔸uê8ªZÕÝU 8qŒW%&v§–vrUeÒŽ9†`!rÕ ­ZÓ¶$Yáæ\Éݽx FÁ,˜G~‚N‹™8'¢­S|šý¼æî!ð¦iŽK¾z&Ï_m>ùéf{ÅiXw×´{± }}w÷þ_¿üÝétè{<{"êtÿo‡·¯žwÛÛ)ÏÐÕvÐEˆGçîtšçy5cw¯Õûn·œO§Óþq»ÍÐïJö‹¾zùÉn¡ZËúìb·ÒüøðþÝ[yÿí›?üö8¯H LXv:=΋þêW?ÿù/>ïÒðåï¿|ýÇ×ÒÃí»Ç8öt|?Gì!‚7þöt7/˲®ùÔåœsv§¹¬z@X¦9Û+Þ„ëíuJýéḎ%EÅPáøÓ‡·áæ¦Íò¡ãn¥6v ÄA,c×go IDATZi‰*©Vvx`b¶Úš ÄÕëÙH NEª™9`-@bªE—••B`çbœ±Q¹Ššj™xÿˆaË»^zî¢(ǵœî^ßÚã*9/‹ÄËÒŠò 373çžu=Áóÿ$Í-áÄ|ß:K„ "`W´Ý™£8‘ÃUµé58·R"Óbu©¥<±4TfbYk®U½Å¹Û¥ÝÝ? 2&n‡$Èè|–+YõjZH­g¥ïH¨è|\êÜ  g^4ƒÚŠÆApsh{z83g«>MäÐ(‚Å4‘ŸT'…;ŒØˆA$"ýöâ0ßïOD4v#ïOÇÃÑÆ±AÁs‚ë©£^(E‰$êš«„sv;KeÔêS±U‘YÁÔÌ팯²§«ÇùGº?O9¾sc¼ilçüPŠÓ\- uÀŒ¸R(QRtö9¯E5uQzv>QÛ\°;95ÕÅVSíHRp¹²VKA—§`<3w!vŽªhLp븨‡"¥= —mBÓRWÒB®1  ïzDNèOÓ<ïg–²¤ÑѤóRf”µ+[`"aVbÿÈ i_Wrxu®ªªj¦¥JÑ+Ÿ£Ù…ŒÈÉ UU5t\Y…LEUT£ybªVws‚Z”º2©Q…Áܵ6êHrVçˆó¥ðÇûÜŸz)èã›JB7àæùÅóW›í%ÔózÜÑ0n»Lù›wo¾z}Øíðâų¡ï7i{ÑÙ?ÝÿÛr¬V,…x(5À7}wgÅÝkµãqšNsíPk­kÝn/\)/5ò0ö£ËKør˜Ÿmwww§Óé‹Ï^ºàpW—ù‹¿ùû7oÞö‚í®n>]Vz<–¹z/ö»ýÊ2ºaxýÕ›ým®dìÀ}÷îÔ†8(àÝWó­Ì1B„'Ê·•YT·d)aedé‚ ˆ;ÓÐéþ§«ó ªO”âF œØ™Û}ÂÜɤÙÂÏà®¶Ut÷ªZÔ\I8¥ŽˆV¯ÍADªÜ­V µJE:á*ޝ®Çñ€(H ‘™Âp}¹íg¢â‡÷XºØ÷:ût¿¬«ÍMÈ  h«»ÁÁL 2X±?!Ñ…i=ï-3@âFÞ@zO§;»Ãœ…DP…¶#œbȵ¶m²1y`˜5 ©Q…»ÖÅëÇ‚]37O:+(ç²–šJ0z*8un–Ø]à9¦€Ž2†Ó2-4er3â–JºØq¿`&S0@$p~ÊÙÂ?Žbænðj¦VVµŒ@pdÁ ¶”uqšÝ@¸´R1+Õ$EÝÔct¸i5f¤Ô×ÖÏißÍŒÝû¾ë8`Vw¢ÈTC®«(”¸:M¹Ÿ+Œ‘h¤ÝTÄ¡]6ñ§½Âô'Æ4#jq ¸¢Ÿ›j®à.-ïíµwE.ÅAÄ´f­"a^‹åŠêl€K³s{e«@ g¿¢pˆ¾ÂÜÔÍ\ÕµáOD„ˆ•fB4-˜\© ôv‰X£p5xÜì¶ãºYæ¹ÛŒ¨Å«¦ÝÎK>ä¼M¢7T³jȭϘàk©N^57ƒU’$]ò3N*S /kÎ%†»“ØZëÇÛE MŸb>Gk[ÜáÆ -êfư$Pö´ïTøÐξìö.~þóOŸºÛ^’t'㵺ª{ñ xœÖ¥TôÝ–0Þ¾?.ÇtÑÉ8§ùó\§Ã¼,Uk:O·‡Iyx¸´Š(}]­dco¾ùƾb_s‰àa¢ÈÛׯwÛ€·ß|/¯v»Í‹gÏSŒË´NG0Ãôîá±L³Å¸ùìÓÏÞøîÝ·ïÍ,ç{îò„.zŒ1ö¬qÇ~ÃÚ€½›Ö£1ÅÈF5çâp!ÁÕª‰¹+Ø]@Ü o!"´ââï±±bd8—µ»¤¨ËGàD+@ 7ªÅBJÝ8˜Á Ík¡Ûn7LJ;¬ÎÑÐ>"äðÒ>ëäÄ0oXPrfâ‘mH]di¿·î\P.µ4‰h²@ÌA¸1ðáhY§Àiìår3EÈ4Zw•ôÏ?ûDÿîËßm//àìúÓÃþþöV•—Iìäg!pr?¬« “°±8³H À,!rR7……`Üè“–}Ê«:±jѶ~jÄ}ZvÊùÁÉ !n,W™:Š• 'öBn„gbþ 7÷§6SèJ)¥•´±»/nv—/.ºmøä§WßÝÞ—ËÍõ´œªÞ¼}óæ7ÿ÷¡cÜ\:æ2GôÃþ”¿úíôÅçݳËOnßÝk%¸|ùo./>«¤¿ýöúêj·/K’‹íåÃÝã|š®/®˜¨¬ùñîÞÝ0Nûýþõß\]õïÞ}GDIÂØï¿»ý§oóÝ·_|1ÞÝ-ß½]ÇMWòºããÝã¦ßÔš»±[b¾»»¯¢ù”¿¹}¨¨î~yy™¹¿¿Ã0ÞïwÛ›yÎ/^=÷ícÍèv4Mes³æ$C¿é‰åòz›–UËrl”`PŠÝ]Õÿ½Â6o~„ø÷ ´òÓŠOU½¡ð^ ¦’×j^!ÆaÇeYÚœl®ËÜ€`JFt.[l;j2‚¢ €ÝÌ(pß÷ /¥0S¸ÚrgÚOØ ‡µ»..>¹yy«TmYJîúàîÓñôðþ¡¼}Ä‹OQ†uVÛŸFí»0.^[e˜:@"››ym¦“6!œïd)ÜÝô¼‚2BŒAbˆ¡Ú4t±¬¹Q@›a¸¾¾>ï2j„Hl¹Ž±›KK>?NÔ‚!‘—¡*è0Ï•Á Åà«C­^Q‡®ç {^³³Õ (3›YÍU]mŸÖcŽ—Ø^ «²gP8>ŒæÞw¡CÜj|¾yNu½}xÌ3‚‚ ÖÊîIܽæL©±¤Ý0C©ê\M›aðZæÒi‰²¼;ÌqfXÀ¤~¬3BìÆÍš«;îPt]"H^gS¨ž–ÕÇ]ˆ]p!,eQÕ4Œ›~x¼½§a+]\\ß~õ+å¬^±f;œÊqÒbXÌK­îÜ4™àPskÓ•š}oâõ&H8܈ÂùclgÚ©;Äiš—>Õº¬H"Ñꪶ»»‡e-µºDhYÍ+›“o×a§šµº†5;ÜRH#\—œkÑl0U"Â"rÎÍ™öC¿®3K ºfw‹ÂæJn] ¹,1¤ÙuYÖëgi77à µLúìå÷wßÝcËHžõŸÿúo”XºØõåï¦d1»¾_îû›a$gå”r®AJ ¯ ÐH€Ù4Mnu3¤«Ë©‡µ®k.—ÛØå‰ð³ºU·ì^YX’»³µ&LDj™¹@H“3ç È«kQâ <–JäíèøÑ7÷’µº3‚t¤^HÐmÒåóm„£¾»}søpQP¯¯/·»ÿý7ÿ²ÄóKˆ÷I"q ¹äë«á¸ŸO§©ëô›¯¿[çþârœæºÙ\ŒÝcÇéÙõóù´NÓb«}÷îüЧ.çåùõÕÃÃC$ŸæéÍ7_m†Ÿ÷‡Ã¼ßŽûýéñaúì§_hyw8®W‰õñÍ×aè—e]çeÍsY³ºy™÷ãæâõë7ÝȺh¿¸~yõ‹‹¢ùÍ›ïn^½xýøõë?|«¨WŸŒÏ^\?,ª¶ßgÓã®›®ÒÕÍ‹k;é‡ùÝ|¾? xwúqr=9‘œØ©UßZ»ÌÝ­Á µRJ­•ˆÈàj0r;Y»ùþ9O5ÛèeVw(Øé„aÁßn®ÿç—×M[êq‡Õ<眡¹ÖvCgHÍ#ØÉ€€"$¨‹€Îzo»sÛ± ç\á¼’;ûfì<ô»÷Á¹Z5+ÅÖâj¨‹±Öœk­Ð–Ǧ$LÎõŒá`¥ó ) HÜqh»æB^øû-_ ˆ@ŒLEëZ4W«ìÎòTàN2ö@¬u›0tI„XBØmcLôXrQ°Y€B;sµ}Yp‡:9œž ŸJæ¦kk[#ؼm½Ö U0¸gáSµ“ãä ÕÉlÕš‹®UÙ¸K£W­Å‰,¥Þª•’w»!tÁ ^ÕȈDrz8ÄÀºÖm¿›öSŸ†e^»ØíOk)VªU…:Ìa`C`pÛb1LŸJ>¶û_&žâI¿…?‰Ím‚3˜ÁΈS‰‘EÌ•¤€ªŸë¶Èáh¥’^j ”sˆ€` ’ój“\ˆ?–\’° %-ÏšJyþ Ôº(…Af‚hÜÝåðíz,½„mê¯û>æpê–s­éºßc"£ããáÕËW·~¤› —}©‰×ÈÜ ‰ÈÈÄQaƤ,ö”N"©²~}û®éýËm^ÿö·Ó4õ)̧ÌjõíÌ V÷;ï“ÕÚÊ‘1Hˆ…8@@(CkÔ"¬n±ƒÿ pXs40³ƒ,déëT¦ÀÝqº.»g¯FIºtÿ¸¬TÁÊuañ8Záõ”Çn¼˜k±aöưq÷ò»·û‡ý×®&ÄUË›×®ˆ¼~òIz~9Ô\H«e»¹ØÞ¾{¸ÞÿøëÏ]¾ü×/·ÛÍ/¾øü¿ü_$¤ëg¯þéŸÿíxXooýùË‹aØ=–ñâåõ~¿7«yáà&/%xÿ¾ªn‡Î`yQ"é/†Ožcãîÿø/ÿ<ŽýÍ‹Úw!?æišd×m»dYï½sT¤!vÛ·ó“…ÃhWoÖÿ~…½‘³>þqgg"vâó"‘Sdf«Ys!¢3ÛÎÎ纡93HÏ<,|†ìºñYœiÛGSU§ê±b4ü|óÉÿòéåÚé®í”-/ÓBÂBcp&Fèâ¸î†6Rc Š0(¯KÍêhÍL9ÏÔÌâ†N~ÜÛ.‘éIs÷ 0$ ªV˜TaŒHÜÔóRJ®eE.®D,ˆ™Ÿ±nFð61 qßužµ¬Z`íEP@!Š»­¹–bf,h£Ö“šÌ8OôXÊ0¢K\V‡9‘yõö¦3“À©ý†ç“T 1pB¨År5W¸H2|2,Œ€Y6³l^ª¥Ø%E]—‰Ü‡a æjÙÌkµjì)Æ@ òj»Ý– zIûýý(c^Ïœ×RV*ÅU¡ ªãðJÎpóVYïF`‡3ý™T‡£+F®pŒÄ™Ð²¾æ¦°j^}µ !!U3SRH8€ÊYÒ{ªŸ gªm}á͜àÈbB… 3>–žóù;çvît<7ê0À„öar³êJ$uqØöÝÅæôݻ´èéá”öóqåe᥊òE<ÑB"wz¼éQưÛíúy_0庖ª fUZè*Hà ðZµjQWvHÀa:åT¼ ›ëëár7·¶¿fLq3ˆ©5zgmLît~öS‰#‚ ©›Cáš“ý¥Õ§TÈ &Ì.e­Š„‹g¸zÑÅÑusç‡òòÕõgŸßP8Å¡{Ø6]cÉ';ÞO—›íÐml-5ë<ÏÀ~Óo.Òöº[ŽCq9Í%H’Óqî;üòï~ñîÛ÷·oïw›Îjíûá×ÿù—ÿø?ýª®‡Àúìj3Ž›¾Ç?ÿÓW÷§Ï>½6W_~ùúpÌóä!¥›ójP 0dŽu>×e!¢»”h5åþìææñð`ÕòR¾ùý›·ß¾Û#„/Ç ƒ¾ýú/>ÛŒ—hðYÇÝfÑ5Oy?ôPu.$6ì`3¬ÒÇ@ÀÿoñdíòÎU‘‡$®®ªD”RL]<# 5·Œ dröššúǯÛGYãëJ`#sRƒV¯fA+>_üãÍõ/¯Žéîëw€Ùøìjy¸‡ì6)J"EŒ}¿1Z×#ØQ—ršO –OKMŒµ§JS`ÍÝ]8>Þý,~lìþˆRò­%¨u’¡áž­¾ÞêIRˆ¥¬¥Öìš[·¡AU €ˆÔm-¥šA„¢Ô†8ÄáÞZœ(¸û¾OÅr•êŒZ1S‹‰Rç½Ï¼î³-Í ~v~4ó˜˜É½¶ï,ÔU°» !E4w¾ÅÈ.<—:«« ܘªÁYÀ¤p5 T-¦êd¾.¥9ñJV2s˜Dµ–6°UHñbÜŠSé)iÈÒf07q0Ü ‘¸0Wsv ëÓÛóWàÌÙ ªŽ«+üÝ/_½üéµÇ²½¼¶ò+2C·¡ï¾þú޵ìð!¼¯$ <O÷·ë2ýï_m.§õêÙÍ·S¾ÝŸœÃ:Ïýf+ÄP“'¨UÐÙt+ëØÒòÙ'7ó´|ø°ß/]ŸÆ‘úþêæùOîîN_þv–€q“ž¿|^Uoo? C3„‹gËîâ_þë?ƒôxQG Ân¦ŽÛÛ÷ªÚ÷}`Yµä)OJæ¾”Ú÷=ƒ]mÿþ”—u¼îÉÓã»Ew]äPêZk ‰v—ÝbÈnÍü´=! ÿÿä©qûjÌ÷ÚÎÓ'ò‰ fu#·fÍ!UÓ’Qð'h3©+™C ƒ .D,ÂÌ!FI"Uªef&'0£c</~¾¹úÛ+zŽ÷§÷8¾A„vœº‡µ‚Y³NÞ¯]‡ª5±GEÕ%—ã„ „Ó÷ÿÈÛ(Áp¨œ™ÍäË$üÿ1^4#<µÄ£ÂÏhà'êi nyNE«uj¹k÷ªZÝÜ-’š›9ˆD(ЬV›såZb°V­µ¶´±Oú–qK]¶¡>D\nú¾Yú¨]Ðà.¼ª‚؉׸×énµµé-­ô Þj!ÈÜ\íÉ ®€9U9zél]×Ö©¸0–u-†Âd,-˜P Jl50‡y9Yu ÉÍæ\’R×÷ÉÈrYͬÖZ]‹– .Á§ûÓå°™–õùxc³^m.ëá~¶,v¶Ã5f€5ÙšŸJíaøxÚÒGGý7XÖ­õžø ÒhÏ3…)šæÞ¥ìÕ`µžÃÈ›¾6œ“4€Qpý¿œ½÷“Irçé""2óÉÒ(Èn´Erox·Ë#ϸGÛÿûì–Æã.ϸ»Ç™éé-¡J>ý23"Üý~ˆ|zÈár¦PVV €'2#<Ü¿ßÏIJª¡c@pe´kb*"ņ– U4å,e€ƒ`fÎ9çH bŒXyrÈžµrÉ“‚t±µœÆÍôìòb|4Yî··›Q§±Ýl¹®©Â;=>:}½¸Î Ö·£ºÂQ£•K}24`ÄàœUb»ÛIŸrgL¾ªªÊU®öf¶ê¶£Éx·ÛÝ]ßX×L& ‘ª…ª- aÈeUTc#° ªªåyd5d3CÐñÒ@6ô…2ñ¯g¨þ–Ê]¨hî8Àü”ÏϦg¡K]=¥½lúÕjK¡²¬2™LêPW´]ìáîvIYoÐ6ËÍý|üqóüùSçaµY&•u»[n ¨É1.Úû’Œá®_¿YÞ·G³cÿáǦ~wýæ¯_þÊ$ͧ9¶½l9Ìþèßýx<=ûÉO¾øú›×Ä0WI0F\®7· y4°áéñ¬q]5UÝ9ÎN/Tñõ««ûû¾nt4Q»k½wÏž=F777Ÿÿâ¥?ãG˜ôõõ«n•/.fäÜívÁU/€cd‡G³ãúlümm’sÎo‘Èï'ÊþÛ{îf¦*jR<ÀT®NМs X6PoÊ¢9甡!¡á¡åE ``&ųˆŠìÙ5t’È9­ðøÙ¼yâñ˜ºÑŽ<‚;õÖ4£Úo:ËÚJŸ%gØJ«®ž»Ñ(xcײ˜Å Ñ {P>ôfÙˆM±ä™êÀPU‡ˆeú:PÜ‹]””8!0‰$‰)¦®÷ªÁq]‡Ô­“ˆ1añv‚šŠhR%P5a(Z òÎiI9‹šH9â xÎQÙ}sVUH ’³ hIR-*fB#$G%ö4+{/¤Q2©&ç+G•7ïÌu»}Ü ¿Í6ÀÒ£¢²mhÅ MNPÀŒhàkrE¤ç«ªË9f‚¬š2hRHDUÔrÎj(b`æœ3Øg ð¾20(¤~&ïdzi°ÜiÛkÚG®©Ûí-bê3f0wÈ;=½‹Åy þØÿìZ^*=@X‹%OÕ¸  K¨ü±&ÉQcN]Ì)%̀ʬàÕ¶*”_eëÁÀÈð? ÐÎ*w05˦Q@SÊhYŘŠÐßëÒ3›cfÇb&©¯«P;®§¾‹]Ë01Îç“fÒ¬ö[®ønyW×#%€Ê·²nEÔŒƒã\@®‰ÆUH}ß¶mŽY[5§è<;Wa¼ lV[ U2R`À, ÄQ%D°ÓVž!«ii‘Zѹ;@Ñ¡k¿GÏÝ9P5 p|ç§¾¥-„EÙ¹`Ûnj Í~3™L.Ï/îìâ®…ËźßŒÇðü£g.Oï·íæ~³Xí$iÕ§x~~þê«›Õ<ÿÿãO§ãÉÕ««ÓíÍ#xòá³íúnqß_]÷ÓqwwÛNOÆOŸ>½¿Ý½zù&EÙ¬»˜à?ýéÿùÓŸ}¶Ùm“ÚÑ )ÈÕm ßüòå+ιkªQ¥®®ªÇO6õØ9ðòääÌ ·»ýÝÝ&çÜ4·MÓ\__=~rÔ¶íõë7³ÙÄ£?»8ùàòÃ/_}éÕçÞÒ>*3„ª&TêºÎ]cTÕ"´ø7¬ïÿÂÌÓÞûÀ÷~S53#9€‰™¶&äìŒH8t%ÁŒœS.A4ÃG  fìU5kF@-÷C„ì~òðìäh½\ÜÞ\ï–· ýGÏžÆö³ó“Ó]·}ùbùí«¿þäÓO?ýä¯oÿ¿ùÉq=ÆŸýìg)åW/–ǧáù'Å´Û®_cv‹ûí÷>y®Ù¾úê«Å}šLÞœ^ÄØg‰m»Sïü僣Ývßîö&PUõb±d¦‡./^¼~ùÁ™òf¹ïÛy4žLÇÚT ºéÖ׋[_MÙ²!š é=Câàw_Fzß.p8¿ ¦PÑ‚ (5&"2±!XBd‡^‡6 2b±w(9 ÕLE‹ EULsßT†ªšØS²  ¸{õ:?=®7°ãMƽ«Ç eÛ­Nfg>T<òaT­×Ûþf»ÝÖZ@^uto£up­ n¤AÄ“åRYÉÐë/× °Ã"¾èdlæÈL€È”ŒYÍ1°¡î3‚yæà<LµÍ1ælœÁyôÄH #QBÈ„ê ÁÔ“±CòÔæôâ º IDAT¾7‘·Ý/=ts3(‚X6…"¼p„˜Jð—Q*heg£Ñ¸Ú‡DÛØg—c$è·Ð`¢L£´®Û´ûxV¦Á Røà¬*¹ô£uÈi,j!Òœ0•}.8æD àœÃ$DQÄ ù ˜€÷ûv4®©o;U ! r[爃¯Cå=“³Ív·ÝêvÑ^œ0«ô;™6÷[—]·‡ÊÑn§Q`¨ËÖˆLY•'Œ3ü] ñ;¡cÃD\ßU*4ÈfHÌ2˜8A4CFuD¤–< cvΪˆ•¬’N útüèÑ“?z¾Ún~ñúõê~q÷f·¹ñÝåû–{½˜ó¼9:·a¹»»Y}û­\Ì?8ýÃ×7ßR»KðÇþ§7¯_ @|¨Þ¼YJþR W«…©¯Û­vgGÄÚe;ŸOý拟nONÜ~ }ߥžÆ#ws¿¸]Ìçó§/Û}¿Øíl2㪺»ÛìWÝ£ž¸ºê5ß®W›ØÖ¡º^®_ÿ·¿ŸM4ÁééÉÕÕÝj½¨ÇžM&£×‹Ý<;ŸOÖËÍ›7×íÖœ" gU¢Á¢HLf*àË(ßLA˜ƒCH$«t] ªb2r®að©337 ó#@É¢F=h˜‚tLEÛ^ÚË„(’€’9WÇÑ©šI^´PAÿÙ7=äÙ|ØŠ ¸\Ûìùy›RÙ¥ ìŒaä¡ ¹{¾ùï·²s™ÇÝx™Ÿ=œî«v½ÚAFÈ¢YbÆl.(  2Q"9—Ô ï8x!ÕòøF#ö^DЃ¡î¶Ëf%wÚ4yêÀ|´CɪÓàAÍZ«W»º‹ý2§TÛ-ªg¨çM‚,6»X2`t5QÀŒ h0¯Ç©Ï )©¡°ËDYg„ª>[m8B¨²zg›nÕˆ¯u»gÁÚeÓóySg?wÍšÜ%6¨Gзੌ¶Še2˜ 3“˜ƒ³œE bJ9o»Í›u·Ã./ÎØ»dR1!@ßvY Ï)bA!€f³¨ÚK˜Ö}Ê]ÌcSŒ ]Ú«±(…̳º>™8væ¢d$k×-«ƒLµsëmNö v ‘ D5b.ùë0ŒìÁ–‡Þû°â½ö;øË£-=$bPÉÌ,x¨!:Õ˜ºsfc¥@œÔ\¨õ½Âq`v(1»¤ÑB±)3†€µoû^L1k¬QsS m¹ä¬xDÌ}Cpª*ô 9\µmÕØîõýÃï}ðáå³–ò,̺6= ª†ºþú›Ï\Sµ}Ïgý.k¶ó“s4 £íݶ¡*ÇA½§=æñ´©Œ…–7 ßꬮêñiSßÝ_Ý¥ýU+5çóª~8=îV›O>ø8êÆÍêîþîæþÑÙe¿ï_¼~3¹8§q³¾» 䃚)‘qJÒ 8Æè‹kI°23SD4Óß³rïºN1W T#SÑô¤ª«Iî;ÉYº,Éz {–ªâÑ>¶ˆU=qã9´ Š£¥W×7ËÕZܼYݽؤîïÓæÊâ@d{s·½½û?þä?ýðÉÏþÇ? ôÛçÏ7Ûª1›­—+;žÿÙ³¯nÞ¼xsõõW¯nï÷„^rJ}¿ð®žÛ}÷æf·ÜuÛ®"`ŸÿôËjäÚN›&›f<ÁÝÝý¨Í' 0©ªj2‰«Uss%¨rÞ¹¬º½¶»öönö  ÄO_ɾߊf9:‡›å›G1GE³Ãñß~óèJï †:ÐðL˜ÌL ÔtHVfÏ왹ÈÝTÕQ X­ï€÷K,6”q ÒÁš¾uIrËX\¶@½¸àýÉ1)»5t×[ØyØX+®QÅ/Àåº*×!ñ{Ü-DvL,:´QE2¨€c_»Š‚ AÄÚØKN@jÅù(¤™ 7%IÙvH“t9õ @ãl¤ÙDÚiì±ØàKvìc@HäÙȦ¢*Î) "©eóˆ”j†qæóiÚ¾–äsäÜ‘ôªfP¡¸¬œÕº(»˜c2ï‹­Œ´Ì‡ÍPù½º ÌÈ2B2HÄJË3£‰¢¨iÍZĤ¥{7p¡rÄŒª’bÔ„ˆhÓù˜¬H±!T*¨ V¢¨‘–2Pþ™ ÃÞ ÓÐ÷5òf`%» †“ŠDQGUÎfd†–ÍD²jñ7@B`„dP†¢jX|Ìè X²!žw8 ‹BMJªV”·J%†d!DBEÕ¢ÞGg„Iúõvu}wÝÝΟå(±Mãc‡J»UË™/ONº–‚_¬–6õuŒy}wQYÙˆÁ4¡ô`4í÷¹©Gãf"1ƼB3©|uû ²o·±jªÊ›ç•õWiw¥{:yµ_mîV££I¯ñå›Û£ãSÝ'4C=@EK\»˜%TFg䜂CSÍ8ñ»‡u`FDßä“‹ptVçfÇ.«Ef§ŒÈ»N»Ô§l¾™À<%Pw“fvqF7ýbh—¶¼¾Ùµ‰ÁݼØ-®Rc ‹¯©ŸÕ±k¡’Ív›Åç?_~ùÅËOŸŸ}òÉG¿üÅç%»òøìÔûªiÆ/_¼¹^ïü|¶oÓÕ5 îF ì;ð¼ÎqSOÙ…õz½k·.pÕ„¦©sîëÚ]Þ­-¸íh4*qÉ«Ír>?‚ÅRœßûÊ+ôëm²ÓtZU®Ò‰`TÕ9·}×ïÖ»ïÿèSe}ñúë$©Ûô• |ã뺮Et)ûÔÈÛ0h‚âÞÞˆÿz§²èSÌÔ£.ÑÌÌ΀‰äc9 Ñ[rîû§±"t7ÄÒYzÉ}ÛU@Með$禣PC}'º»_BêòQšºb«êd8Âf¦ÚC·è7÷¯DtÝA’hß:gÞgK¢ŒÎ H÷ÁE ˆ’Ù;"Ò@ÀÞ!»”ä Ô 1+ ¨H”M’i2Í`MU€401£€ckCM–{MIM˜Ù3›e&DSíÛ®Ýìû¶ÕT^(™ÚïRt…üFÏ‹ærÎ"Ärx+é€J~k7QÕœá@$(NßÃöÎ예©Tç˜ûy(V7Eö}ÑÄ”@•ƒ…˜ð;I¿y™½.ÊŸ÷#M­8Ž ¼ XrÎ)9BAµ”{Q&Bç½G£@l0 +ÐHó}KÔwh6‡™€³ePfdbÐŒET¢H@„Œe W$¤¢èKï~au_Í=šµûmÜÑl²îÛÍâÞmï–¤ºS´‰«fÜÜíËW7œ€s¤ *YD€0™Žë ‚뺽’Õ•£PUÎ'Õj·×Ýn±¹°xÚIÕOp±lkWkŽÇ£0^ív¹ë»H"\T „DÃÄXM˜£ 9fÓ†¤¨¿û@UÑc¨àìb||2ZÛ]†~±¾ŒÃ̘Œ]›$oaׯ+“æ’»,šèhtv/Ýòº[¡µmJQ ë»Wûõ- 7ëLZ摇4™UÖï_~ýUàÁyµÛ¯þñÿáh>7€ÅzÕeÙµ²Yo_¾Ùtr7{8¦SH T!%f³Ùýý"„z4ª-¥tÐ#æã“¹s®m÷1‚ t]çÑh4zöüÙh2I¿ú½…*ÌÄ+ˆ9Ðé´ Î- Mzvrúèñƒo_}{w³‹»>aJûìëÐï7£ºqªàh4÷ûl9Š–Û›Þ]•ï®|¿ÿþ]×ÇA:&o5‚Ã¥¬&)õˆ("f2@&aà†ÙðMÀ˜™±YAˆ•ÇTÝ2¡° `Ì%ÔÂ@’Ĩ’UzØo¡Ýæ,þƒg–µò®ªZ‘>Bf³ U„㺠ËAÊm· Vy`TKÂ&Jd¹8‘‚¢Ü‘¬j BÊÀEÃË& 4+(BRCQ`@PÕ,™ E C]ã>µ1«1ª(â xï±K}GB1úsÀÌʘÔ:Ë #)dYODŒ ‚7@ÞaÓ„VÛ½¦¨’€ËÐV­bWYðÀ9öݾï[È}Ñç•y,1{1,H¿ïL! «ðÜCØG13U-±:ð™ F84È ËJj€¥OÆ}—Ô2##+s&¡igଅ¡„49Ç`ñ`ê* '´áZÒQ „ù0±,Q‰ŠïÀ¿ò~Q?°†CK"åoƒÛŽÚ¾3+ü!3"òà˜: %;d4-~´2STCE2d Ö’’*†VöZÇ*\óHT–ÃCG#R><ŽÚà@Ôâ7¿üy;¹¼„|·YßmVQm½ÜˆÁÙÅŬjªP¹òý6.÷Mª`ØD­<0vÕˆU°7ÑÊùàr…Û^|íÿðûßﺮ¿Ý,ïoo—«ë´žž>ùàé‡ñ¤þöË—³ùx’ÝâÅu—â|:ɱâb Rú¶E¦¨ÙPÀr‰ƒ7¨=:%àßKç. 0›ûÙQ•’¨ëÝ2[»ÖÝr·ë4 C$ȼG¹ïÌ›Í>îl^?hWvwµ5Ù#7U™1t5ŶßCÞ%ë –>§þé÷޾÷Áƒ«W¯ÐäG?üôWŸ~w{{{{[×Ít2ßõyõò ²ó¢AŠ:ŸOgÓcö>˜nr†õzݶ°œNçUíÕbßÁ¯ñ›¦©C8?›øº~¿Ü¬w]??™ŸŸÏæó6õ«åfßmŸ|xqvvR×£7¯^ß\ ”1ãÙÑñêþöÕ7/÷±5Ô£ÙqêÒl|t{}cY‘„ ä•TP…¬Üëeu*ûŸÀóÿٺό"l HK‡w%UÁ9!½“* Z5@Btˆe†*…ÕíDrßAN㪶êdç×~ä«m·)*åÝ–wGv>™üžâÆîq™÷QÁ²FÔÌ• TVb‘”•*¬ŠUf(¢‰°xɳ’uh9÷9fPUO¾—ÖÈP´Ð¹›È°‚8¦à•PÁÄy@}sGÈ^TSÎ ÅAS¼~æ÷A|]¦³Ûû[ôþáŃ6¦õj»m;áxÔHo»»»ýëUHYÁ .LjØSƒÒiôH¡§÷y+Ÿ~üt4­§Ç#™¥JëÐelÉçÿä÷NvovÛnë¦a6™ìvûœ3aÐ’ìQ »!ª#éV“³Zc0gäí÷Bþ8ð¦³ñxÜì» â®—±±]-ãz7r¾©‰‚«j#Z/oRgëÛ® ÕöNw÷ ¢“Qè÷ûžr5!—ºÞ Í&“I…}·?žÔÿëýðg”û};ŸLš:œ]œþÃßyzžæGgy»ⳋG¡™Ý®×0jªÐĘ»®ŸÏNdŽ77ëÛÛxrâ Z"BÝxØm»"àõÞ7MƒˆÛ]ΖEànqÿææõùùùƒGöý~±Û‰A Ò?¸8À7/òñ<4ad*7¯Þ8ç*†Øõ vrv2M×÷+éòhT3Ô£ÊÔöÝ&¥Nô7ªöÒ¡Á÷ê÷ßÐ ¿ êpn0+îÈÙˆÐ{"_¸Š%Uï»§f5$d¨ÅçOÄfŠd`ˆït¥6d,¸T›Ïfgǧûý^,“1d0³#ܼ…ÊÙqs<>~0moZȸì]Üw°À€F”+ªsÒ¤:(wËXTŠEĆMQQ“tÒ·m‹ìœs’©Ô)ï=»,¢fÁ„bšÁ”AÀ°Œ‹5W <jÖwk"’•¤*€@؉i§¹Óœ Œp Ò˜€ªGp”À;˜Œh4ªÀYG1°†±BrŠhŽ<9eÈ"å6IFð f@ÌL4(ܳêð’ã¶ÂˆlæŠw‹<PÉ(mÀ† JmRT#EœN ‡¢Ì šª³0‚©!¨I†^I˜À¸Ïªx`6`!l¾õ, h3;hö‹~c¼Szo]Ƈ\­¡ñaXF¸d\‰H!ܶgª™¦,h¦jÙ„ÅÀMóÛc ‚-p4Mi@ãUÞ{1“lšEÍÀe@%)ŽVSÐbîC†Ê…f6‚&4³±rüñÇÿN¿}ýæêêêøì܇ʒX¶´í»Åf›y¿Ù/ïWÛÕfZÏ$[†ÌDŠ bhÄJÜ÷©ΚZ,ít¿è·ó³É£}ü·ÿÿN§ÓŠÝÖuár’·‹—›7_ÿâþãþpöøôÅb-.ÿÅ_üiÈî¿üå_k³¦¢Š)£”··³3PËÙ(eƒRb“²ýÿΕ»÷Àž³÷®öXç ªÐ÷`UÃÁy7QuQ(ƒ4µ›½Y~»Û/òžgõ±ôTáøúêv·ÝÏG£ŠÝ~'Ž/Oç#/9­¡ß/ïÞŒ›ðã?üÑ|>ÿêë/~õË/OÎ÷*/¯V1ùÉh2;»˜ÜíÖG'ç§›ýÍÍ]ŸeßŬPƒ+ݮߨéùÙyîêÕUpMí«ív»X,QA}ðÌQD^¾|9šL..Ï—ëÅj¿vŽš¦Þ¬W¯^|µÛµ±ïð½O ø—¿üõvÓªÀÑÄÃ(Iœf5¶1z?=g4WW¡ ì©Mýr¿ë\0²CÖáoQ¿—.*9"VsˆN!H0påöVÕ| ¯–cù°¼WÅ ³ñPï$IXÎêVØ|ë2´mK ‚¯““ØÊbµPJ³ÓiÖ’ÁÖ¹_¶«$i~y2†Ù‹»«t»G"Ë–röœ÷,2F`FdÕ’÷P¶‘C€˜Ed¿ïL1÷=„Êä>9ÄdßþÐ&0Qé,—MT‰]N 8 ^ÌráÂ2Z ÐP ôì6’[Í-€0(b¼1G€ a6©ë‰S–Ä’*Ëž3YRQPØp]©wBÚå~×K¨àpà+:C6ÕœJXŠe‚‚°B„’"=HY ²)Š%0¤¡ŸLPÒ|؆ ŒD-+=HYJ¼k™¬bBCSMþ „À(“a‚Þ—F}Í €`±¿­(¼£Ê »éÐ&´÷’˜ÞA Þs®Ú ešÀeð#""‚Ù³÷Lˆ%× MEʆžOiå#d5#4%ÈÉ@TJš+€ª >,f)©º†I‰ÍPQ” L“HíG£qÝ̧-j—Óù“ó~ðÉËׯª{ÿìÙ_«õñÑÙúndža{·]Ý/ûÝÞºd š I4ÆÌ–™I 2À¾ï¬yËY£yÌ#·ñ²€ý=ì¹n¨ò©ÃùÙiÜió?þäï>úðÓ£GÇy§OÎB":jº« À@LiP¢Dô¡â94͆ˆ²”…Ìí÷PË´º½äŽxtT9ùú‹¯›zÒ·ûýv“$®6볋Ëm__/O&Ïžz¿Ž¿þòö³Ï_/¦§§â胞ŸžžöÙç¯^¾¹ºêœƒ§OÏ^¾¼ |€íœƒ§O]Ó49'Iêû¾QCÓÙ8„°È»º 77÷G§WªÇ)õm u­Î÷žá‹_¿¼zŸ~Zýà“O®¯oö› ÂÙÉIY¬wUµ@Çl6™.7÷Q’C?nf!Œ\EȪHùPÕè¿>D}_ ˆ„ÁÐÈRÂÀÞUœs,Ê÷C¿à®ìЩµ®7(ÊyÀ b2F@ !ŠwbI_^¯·0RÓj»½[Üé~ΧÍh,¨›q ÎCC÷ýróíÏ@ÜøÁñeu¾øå~ùek[‰9:¦*0"BFe#dòÚ[1Üš‚‚šb=÷]͆žØ“’Ôñ1‚"äC—&«d1U BS.þCÃlð!"¡ 3dœRRËFh„f0¤&)FÆ Ž ®]h¨åÈ“ ÇŠ3ômßõÑ&Ó#î¡1·9õC|aVnØhÅTL³–ç÷ž;‚’BÑhg1PÉÂ`ê†ÊÐaA–&‘œ†ž;(`(#`/51P-o²±‘ÁÄW(I’jpLä ¨¤©+ wU;Ørí-BÀìmäÝÊþo›ÆÐÛÝ ¡$ iÎëy*DÄ®ëT5iÎ*–¬agÈÈ…;GÆ jÆMƒ(m4@=¸¢@‹ÔÐ$T P0´Ìì P•(š%ÐÚs3…Q³k×ÛýNï‰_¼øÛ¿ûo1Ë£gÏWëí·_}{úãóãÙÑ8Œggý¾ëxO1v¹Í&”µ¼Ê hF–³Á.&çEúV ŸÏüt¾ŠËŸ¼ú"Mœ‡Üz“ªF›º™Mϳs_ý_ÿy¿_?yòlAË¿ÿÅ?…™MüúU7±`¹AyÈj/i¶ªj™Ì d  ¢´ãï\¹LjÜvöóŸ~óøÓgßûãgËþÕÉôi–=ÄíõÝæÃ'“ùìügŸÑ'ÌÏîî7GÍå_ýß·ºRìáôlr:{pÛÞ}õÍ—)ïðéó×/¿ªFõ“Ëñ¼i@î™Ý|V=yüЀ..ü?ÿåož<ûàâò¡»ºZetß¾¾~}s·ÞÁÑon÷W÷ûãG'ù—5™L>ÿüó¾“þðÑýýòõëÛ££êôô´Uû·_V5<~rifçÇ·¯–ëå’úé³lúÍ‹oˆp<öÎ9§ñç?ÿâëo¾ •¯k€£éd»XÂé1ôûþóÏ~þýïÿà?þùŸýåþ›ªv_|q]aßBïNDË9‰æñtÔîz± ,†òàòäü ß¼¸êû$ɰ 2"ŠlßW·!0"1¡#r`Ó¢©¦Ü¿•ÐûJ ®ªˆ8BpFø¯\ŠFE&ç=:d´èH|!··_¿ÍNê6-[ýÅЄXñõÝ-œÿôCŸìyÓo`‚PéÈë`ì@:h35y£ Tú- 6Æœ%„uF¦˜5&@&Wíw»Ã¨€9g5L®®ë”6ggg–®}]µƒ}ј¡ˆdÉ¥r)Ô\œ/ˆ%_»O1f bªÌ숈cb°Õ¶OÐCSErĨ Y 7 „ª†zâ©‚^ûTùuÚc¨«ñ¨ÉDFTÕâ´ÍiÑn—;éÀ!‚a%‡ ¢ˆ¨chJAD˜0 @66…ª Asâ˜d\WìhÛ÷ÌLˆ&9×͸O=K¶ÑhRÞk*¶5|ýT:x¢jÀ†l4¸ÚÉ0P•³V䨂Øg…Á§!oDÁR)…ÉxH´€wuúá*ºç deïZƒeOÂn¥ž`0_!zbvD)çœsß (FfOhŒ>ö%R#$ éú, ÉPÃXÖÜgŠ“‰„ªaæ>§ÅT%%¨x53FÓN4YDDsØ›dŽ«°éöãΫ*¬ë›åýd4ä7/ßÜ/W—»}oM=&CÏõË'×onn^ÞÌOØ•”Å:ÌLj˜ ÆÇÇû¾]ïö—Oϯö ­¥:ÚѨµÅÙ=ÿ›¿úë^º}üXU¯¯oï_½ùÞ³Gˆ¶^/zˆIäë¯_/oïÎæ´ÊÜ[*p|@pŠ€D`D\$¬oƒbŒ0¡ šþ®•;ÆÞÌ`µÈ¿øé‹Ì꧉pZù†GÌ"ïv;µì*çkœÍ&_üúÛõJ§Mí«2]¿¾¾zùjy·~x9º}óõâ6¤çŸ~øög_ÿòׯ¾ùæÿÿáúöööþúnµÞíû]Ÿ¾øöͦŸ­7íêê¦ËvrŽNon›}·Ú¬ýÍ=3ŒÇpvvRFmÓipÎÃryÿà<~rùàÁƒ”úú µo÷»««+ïýéñéh<Þì7Î9ç\È¢¦>‚‹Ë‹ýàû·¯_|ñù—« ˜‡ÛëëÊ…œõhÖÜÞ·ggaz4ïbÛžm[5èbÛ焉 ¦Ümö·¾ IDAT7óé±rÂ2ÁœÐEßæLÿYºÕwfÃgán!CÒ·£Å·‚°"…,û¡NGD$)R„ÂH9 ¡JÈ×ÐgwŠŽ] ïˆmó öv=ä ‘úVÆa¼|üVwàƒµ«8I$æÊ×óêx5ïëf4ö\5GÍò¨%hpˆÑ \Dv†4˜Û‘™A½°CVd$rˆ¨2t›¹œ©Ëf—ÑJýûeq+”8ØÂSq 0ƒb‘舤¤À( ©©êÊãÛKfá0¥,H#€:@¨@8e6 °ê7Và$}Š&`l˜ ³Q"Nƒ"»H5ˆ©‘ -Àʉzh£•׆Œ œò‹Ù©f;„ü‰HPO’ÅÊ3È^ËT¢è(””€‡§$^SʃvÛk—=»ÊyfD‹dÔ¬œ. ¨@)ßußã~ã»u¼X'JH¬­V—V•\8àÃW6ÈiªŽGV¥¬ìJ0HŸ2ɹf@ãLQX…)“Š’dÓ>Å®ë|Ì»œ£ R ô‚A6S2# u3ÕÎü¸îV©Ûìs„Ëg&ó£›År³lÇaª•w›•ôÛ¶ŠE£íÖ{DFsÌl€ `È`@}e%à&Ф±v'UòG££'îüîN:;arÓ­úÕ–²°æ?"ß|ñòÍh~œG¸ë£ßU7¯î.qF‡­û0>.ôG.AC%Cb£":&þ}zî Œ&«[ý§üòzyñáüôb<™ùÉøœç£”úÛåm·ßQ¨6«û¶•õªí[˜MBÀFbîú ƒ\œø“y}~:yþ´ÝÜßüÓÿøêÙùl}w~vts·ØlÛfrüúó›åî»/–ÈŸÇ LUÃè’bRi#4ÌãiƒË‡C¨×ëõå£'''ÿõ¿þ}ÌýÕu>>†PW1§ùÑüøìtñz¨›ußõðä‰ÿàƒœs‹ÏƒçŠ1÷Y⨮Ÿ?ùàßÿøû¢ß|{ÝmvuàÕbÕïÓd2išf:M}ô¡"ƒ2|ýí7ë]Û§ÎUÞ׳NçӣɴnÜòfñæú+bP† g&ç8¤ÒƒþÍ܃Ҳ@3´Á(Oq³º÷@N<ˆ¼ì-’Iß®ø"@Æß}›¦ÊEžˆI!+²ó›ê¤¥{P¬8;í°öãÆ·u¦ÞUµ¹”,ȸ™M'sÏž"ŒaR庙`:‚¦‡”!TZŽbÈe0 0pÄ\9%§ù ç9¤TMeFtä–›°€• º·8øCͨgA“x„¦ò™åœÅÔ‰‡°y着b”]ß’ýf+ŒIÍ#`f¡9c‰ Aªƒ£èj¯ž-¨*d±^,* ó¾!0ÂØ;,ATÃÚ<Ø:õáB3‡à™<ñ€ž+¹" „LPTþ¤6˜Þ:vZtà‡4Y4@+ ̆8èÖ­O¢q0õ¥í‡Ê(¦àŠ.D¹K¥[ÿ¶Ç÷¾9ø¥†£`áŸ:æÃÜõ0Ða¨0‚c và˜˜ú¾7¶œ%e+wDE,O Q )v ŠVRÁd)¡¡ƒ!$•”RJrIªcT4•wÑÏj¨`|Òuq»ÞúqM LÝ8PZ÷»ýͦ_Ç®Íç#s“=¾x|·®}Ýæ~Õ®Áh<š{LÀ ÅÐQœ“ö"µóóãùj·øõ‹oxÎô'àgüry½E¹é6|}À–úÓégÛ/^¿xù«ÏîúŽÎÝ'?øáƒË‡õ/¾ –Ú æa³…ŶO¢9ëvsÎmTÁ×puÛŸ]øý.]]]¥¤ˆpvv–svRÎu ¢ðÍ7ßl·ë££Ùb±ˆ1š@ÎÀ)¥»ë[U½¹ÚÌçE¤d×Qp!·±]·¹ËMÓñtµÚ´»®©FÁyv(š^¾~s|züäùÓÅö~ݶ/¯Û‡͈ýbqݶxüèÑããçO,ïW_þêëå]¿ºƒKÅ…*œþe0}>c¥ÛY(¸oK¥w’òµ4+Þr#排¹j¸ªf%LÞШB±˜zË)ç”{4ðމ²Õ‚Jæk­FT×¾6‚æ²é}›¥ïº.u{긆)¢ ˜&‰@ÎÀ)£éÕÖòÎ3ôB€FÌì0l¼…Wf)ŒèÉ94éÚ’ 4‰ó ¢–³sKƒjˆÞ¿B`ðF©š"9´ãlDª&Àй š€X­t«UL£%ôD¤”  ‘ÈH‹û¿t+;Öú²ÎÓ‰‡R˜ P™—á=(š˜`ÛFp¨ª’‹Û‚ ³  )’AL„ŠÀ„ ìŒÁT±xŸK9fð@ÆÄû}[øæ† lH€sÌ9åÕõ"ŒB·Ý¢zp /ß|³Œfój2M¤èCM² ì“ÔA£lW[PD…mÚW¾Öœ²%uæØ+Á"ÝÜÝ6Ó†‚wÞŽ=xöäõúÕ?üä'<ç¨i¶ÛÕˆ°žÔÈÌÁêx:¾||yñðâ«_½@ÉÛÅ-æ´áâ7 t@  @ˆÀÙzDESJ™ÑWVúݲ±`ŠÛx‹]Ü,oÏ.7‹—÷Ÿž9/œªéhÌËÿÏÚ›öØ•$iz¶¸Ÿåî±0¸æRÌÊZ§jº«zó§5H‚ZÝj¡53èA×^Ef’É-ÈXï~w73}ðs#³º3ÔH‚  oÜëÇÜìµçÙo…}€ ªË¨ß5© ©ÝCIWÛ§ŸhìOÇî]nn›Ê¼~Ô¿ýí³×_½‰£ô £ùôÝíÖʪYï&“Ùø«1ÐïÿÇ«‹KçЃyÏ¢1¶:ªéøøx>Ÿn6›¢ÀíÉ“¹hèº.Çc<»Ÿýì§]g³5ûîåË×UYž,ÆÛí^bf¨jhRûž”&Ü\\5›Þ9'½Y4òœ×».^ßÞ^ݶõ¼œ.Æäþ6lÚ›~½ÝPéëñ¨*¸‹»÷—›û''÷îO?yóÕûØ7»už‡¸4cG¿Mƒ7œÁÙ4`Á—=ÚëvHËhž½ w5SäÜŒ’”xØ„TÕ¤A{ÐQ„’o×B¶M®ÃM=û~Û¾+šÄAêDȬš]Ÿ¶©Òª§N7²Ûl¡Ù8O¢ Šl¤€–€œ!eíƒiV¸‘0BÒa%„PX…@r$ ÛùPÿ%h“†%W¨œ¯œ'°“%1Î 5ɾc^ë#eLöŸ‹ÍQ|U]øŠ“OÉIòØHߘ96V՚ʂ|AØw­‘8,’‰d–0åÞÔ@ӥØ=3!j’¤Â™”•¿ò@™†ëþy¼*¯©!é°)$™Ï«ˆ`H9ϘóY4DÓÁWeLbI%ª  ”)ô¤H,ŒÃ,ýfP÷î–ƒþsŽqà¤1|/<€cð  ÍkUØÄ¢!Sáò6:\C‘AIˆ ÌDs Æ…YÌC"PF#Šbj@Ì\!$3"ׇ Ñ$RËâoCèûh #WA4Ýö««ev¼ðlä’ ¢Äææj×D-ÇãÙéÙ¦i×ËÍ-Fdžœ¡¡áÍj¤WÀbÀŸ'ÓåfÛÉ~ñpÖj|ñæU(ºÏøð8ªÆëýV›/l×^ÞÞN¦Õ‹w/7¦GãÅñìôäèG¿ùÓÛ°Ë;݄Ě}Md{tÈùuöH †"EŠ5ÛØÊBþ´ šJès Ês Bˆé .B¿÷˜h~T([Ih€"¤Ä@¤}Û´ûU…<›'‹©Jûáýùï}ùÑþÑ÷~8)§Í²}s~ õv×Ä×»£³Ñd±¸Ùn‹Ébq¯Ý÷©Iz6[üü¯Ù5í¯û{¸wvÖÆíh\EED…¯êºN)1óÙÙÙÅåEY–¢è½ŸÏ§]לþä'?ùÓžŸŸÏf‹étºÝ6UQOç3P !´)0AIe×öoW·7ïoÏŽãzff›Õ¾ëÔ—a ë¤1Ø7»ª‚².ÈÃüdü ¿7:j_žß¬7»ñÈú½G%¼~ñìòúŸÔÓ‰+5ÄÃ:"ªßj¡¤qÊgýp®L¾¹ÿòÍÊ]Eˆó’úà!0ÍïŠ ú@@5!BhºV1˜¥A¶è±¨]]TØ1µj© ݪéo÷Z¥¶Û¿»ü N¹. WÓx<*]i .o–°ZõÅñq}¤ûºoˆ}.¥ÅÔмGR@QäH„. ñgg†IMT²TŠ"7X C4±däD5D‘£J®ÜíÏÁv„Ȇù^å¼'NÒkJ"F(b& Ù;ò./|Ø!Ê=ÄAe¨Px¨*(êÂWN+µ#JQ—Îæ§£¡—šhµš“Q6.!r޵ä ¡©eŠ¡)å>eÁ¨HŽ‘sÁÐBJc‰x7À<,ÜÃ!û†w¹Á7>\ ³`dXPBÊg¯ˆD1±ÄE ц5!6B3#QTfo€–+nxèj vÛÃÏ_ŸïHyÊ—ÅX„Là‰£Ï ‚”™Œ’!©çx¨¸U“™õš’¤ì >´+ ²¶ÑƒªU2ÅH˜V1A””sS†ÌÌlld53›µ¤j)šeÐ?¡Å„ÎÅ>”ž¡ ój„ÎmVýtT àzÙ0Ñ|Tu{y{ó²œÌ0Õ¨µ¯œs1ˆsN˜Ù@T%ƈ&Æbì¦ãIûÕfÝý¸á½r2âŠSÛ÷›6%©§“ÑñbÙ¶ô?¸i¶·Í:úªZÝŒ ?š—'ó`¿ˆ”²ÍÁÑÀÐÐ8 BñÈÎÐ H¡F› M-yøË+÷d‰ÐQJ €X²5ì{øÀëÐW®TÚîý¤‡ þhNí¦‹©µ”fóÑãÓÓ±são~usÿìäÇ?:¹:¿ÙnÂ>¬9¹?úÁíËg×Wz‰/?\/ÀözBÐË7oÿçÿõÛ¯6_¼¸~tV-‹íûåz³ò®èºŽÈÇã>¤”>ÿüó˜ú¦iˆ-¥tsªªØï÷ÿü›_½üâ«×_…ÓÓÝb~}ßw׋Ù<¸@Ð bé¼pŠ ¡òåd2Ùív»ÝÞ{2³Í¦#EÛ­`W·—_¾|VÏê„iz4[4)Š.—Û·ço?zttÿñéÙñüþÉéÕ‡Õl^ÆÝn Ú 9&'¾Kgóu¨û료1Ãà SÈ2ƒ\ìç·åcʲ™yÈÂc†°"¦À{ŒÀ\V®WÓbÌÈ6m³’e»y½kºÝähîÆ6?™OÊzcŸ¬—p½ÖQmh^¨"×3HÁÔ¡y6öÈŠ Ed¾×¼:‹j IL²Æ”˲ˆ1¦À˜ÉåuR0‘Ô…$¡)ÝqÌõWID©J@ΓgBP‰)[óò™íœjDP–¾(Šd1¥4´ô[ˆPU4Eá¨`_ùèM(ãÚGIÅŒ‰ÈzëÛ–¢;z@àOŽç'ý£×Ë%ZXn›ÛMÿ“Ÿÿh×6u’W¯ßžžl×›/Ÿ1*«ïÿÞl2ýò«—}úàvyú¸\ÚãÇÕçßÿá«W¯^¿þð»ßýAUÛÖî?§(77éá}ºÚÝüóWçó œžÁt:îCÛuÁ{T…¨efc )¨Lnbãñ8Hâ£ã¢,Çãq/Áv›zZŸ=<{ùö•1ì7pùáæIñ°0žÔÓQ±}øøÑn¿Þ7·×W÷OæÕ¨îcxúÙ§˜¸Y‰v›Û+ ê™ðÀdÒ¡63Í#È|#ÍÍ[bb$ŽõÃÇoàOš‰æö "{¢Ñ¦yEpðÝ ú]ÁÄDÞ%WuQù*nB¿Ù÷Û=ì:X‡tÙ´û³O“ñÉQ9Û‡ý&¬ -®–ž¥¨ÆEM£ªC]ëAZMbd9‹€˜ˆ¾náª*ˆ‚$`¢¨D ,æ=|¢¼² A#铈™bNÝåû ¢+xƒ|šVHÅà‹·Þ ±V¥Ç.°ÁØž0é¢uA" —OœÃô T‚•‚%ZÉCÚ6í¶ª€úŠ«ªp%¤½~Ý92PP4V´„* Ll g±8@V#¢îb”±WžÕ˜MÀqÅ8fW¥¶#5o€Šœýã†FHù$µœr0€”`xõr**~ £INÚR21Õ¡ÉjÈf1óE îÎ;¸ x#Æadš(0“­Ì´FÏ8ˆfÖõFØR^µÅ¡w”#éJLFDldÖ¶‘Hˆ |+29 LBƲ£Šº$†`ƒC.˜ØÌ«1b«ÃmJ• ð…óŽ™MtD8¯kuþäädµÚDƒf³NÆÛ¾TV°éâü¸âþñéªm*瓦CUÕìˆ=Mgã‹««¢( ç¼°¡ 2!óüä˜JÑñåõUú]„±Ý[œn—›ã££}ùþ«/¿|öøÁýédúå»w݃³)éÑlv䪯šóûÓÅ;ÛxhªY­k"b¢ž˜€ • ›*¨·4%7g#˜û.CÐwü>i’":B0´}3ˆkÒ–U#+&hMò]<>SŸÎæ“?ýæO¦õnk·«óü裮é÷Ýv~t4;ƒçá*¾~øèÞÏž.Þ<ûg©\LÔfÓúúý•™­×[ØCO›q·ïã¾·Ù¨kÚ¾)…§Ÿ}öâÅË¢JU9Z.×e9~ôèÁv½íºn\ãû·ûÉ6K®¡®a<.TµíûÕmr<>¾ººI¶»wvJ4ïÚýóç·ˆð£ÏO¯®®ß_B#íb±P§½õŠv»†ã"eý“ÿ4ÆþêöjVMðèG÷ÿç³_¿›Ý~ú‹_üÿð¿owmQ´îby4žœ¿ù}iõ¤QÚ8ÍA=R‰1{= ƒDD‹DÒèbá«Úõº®q6›ÄÐÍša³Ÿ«uˆ#ò±1š$Œ˜Á-™N0¤AÀ Œ ATP0—´ðè V°.IBLQƒ˜  ­JAdÞ³)¨1ˆZð6´ÚDJCB0­ÊBc@GL  F„•sNÅ“R˜õ¦¹d%Råû|YbCY}ß<…®“ €è}a€}´.HòyŸ»JÈÒôˆÌZ°2 °HQ({òŽ8u=&‰‰¾¦4²ëÙ¥²¢¢ô "Û到N¯ëín¹I©Uq•[î×h±m%&rãI‰»°¯ê"€¨êh\M]H‚öáúâqRêjgà""`r¥Ûm÷ݾ}øôÁ÷>þøÝõû£éñÛ«ÛÊ¿ú¿þó>¶?þøiÆ?xòñÅùÅþøâþä„÷iw}S«K¡™O¦a—@b2@c pQs„ˆ‰*$FE):f_©3÷ݰYýޭɝG+w1½œYȽÀHjãÆZŒ»zVi ·á¶ÙÃíõ‡¸¹jÖÑ£n×ͧŸøÓ{‹Ù)L«éø|wõŸþîÙôqÕî˲¬«ñòfysÓÖÐѸ, _OÆî»¶ïVÛUBÚ¾ûꫯÌìñãÓºª/..š}ÿðáCKX•£˜úý~ÓïáxUE!èÏöyQËår¿ß'Y—%?úèÑÓÏ¿·¼¹Ùl6·ï™ù£J眑Vã²èû‹«¦¨üÙƒ{õxZ×u5~{sss{{B¸ÿè>½yñvRN·×ÛÙØ¯.÷ËÓË““#íºpyu+"î̽~þâdrº¾t0*A…> ³¯eÃ64 žÉ;W:WúB±HæD2Z"É<Ø +*8Kg$$PÍîhPÎËšªª)€u™Ð ,€IqvZ–ån³½¹éD{f´ï'06%'nIcÒ…g·’?~?|>ÙÎÜÂcrûõ~u³í›D®XÀ/p³Ù§ˆ©¨êÎoA%ô}¡¾ bæd– «0¾ÃâÏ`SMš¢(p–õ’6 "öÄŽ¼#‹]ÎγIžÐ9D –$™³ž)))j켈G`IQ!ŠY„01*˜ó@>ÓRó:+ •¥B‚K …iƒ’,° GW ÷àSJ–" U3FE5K1£û2*Ýp¤¢~ åýUË[þd6ìç4¿šS¨'D{Ð ª8‡äÙ;.-ÓœµšÔ™¯–²zÐ8ÇS˜ÅÌ Ï4áÃÄ:' éamÂ!C73æ€X ÐÐ @ÚÒ,áœWU`gL`ÎcJ&šç¥ù_˜ /)ˆe‰­ ÇæQ=<¡JV†ª¡X¿ÓÔÉÐD&* <ÚŽ‘ T!3‰ªU v#”Rd} ;rΧޣ‚cD…¤’’™jÞÒ@à hcR0>ܤsúßÌ’©)p‰à¨šÔ£Eu||¼˜µí~äëÛëÛËôÞdqot”@VíöõÅûÕíúÉÉÃó®£fÕ®.–°íãÙ~¿!Ô„@AiˆSŒT!— „Àh¡@öà¼a’¿¼çþçû6øÍ%d›m„” !¤Õ¾mƻʠ?;…“£Ó°_;†Íf÷Óÿ[_Œº `TUãñøÈÕ“éüd»þд|_EQúé´ZLMÓP×ufæ½ßîw77Rðäþ¢(ŠgÏVUUÕÝڪ뜜„úØ1óÓ§÷›mYù”BŒÛç_~±X,º®vDŽ‹ªüü‡?ü‡¿ÿû›å²í€H&#dtIå“ï}º8iþø‡7*0Ÿuutt ··×WWWMc£é(„°^Ãû÷ïUáh~ŒÅòû·Ëõªmg'uLíóç«/~¿ZÔàu“‚E͛âòÝ×ÜÁ "@b`v@˘RPtLjÉr! ¹¦a@ 0 =ÔÞ.ÆÚ=8+æÓùbŒ¤ Òì6Ín‡LCµ4 Œ˜x¨°iúç¿[ÞÀÙ¨¼7FÏݶÕzY¬¦õ¹CWOÆ“£Q9›”£n<eÛ^̱ÝJ€z!Fç ÈBûúÊ? ‡³J$)›$3F—õÈ–AÅÄ”ˆ <fÎùªð½¦^%¨%05C&d$éc¡Pœù¢$I1 0¿ÈDÖàÀ`TÃtRÔ‹1ÏÐ|ÐÂÈ ¡ö½¦$…óàPnA2‹" ;TB1Õ¤ßrõÌkdô/æ+`¦)šH fI €MÙt䊊B‰ bž•šñðé¶¡PU³»'zîi ˜å_«™ æ5/TCTU4`DG™k„â€b6Íâðw¹­fƒBK¬(4´ÇahqÚ@,ßQ‘†>1bÒ4äÑ0/äÂRuà°É’÷;ò ÙÁ ¢ À]Qúº&#ÈHĨÝnÀ©°‚© ˆI*‹p¡ IDAT¢ÒäRŠDCPH”˜M˜sµA )ˆEQ )Df#GŒ.³X!‰Ü} 5§Ú@“´m4AÓ®—«‹óòv¹”?ÿì …ÇÕ4õºn¶]ì,X¿ëùÄ…&ì®¶°m‰½q }p̘0’%QM–Iûç8`$DpÎ!;@¶ÿ—žûWò¯¿ðí=!!) ˆ(ˆìSRLÍb^ôŸ}ÿãï}òh}óAf}³mÆ“ÅŇÛÕ®ÛwÚi¿i/OîŸ}ôäÓgÏ_"l›m»ƒ³ÓÊW^wz{{½ïÀûÍdV6}_áóÏ?þ›ÿËzÄ£ÑUµW¯ÞlÖi>/B¯®®¦Óéd2a¢Ñ¨^WÅ矞RxþüùË—ï¢JY–yãy· ×W·?þ1ñf£u š`¹NOONïÍæ²Yïq·Ûõ«åjµ ¡‹QÙãéi½ÝnCÇÇœR*KŸRÚoƒ2°×³ÓãzVm÷TžugGGÀ´˜.?lÈÝô RT-¼“¾}pRÌû! +9ç½ó.Qß÷*ÑL%—7*|›,¯ƒ‹¨”PcèÀꢪ«Ùl2®ëë›"© $rŒEÖ¬j€J`VCfg+8h¶pÑÃͦWÃd Ð!ìö[p×âPæóðè^UZY—•Ìg²Ûh«A‚U@yËÀ"2#"KŒª†h†îX¸ö5%LUU£¥€œwÔ“Š˜DI)¹ÁÛîØ³+|Û5½J¯™Œ¤ÆˆÈ¢F ’’JH1¿g€ ALÀă1À¬„ñ¸,§•Œ-yU§ˆ’1gÑ¢¨Ð¦´"`FˆÎ’~ãn‹@€4ÃíXˆAÀ`žU™;A1‘cïÑûÞ°%ôŽ‚j@5de02r¨‰²ŠÕPÔ©VD&R"ÄÕƒb°|*˜£©A<{eÌÜ d%bç–eÕ·ÍÅùÅru³\ßLgõÏÿÍ¿yóöUYú³“{»›Ýv¿=ºwüô£Ïþ§?ü§wvÞùmw¹Õ«öaµ&ëË'nì E²û5[ y‡ù„¦†wš¦¬oÑÿžûwåö0G¡2QÐÀR˜Oщش1¹‚«u³ëþöïþoïF÷î?yüøÓ&Äw×®x齿ÿpzz|ž?ûòÝùf½Ú@¡¨Ê<â©ªŠ®kvûN&óÙx:•´©ëz³oÞ½Ù¬ÒÉI ¦MÓ§?þéOÏ<¸Y®Ï/>³ó^À¤Ç¨ÐÅ@®øþÃÿx}{ƒˆ ¦*¿ø›¿99:zóúíååõd2éºnµZ­wë¶UfH ê±ûÙÏ~öÇçÏTÓƒ>|ø`f——7Ÿ|üxÛ]ly ¢ÙlñäÉVSIâ.6Û]ŒIH o C8çˆHUSJ¦‹ )3{€bIaˆp)dê·h4øÖXÎë~¿†¦…qµ8:ê>´ïÞ¼ ]–@É;'œ’@4àŠÊK±“ à ȃ0žC¿¦(qœvQš-ÁÖâ„Ò ©me{ÝGŽ 8›MÛ½E‹ý®OÊì æR˜á`%˪¼÷>dãÀ(ˆ‰¡C²ˆ)€È7Î…Ò{íµG"fvÌàPÁ:MX44ðŠ ÐœÆqQ@JÉ£ :O1)’±@i‰PT”œ*ë¼î½ôA5$‰Fɬ`t™#p¯ 8=À Ñ ¡f¿y޴ܱVL—XVo3Òƒ¢¡1Á´ªÆeY;ÇU½Ù7Sï¶–"£–»W"j&yÄlªø aÒ]D]Ò0xx &eD#C3L†Cž“š¡Qd*x0B~cK«aáV†¥&"µ»m+Å–Éìˆ& )߆x;;1É÷7ý3šÍ×xgˆhD„44Iž7–ÌZ‘C }@,™B¾d"‘¥|-"dB€qê ÎkSFª¦¦¨¨D†4{ÀÔ2î2h[ÜÄLT‘®ooæ'“§?)F\Õµ™ŽF£ºûÑ£Åý£ã…3÷îÕ‹ÕvÕ,÷ÛËÍg¿Ç‰ßj.WoÜ{ôý{¿õÏV_¾uB ddÆ¢ Ð!¡‘å‹Hf ‘UüÅ=÷?~m±œ”ÊßÌ™ª&V8_Šùt»¸kú÷oÞñEL>{Z»bbÚvm‡P¨ð—/^±§ƒ™ZŸ$ Œ â¨@±J]“3PshY‡MÍCNœršP@˜#dƒ}Bt¦¢­åˆÍ<À¤ªÆÞ3 ¬™GÎ@SákHÞ1€%SB¦ŒEî‘f¾.d§@†j2¬kéÝïßQÂE ‘ ÁÔ€ ™Èpà“aÙRnјÐ:º“Ðä“;OO‘Ê!õˆ@ι”Ò7[‡IV¨š*dZòðã »nÜ ú$»†QÑrìM‚jÒdˆ¥¡'FEe1DE (Éb/DVùíT8šÄfæ„À4G¹±#pÄFóã0A3pe‘À (™©YLúàÉG§÷æý׿¨jVëÎß¿Ñ>J~û_~½˜ÍgÅôêõE·ÞöéÓÅñQ$»:¿Ð«ž;m—ûnÔ-iuu~YHb…³CSVH@† pØä!‘tÃÃFŠªþ¯ÜÿlØšñ&¹Kª™Za³ÉØÌnnV1J•¦3h‚=þæË—o»äàA9Ùïú›Uâno_ÝÞ®?|òé§ŸÞ\]‘­VEáERß·D4šÔ̼m¶ã1•¥¦”NOOŸ<ùx¹\öý—1Æ?>ûãr)ÇGüèÑ£ÙlöâÅ‹®ƒz ݬ–\xO£D–ówËÝîž<|4™ŒCØû‹qŸ"‡v2›6ûÍjµªù|^UÕýû÷?þäÉ«W/_½9ÿç_ý·z<&¢¦éÊ2¿Ëõ¿ýýäh6Šº¸Ù¯ Àù“{Ÿ|òÉË/ž‡›ØF†j$è·Vî)%UÍð, 1Q‘I4˜eWGII$º²ÌªTb„ÜvCdï’¥ñtT×u߷˛۴߃窪SJŠÙaª$$yÁ1¶™¼íœw7±I ¤˜Ðtág t 3š%ý¶T¨2Ø… JÓmûy5-ÆI"Xtˆ š–ÀTR4"ÎêW1²j€<„<4ï® ‘SsD.í H¦c,˜È{öÞ«Y”Ô„¾'H @H ÄŠ,Ê¢…gT%¢BÌ’„Ùˆ’ZB#‹AYÀ¨€£ã Ï‹í˜:†!"‰AßMIf.É•"õ¦iÈ•3ƒ’‹`I4™É÷ºÕF¦hF*L.òTsY› $&ñQ¹*QRꣀŠ+˜*ïKƒÒó¡ÿ&xÀ©X¼”‡§`jHˆjF’™€ òõùwª–Ñ€H( †„är2ƒ@é¶?D2`O8ü'•@Ɇ>»¿ËWª¬Ùaª*""Ã*Cn,ŠBH’äN®ò3ÝÀ’Yæñgܯ©æ'³2€‚E•ÞŒ€Éa¶‚ ˆYY—"€š“GP¯‘@2@59 ðÎy F޳"1ÐêYì=˜æ3õ®‚NòÕ›·W×óù|±¨O§“r|ôôG¥ãßþ×ÿVôؼ߬.®ËÂßó ÙÈþvåÌ|ÇËwWáÔO¦{uñr·Ú0 'G̬è :3Eîc„á)«hà‘Jr% €Š‰è_ÚsÏq»oé$ 0‘3"f F2*™Àº®{óæÍòöêÁ½³ã{ŽOürÙÞ^ï/¯/Û¸ÊGäBŸ>ýÈ·»øìÙZ¢>}út>ªêbþWföþòýííuJ꽟LGÕ¸Úï÷óYµÝnùË_î÷{úë_?g–O>9:=9Y.—<žL§SçÚÛU:{\Ü® ï¯œˆP×¶«ø‡Õ«ããj¹„£#¸ÿð3w¡ŸÎç¨Åû·×1hÚæûŸ?ýÉO~t{{ýàÁé¯~uýý3w]7N·Ûmìàúò¦ñêCsÌVÕhVô}|þâË¿úùÏ´ ¯ÓÛ÷pÝDèC—é¿"z _ûý>O}‘‰ÍîÙ¢–¢y®ÊÒ9ˆISÒ‘YÈ€UEfv?úhµY^\¼M D~4°$µ{DFŸ p1˜¨ GÓ¨)20ƒS•®¦}¹¨ûMßíCòâ@¹ÛÅ&í}Y )°Ó„ ׼¬VmÛÎ?ÿ W…”`dFh2!²œ|!ŠB{9ðòéGT½‚™f’ZfvKF‘°ÃÒޏ—”Rê#H )Ïn !:sÀj)+#:`Ë6Ða®„œ¥è8î!6–D­íc»ƒÑÑYÉ¥Gï4b¯Ö Åh@™c¥˜ R6Jà`γGÖLƒæþ¥à3!tà$ĈØwJ/2 Ãa]8}ô µËe”$oyˆ”[äJÀ¹¨Òw­¡+jÙj‡ä,‹^†ž6è0O`ÊqûŒ™ËÊ_¡¬q%@5DBSæì$UIF$  JŒƒìŠ(jIòŽ)ˆÞñ„é0}$±tÈ!š€¢‰‚¨„ºÐ·¡g‰Ê`XG4‡è™™Csš=s& ”(iÓ\Oˆ¦!‹€D†e"ÌÁ~&ú]¨yÝ ÑýÓ“ÕòúÕ«×_>Û-棲 GÎ㉋tñþ¢*œg÷äÞù޼{×­·›Íf1;‚ÔÇmËcøpñ.¬šOOÏ`¿Af—7¯²æ>ö)"’ #x¤¹&ƒŠò;wû.½'~'s&ÄàEÑ÷­ôêJÇ ì`¾‡ÐT£ªîF¯Þ3‹ùÙÛ—o_Û'Ÿa+"€°ßïG£ñ£ÇÝë¯âñ~ðƒiUŒ»®sè4ÉÉ÷Ž?ùôÓúçzöì"Eafïß_>}ú‰+Êj4^®7¯^½ªëºé›z±ƒª.®n./.6g§±¨Ê«ëm=‚>†Ï>[,oVÓ锕¸YßæhÖvÝ}ôQ¹XÌÎÏÏëQU«ßþþݼòãqy||Ô÷íÙÙÙÍÍÍßþíßžŸ¿3„£#¸ºÚÿÇÿøË® ¿ùÍoêz¼Yî'c}ñÅõÉãR“LNæ]¿Oc|zvÿák·áû•¦´ßnïÏoߝոwü³{èl6«ª*—ðÀ䲕G4¡yo&Ûí,´8! Mvž;GªÊbéüümß÷)Æm€EQ¸²Êw:M"–PŒ€Ù¡&̾ö>õÒ¶y¬Ó]»q‹Y5GSõ$ŒÊ<­NT•É:è;,¨h] >¼zõɧ?üäñéå»›ó×W Š®4U  Â{&rIÑU¾ ,ú¨’‘œ¯ˆœä®K®ß‘)߈E Á9WZ¤Á9‰›í:ˆŽF¼É=Ö‚¹Oªê€Íl¾Xì»v½ß…(©¬Ê”¤ä"õ½šyŒfXÀøØOÆ×n×€òÈ;åýz;ù\'š'`‘°nŠFJáÐ*“’€Šy¦ ª‚ ‚# BcDF`4rXxvì1"À¸0•nÆìœ+˜ mÓ÷ ¦¥…泘&C gH wË-,"Ì3Š<›„œ‘>Ì®‡F¿e¦<;ªj͸Íy:@`æL/Èæ.3""@PS@"€ÁÀ.–<ÀìÁ#£ëb"çCŒUbd`W¦¼™#š’$±ü÷ƒ(¨*"çÀ!™syD Gƒ‘Ù‰¤Ñtb·Ëå$ß‚ªb”$9…ɨòìúvobι É{ß%!Ñ¢(A¡Ûmp2™^Þ.Rb¢Âq‚Ô«ÓD³¬Þ3‘7„S-Æb†ÌÞ±Æ !%$¸¾Y‚Ù»wïG…‹][zjÖûEU¥õ¾ûä=ïÞ­^\ï»R×z¥ÝfIA+qíõ®ž—“f³›ö)!ƒsnä]AÜÆÐJ9ê5¥$ލ*«yY]12­T 1üïkË|뱊yçàvAŸ~úñ_ÿâówï^ïé'_|ñŦi÷ûpùâ- åç?|tsss~þ~³ÙÌÊúèh¡»íþòÃq»ßìAííÛ]Jz~~þÅ—_ö½F®Ý7ÛuÚoàOÏ_O˲¼¹¹¹¾¼Çëõz:6°Ûí6Þ—u ›Íæôôô£îov›Ÿþô§GGóßþúwÏÿø• |ö½NŽâjµe爀UÕ97?ZœÆ ¯Ÿ¿ŸÖÓÑhœR¸¸¸¸¹£ÄIá'?y8?:~üøñjµ©ªQJi6ƒ¦IfcZî%ËbæÙ»>Ư¾q5Çãñõû몂ý~'ð"r‘»4äð¬=Ðöp`\áP¦’¦ÌÔÍÒÔ<55%P±U&‡pÛ †ˆM¥«Jöà$Dñ+[Ó¶T•ãéÈWeÓôûØ™E캞ѡ:° ÒDe!¡¦iKߢçÉ|šz“„!DbR˜„IAID òþ¢æ‹Ñp»ÏY/»[IÍ<p¼÷̬r §!2ÁI1˜Uï C& M”†ÎxJ‰É¡sFÄàÆ@3n|h8¶š@mL¡ ÚE …AT$’Ø«u‡\†œrøÀì.§¦CˆÁ#: ®Aùm–õ~Þ¹ ±@ïrãíUd@ïÈ»ÃÁ=T±9bÀ$PÕ»Ë÷G” ×o “D%váë1f^¦»2ïCµ;—|ÓàaŸËômœu`y|2Eþl« ‡Ð¦f¥û7ϘÍí®„zgkÍó”ûÿwõhy‚BAÙ!&%«Àœwe]EƒMv]»Y­ÊÊO«Ñh6—¾iÛ=9‡ˆ€A{µ%¨F0aHb’7É ‰¨`X$"KÉLû Y er¿™I¤1õš¼°'ÖÔw›Îvi4¡CJêŒ@"b'F’CºFD„ŒLŒä‘©9VTA4Ep„%ZEX¡•€ òu(ãÿ·~{ÆÉ‚˜;Kf©¬áÝÅ›_ð÷‹Úû²èRlbTO­hḞKÓw°Zݬn§‹qèöçç~úó§Ÿ}ÿéíÕíÕ‡«ËËëÕív<®'5¼}õæÃû‹««µHLëån4©>œ^¯¶QlV–DtyÝÖûÖ30×ÀЧ8ŸÑ»··jðøÑc9ï³8Û&“’%¤íjK§'ǾtfI¢&IfVUÕÉÉÉíûM]Ôu]ˆ‘]^-Uáè÷Óéx·ßÞÜÜÔõx<oÖ»££“4I Žª÷›íXd<ž‰È—/_œ¿ýjVM=캮iºéxz~µ­«I ñ»Ú_GC0ËÆ†Ð ‚!`fÞfÿáÐÕ>x¸ ˆJn‰XÖjª€œ9å<°Dˆ@$”<"û…‹À´oÝdB•;éL{( `Ž)‚ #™š35u‚† 6ëFŠÁEáÐRR&Ñ^Uc”¾6D‡†j(àU” Õ@ÕÄÍÑx³î.ÏKƒ“Š«ÒŽ¢Ü!Žm6›}”Μ8'Ž’9fô5 A›bTµ ¢Í³ ÇTx`ðø#ö÷FÝH‚³èM-iè œ"õZ×ê8)FÀ^¥SÈ"fAJ9ßmˆf„X°Ë£‡Ä`Ð’iAè‰TÚ{*8bÏÍÄ´KT{Ô½j°¼ã`’³ˆ Hy"*Qîïç¾õaQŒ,÷ÍÑTñ_ßÉ A̲Ø/ïp œI1¯Y¬h¹ý‚y Z-èÃU#74ÊÖU# 3¤ˆÆÀš£œ–1/˜ÔL%×ã(††–ÑúÙ¿ý¼šÖeSýñųõ~=ZLÆ£ÅüØ>züƒ/¿xýòù«¶ëí‡?ú¬Ùn¿zõrys{3›oWÛÇŸLþÖ޴Dz$9Ó{ÍÜý,w‰=#·Ú›Í^H¶Ô¤†CŒ‚€aa~€>HÿGþ‡(B_$ C9îlv-]U]]••Y™û]ÏænfúàçFFVw5§©).Œ‘çžãnnö¾Ï;ÙÿË?¿ôñôôxµXEq¸_QÓ6› &›ÏçËíf»ÝNª¢®ë†étº]o./WÌ89™ÍçSföþºïû#@?úÑçWçuYM‹‰Dk¶˜MÐl¶!úív»íÐF,·?ëûv½j‚/‹EL}YúÉt2›Ý”%æóùw¾ûÝ/¾øâgOΙÜññ½ívÛ¶ý´®EãáññìÞÁe÷ì‹@Îú>]a^^_}µà¡$`2™¸b3ô=Cžêߣ*"€0ˆœ#1K#ìöo¼·°­ì‰Ìf LÞd1UI*c$lT5VRQk%9²(Ò˜n#‡–`Q-%µ˜ò4Bv³yÃ(BßMG1Ž1ó`r9-¢©‰±Há™Ôüát~üèCj7Û4Dç|jÛ1›KƘL%R³V%æõš•$[€ÌA“Á(%qAV¨x`Ù}.ÿ Ô2¯ÅĉB"|Îcÿxï»ßÿÎÕêY›º¿øÛŽÜÛï~»ðó¢Ü{óÑ·¾xòÕÍ"Þ óÙÔ9„Âæ{…¦ôägO.ίþ‹ý7=~ñø¹ª¾º´·&{S#Õ”ú0¤>}õôyÌh©”Øû:¸Éd"ÅRì­·Þêºa±^a±X‡ðЧϯ³ã¶ibîÝ;Ü+Ó0®(]\?©R¨PrÎíÏ÷V}×¶Ãv;ìíõ¬ÎS„ƒƒ=çi»ÝN§Î{ÿôéÓ‹‹Æ;¬×kIñèþÑññáþyµµ¾ºÃýùƒG§Ïâùá~¹|ÑÖ夆ôr0ß¿¹l¾é²æX—¼ð›™1»qå…ÜJx Žè¾Æ“„ç“IlÌN‘ÔL,Ì9&b3QU óiÝ·¢’ ž\R!ÏÕl¯Ó&®×[FUÖ±.eÝŠö>8ARfå,fVbuAQ 3D‰ÉƒCŽsÄÞkʳ)™¨e»f6¹‚üÈ2ßUå»'œe†÷Žiˆ}ßç5%Ó&j‚óÖW\× ©I"™±›‹Lf.É{Ç6h„ ¨¦ð…ì‡+ºiÐÊ2¨m’®M¶@up{®,h7¸dd ÞMJ‘,’% Qî±ä|\[jD`3d~ÀˆØ71`J"Äà„%še‡W„õ@Gè ‰,ŽÏ=±fpg¹:9½ÃšT5\NæÚÕïùRìz_³Î’).#ÙwÔ<Áâè IDAT­f¹M~Ÿ‘K0^=°Ý5«›YÊî{%ÀŒU3òÜ$¿Ï˜A 4N@¢¢ ”m»¨*»í-Ž]¦Wì~ÀxÇ ´¬m7gˆjáý´*gC<,«ûÓYéܳ/>žß<8”²|îÉàóUÁ¾@(à={ˆ¡“!ÿú±ëEA¥LE–:‰¤à½ •s¾W†8$%öI f¤P2Õlè 4„°è»¢šÜßßJ}cÛ—>èÈj€§ÌøËôh³#VsÄDŽØˆÕ‘9(90)D=¢Sc#e#üªTÈ_ÎzgQ ûÓ$[Ê¿{ÿo›îúþ£‡½bÑȽ¾{~±|xòÖßþèï—Û+Ñõ-ÐÝ\Þáæjèû†¡ÃôþÞüàüåµRº)¶«f™VäADÕÓéçÏž‚0ߟL§óÕj±Ún7› ‘ÆaxôøÁ‡|rv¶r†¾Çâf5•“ ]ÛJLu]±²c®Bµn‡f³:Þ6ÉÕMc‹ë›"ÔÃcç4Ç;ˆ`:­ß}÷ÝëÅML=‘ŸŸ/—ëƒýroï i6ÿù¿Ÿ(u±3Æd6qEèú>Æíééì­ÓÇ ¿ðiº¹ºzyqÜsŒüØTuÎ{çØ¹ìVt{£ìhdýЫ¾Ä.I7S³_ÒQ2É-`täuÅ0VBÉùÂ0˜Q*#E.B]U]Ûc4$W³g'ITú‚f”Èœ‘938eJì“ äØ{/"ÓзC³­'3b‚‹÷0ØÔ1H³c#¸]t‰¹pDL¨ïͬº¾ïÇÕBà=˜P¸PPAìT=sá’i¯©S¤œ¤ã~‰ Öëªóý"TqBê@¦I…z¥^\éì(¦¡äFâ¶õ(²Ù+±0ß®ìØ)öÓ«ô>a39"OÊÐs” äÆãDÔ³çÜv²ù‡AµSˆ‡1GN1eß–ú¼üæÐ¢¼›ò˜9H·Ô'3£]ƦËë÷›Ûé³ÃÆHÇ]厱€9Õl³¿ýÊó!Öd–µ¨Á2m'Ÿ)GƒR& ¨™‰Bˆ5ç  ¬_·ÕÜZ|É“‚ÀlœW ÆxtUUÌæÕrY¨MÀNôð`o½\ž¿xÖ]Ðćz:9:˜½]•^\o†®‘¤feUÁRl‡ÔµU˜˜##ïKffî͘ÈÛÈ´W…ˆ"IY…P8.Js¾Qvi‘iˆ¤ÊFJl¦0o64]{½]ÍV‹aÙ¶}?€}ÊèΜ@›Ýp™)á|Ò˜¢0¢‘_MÔkÌUJÁ\ya’ˆDYAüÿ§r§Ÿë¹Ãe1,#’€ú4Ìçðxøfñìùp½^~òÉÍõõ&vT‡ùÃ7n.1Z’áþý{_==«ÌP—U9Y\/àƒ3O&èÛv»58Lç<›ÍŽo–‹³Õš™»®kšÆ]”¾AY5>®ëºëº”P×ðUUu];™Ûm§‡ó: Ü¿w:q“§1•e™,EYÍ÷'¡ä›Í&õC]Lš¦¡q/m·Ýnq¬:ŸÏ‡Ô×u}öåúæzyz:{øàMï‹aèÞ}÷ÝO>ÿäææ†™çûûÂi»ÝÄØìŸÜ3³‡_>[zæ8`H ©#°A~á ƒ™CUUÁUJ>¦”ÒWçÑl·hoG¯AÒ<·"b¦¬Ï33¨)”ywÔbgdŸ1ƒ=ç©6&ø‚Ì)“eAŒaP(ƒi) È9‚ÄžJ6†¨çˆ„¡¤ƒrp9ø+%a¦²,{M‡®ëª¢ö>˜‰¤qi Ξ}u* sιàù0†Òåðd"Æ6X–eAEû¾OÉ3Ç:@CæãÀ ¨ hêR æa€ˆ*´n°˜Œ`R0öfØ?Ú÷{“&De§æMÄ’¡'TÎÊj^”³"¤¸6ƒï™#¥$êLŒÔL j$Ycš÷!…¹±wfΑ#òìaI"–4[:™ˆ)¡ôÞgŒ™Û Ú $ ˆ*½hs[œggc"ÄÌÿ"5›ùªÊ¯0òm w¤ÏcÐøØ ÜMh5O´Ç­?7 Çy6(áA»™‰S¡ ³lTËia0³”O:Îó è6ø»ŒaŒ{Íë‘[J™Ð?n^d9N$WüÓz²7Ñj­mÁ½ÄmL]»)I‹ªž–…gÚÆ´ÝnCUFÑVb(*r¬Ñ3|@v”¤”Ô¢BœQQxï4FÄFj"b}²‹i5 »R5d¤jFà1*7ƒ'I¢Ùjh…iãÓ³³Rvˆ=˜Ì˜ª!¡‰Ä°àXá„L b9\=OÕ,Ë–<³'sIIÔâ€ÏPúO«Üoƒ´òOiÇ '"cÇ ËÙöøÁ£M¼ù³?ý@ Ëöÿ³“éd¡Êýf¹š>0Š—77ß8}øÆalõÅ‹eð¾ª*ó¾èº.Ũ{ªæðcÛmxƒÅf=±÷‰{û³wÞy‡?ûé§Þû½½¹™Ò|ŠÙ´ò&“é—_®j¦½Ù¼µæåË›Y]þëÿö{d¼\_/‹.vë5æ¢ ÛèËæèÞ^Š0M) eY:˜3u‡{§ÇG×çgkÜ;ï¼ãC¹\®OOO~üÁ//žOŽ÷ªªbÓÕjYÌüÛÞJ]s½¼>x|Ü¥.ÔÅ|¿º>ë9Xî4ó.ŸmlЊô€†P”ÅÔxÌ¢¦äƒ#¾•N2ÝyHŽœ`Õl×uÈø0‹©YfÃfì½™Œô¦À!Þ“_]_EÍÞÇ~PB …l׸ï¼ôI†X…‚=7íÆrNHI{3‚ˆ¨€)&Ó”ÀTLêÉ´ 4ݨi3H(Ù1Ô2ÇAØ;SD3ÇpÞØ#ŠT)#¹5Ó` ÁÔœXŠIbvD;‚Ùt^ITÊ6>1OTÔÎÏÊFcRQ‡sfÊ™î•"^PÔs_•Ãm  q«m éŠT€\ØGX *Ò t FÉÈÝ-3TF,œ9#§êˆàó‰ImŒodfo`#1ç“«LŠmÕÖ‚X¢3Ä„„Ä"f&–ä–':vÆ~µŽ˜®[Îæm`zm”ºs±îÆô¦jã7ò˜ƒ± œësˆ’ŒyÆp”1FPÁåÕ¦Jœí¥vk­ódLw+ˆež%™é.:~¾|±­üþåóŃÃûoœœl‹ÕO¯^ô-ÞýÖþãwßmczÿo>›–||ròâÅÙÑÑÑïþÖ>ûüó—ç/™ùìòfÛãñ©{óí7oÖW?û%¶îÑdRïíí½ñÆC®7‹§OŸ~ø“ÎÏ_îÏ'Ë ªÂ~ý[oA°º±àÒÁÞ±ç%yvñÕr¹¼h/:“7ß=÷f\^7‡÷¹¬Ëív;S9 o>~çæjQùzöââì«æã¾èº®m»ýùñýG÷o«¯ÎŸ?|üà|qöñ?»w”$Æ‹ç‹ùé´*ÜW_}ùøá½ãû'Å44ÚÔ®÷g7?6-àaÏñ”ØYJQ…UBÛˆf‰Ÿ‰i„ó4™TEá% ];Ä(•˜ÙU€A3³Ôë0¸²ÎóWr€æ,RfC¦¸UYUIL'ƒ°£²ò€vqe€FÊ”bíJïy{½ˆýà§s®‘'"vDD²«ß#Æ6„Ò —¢Jß%&çÜtº·–fèÓ m¨&\XêÛ$)T5È5É’F¼“¤C’-•~Ým‚ˆJœ’+ÚtPϯ»Õ&A X‰n0t³é@ŠE|%Òv¹br…ÓAaf¥c©oJO¥ÚD0Ÿcï¸÷ªÕ!5ÞÚ…úÞQï¬×d‰ Lft4 Ó^º—K×È´àå•J_"‰&10˜àˆŒU`‘ŒÌJ1'ê žP°ó &¦AÁêH I¡],¼¯|18gCOpÁ¨ªU!µÛêf‘ O>uq2©Xs ž’á•iDx¶¼ŽÞƦ[æúëB2ä³Ta·lbd_«"ÇÛQÊcwf'ò|{&HyfŠŒ;M#œ IG½ ™c΢¢1\†Ä”ÍÐ'Ûí>#yÇ1åBùìþ`QS‘*x1‰¬=Ѹ›¨å q zµ¾ºÚv꒸χŽþùõãùìp2_ŠCÔØ…éô°8j/–GåÁŠy%§oܺ³³››êèÁU/â¢;|xªë­/êm?X"2Êbœ‰Ú ¢˜dì#šf_µØ i†|3›Áœgòb–T”ª¦ÓHɃEòld×ËeRD¼ñîÿò_ÿ7OŸ~ùGô÷½M± Åo<*CøôgŸ¾üê97Ñôìѽû÷OOO>8a‹ý¶¹Z´Ž˜ !¸³ëæýÞïû6‘Ì‹Es½^§ã{õáqx÷½w¼÷?ùô'«íæ_ý«ÿú·¾ûƒÿóÿø¿>ùð'}ƒàðùgO°‘§ëëÅùõËÅV]u±?ŸÏöJfuuÓH[HÒ5ÝtVS !õ«v-íòò<"ŃÃév¹ÝU{Œ;Íf’y’L²aަšjÊH))¦aˆCzŒ:„‘¯KÑ¥>‡ìÙH(4˜J¾0AQ¡ ¾lÛv³\‡eø©&»ÕmC2`ö^U)ƒ½Gž çn’03!÷¢‰3)‹‘U_U)fI„ˆªqè# SáØ˜À<³cX4e¿ Þ®áf¾˜¹IRJD€‡2™3*¼÷ì Þ"9ÑQH´c0ÔF=·ŠJæR¥ ¨'ð{Ké“ *z‡Ò™Ê“©?˜†êF¤³¦MU ÊP¢hÆäÙ•ËÆ ÕœPëì@Þ˜Q¤'”)%X$IÞ“!¼‘©qbS$KS°q¦- «äE™GbƒR†å+åh„ $;ôvyXFcc$“Ëeˆcl)íNŠ\Í11HÇFŒ³à`ÈéO:þ‰rŠÃt÷ÕT”À¦bÆfb`S1e‰×ø:bì‚Æî*ól7ÃM$:V@:ŽYÀ0c iÓ‹¦‰C±+kOHÆÖ1=½Ø\¸XΪ8©ÊPµÍf³”¶Ûélúƃ“VÉ”µ Óý«íjv´ÿòú¦žÍ×›ÖS¨¦SIÕ’¡SK¨Ú‹{ÀزžuÓ$–$9ÝýÆÄ¦yk4sÈåœ%#Ía×€B³ÒÉùI"3£²¢-WNɲ?Ù¼‚½Â+8Óå¡J“sĨ}sÏ]í›´1ü ¶±¿v÷“@ŒhšæáÃïû%NŽ_®š”Rº8Óáèpñùùû³YQmonn>ýôÓnÛNû¶ë‡öøäÐÈÞÿ^œ½œN+ƒéÙ™hÔ·½U†âÿýþèÙ}÷mkúîø˜ _nV›ÅÕÂuYÄrèÛlšÙ¤.|Ù¬›åbmf›•%ÝÎÞ*ß{ç­Â?ë¶›óóM2¤8ø̘M¦Äv|x<ŸÏcŒ7««Åõò£rqv¾^‚ “IYxWUÕj³öì–7W0}p¿2ØÍÍMí‹aèëÖ ”¥÷dN÷öCpD4´]UUó‡ÏŽoÖgÖ·Ý/Ç?ØÈ³ÎÒ²Ü2§,Q·ÓM £¤x”Id;³#6Œ}u1SdžU&{“#!o!v]ß`hÝt>FEd)ïÈ3dU‘˜Â”¼ƒ°Œ0W"ÇÌŽˆ$ÉmvŒ° Í‹1æ4µªš&µ£Ähä÷"†>Q;6˜S%Sˆ Rw±s9ÚÌy8ïýt:U)%ç LQÇó>RŽæ™L¬QÍIÙfÌyœ˜—}c­Œ+7AqÊÓÚï{¢}?ãBäp 悉b¯}‡6W»PbQ¥À23†‘!G¨8£@ðç‰Á4¹IoÛ%³Œ AÒŒDãÜxÍž±k·kØm$6^‰]oOñ@¶Œffñ¨—…Âr‘~À°K\gðöµævV&¾Šä6cÚY†TÚ•:&ù™Ú¤ü¹×±Ù¯6 'e4ÏÑîÛi,_ ö³×œYf¢¤yש ß –ÖÍz¹Yú®©S …çɬœLK‘þrÛHj&¤¨Š4Ÿ–GÓ¸èºM¿Ùnжۧ›ž6Óƒ½éɾ tGKbÉnÿè`6Ý??¿V&bGÎ9ÛÕ&DÊá•cÞ½ ›2åD爳M“ InEÕH Ò(ÊD~÷Ø#Ï h\áwf°qÞ­fžh”Œ¡Èœ¿•¼§"0ÿú7vÜ w+ÌÝí%’˜A„”FM3œsçg—«Ë¾Oû³Y(g/Žî½ýö›—O_ÆÐ÷]ÓN&¾m‡?üèøàÀ~ñT¶ÛóyiDgg—« ?.EôþÃ7 öɇOþçÿé‰ë›ô­·Ýz•È!õéóŸ}¹Z,ú¡?Ü;èºîÛï=øêÙÓåÍ*µ½«\^^ñ»onÛþÁéÑáÁÞWÏtÓlªo¼õ@$Ü?=;{cl6Û·HL]l+\¼¼yïwŽofËó¯Ppïø3{Ï“I½]lã{GG7›U"{N*µ›3{ï|íº®‹É¦ÇUÕ$õ´|üøñÓÍËí2yþÆÅýŽfüô—á¸Þ+3«îàÌ9D8Ó7<± H%¦¼ÀÈà8ûæªjZUUJ©i6’D<™ŒÕ¿©ìžø‘—%ÇQÅ1³0iJðŽsTcB#Q³œÖEÌš¹qf0K’vÙG¦’4Â9—ÃÒî„>ߎԘYÉò`8dyœZv¼O&“õâ*¥Ä€5 4wû•3¡ÑÓ ³‘y™[ºN²"ê|o\€gp§ÁÝs6I¢fàmAN›A[ .0 ®¬Ýjld葳¾…8‘xB\e3ʘÕàÈ;%ÏÎ9ÇÄK"à‘0Š÷sДsyX)2FŽNofRÉ£‚ ›Ú/R4¾~ò~Íáü*Qãµbîôß¿¶²ßºD;R¼èí{©âVyc#~¹?“uôÿÈ+°ÓßÃ^ïÿ|ÛàöRÄüG»+Æ õ…7gõIºÂtJ|D®¸.<%ÇÀt*É/Ù9vaR qhÒª`aâŸonü~øÁïü°[Û‹WÅÁüÙùù[‡óg/Ï‹²^nÑz£" >sjèúòrÜö²A׌Ó\G¼šÏ²ZÞ aؽòYZH¬yæl§P"+à˜Ø‚Oâ‘Å#‹ÈF° Ù(íb÷ä—Äìñ/fȰ˜å ½½è ˆÀ{xïRUÁ{*Ëúêêær¹X\cÿ¨+뽂HÜn·WWì°Ù¬ÚV¿ýÖã›ÍõÙÅöôØ‘“½Ct®ýþ¾{ôèÞÉ0ˆÈ“ϳçßÿþwŽ.//ž<ù<´—ƒ½™(šu{q~usÕOçt°·ß6]ù Šõ-RÛjÉL"Ž÷Ú¾;=9üÍßøÞñÉÉÅË«Õzyï_þ›óß½õÎÛú§úôùÓ£ý£.‹ÅúðdþîÛGªº¹Y.o6›%æs”¥»8{ ÇEYì5ýæüfuyy™LëºfcÏôèíG~꾺zÆìêªzþòEY¡à‚bhÛþËå—/ob”é´ìÛþ›λ©¼»ÎÞû,Izõ dÍ@˜œwΑ#ɼªŠ¤lÆ4Ãt½gçˆ|QÞL†¡“¡˜CÎ íÛjY뜓≠P¼IÄ“ƒ1gÊ’Ûí@“T‰YÇÍaž'B?´uÅ!¸!ƒª%ÇL…×ìÀW¡`&ï‚çж sÎ’P§æA\8oª]×õIQŒ×ÁsžÅn­ÿYW– PK–ehTX«98Ž1”à=Щ“cKe#ëÆõ)õ¶ôÃM´ÓNæ{ÓrªnÓ¤¡‘ÔB#T‘aƒ „Üí‚Bmô9BÁìD<#8Wx ŠF•CîKykd1㱌½»Ðj¶.“ÍqÜpL·™N¯ÍKíUQ¿»Mè•<†oôôõeýŽýßD<.ÇDÆãbf(ÞÖﶃ íÿlNR¼ö Â×ã­7Ûî‚ ïîO 30 Î:V¦7ª” ”u8(ÂNC1aR×Û5 ŠÉ4mdHÎÏæÓë§_vÝ¢2å$„‰G°b¢åôåWOÏ7W¡ªOß<-çó­ÆÕºYm–u5UsÑ(Yê£uÑZÓ(I5C0MaªQaFl@JJDJ 숩¥”TbAîŽf9ŽMÍÈ,‘E' ÙÁ«fŽ˜,Ë…ó§ %˜³©Á”IóŒ‚Ø"l€&UQñD¿Ò@u“{Ç•Š;œ‰ñ»,óÜ-F9Ø?ˆEXumZ­6‹Ew3tÛ›5G­ª0tq²µU†gg“ÉlVÕµöý’¬Ö‹ªœÔuý[¿5ùì³ó§_~ù­÷Þ»tRùpqqÑ ±¬fW7«ÅvHƒV Ó´˜Ô勯^v[OèÛ¤D(}qxxxvñòÏþìO¦Óé_<÷9}é/þüÏ›¦ùâgŸ?{¾,< £ûoüÿãÿÁ?þßþ×ÿýÉÏŠ7û:ÔËåÚ‡ÂyR‰ûóNZsL–dÓ·®p\–e]׳y=™!`6›\\\øŢI\ßǾG¨¾ñ„”R‘[ÂŒªæ¬s$¢–’ÝLrÕDLÌcÿ¦f""8òRIAìyÏ>ðtoÖ4Íjµ¶!qUVU%b}×Aƺ–˜c0Ó¶ÀEQ¤4(Ì{ï‹" C¨Ê$f@2e9†c3•»̼û¼Ñäg\â EQEY…~×"(ŠÂ¹æUœ$–¤’’0„5¥Á¹¤”ê 0 åtRw]×tŒIU½çÒ—QÌ©Š·ä.o6b9ió ‚ˆ c¦`V&§÷C»juèªh^'©·fˆN0 ~VAb·YÇM´Ö,åIDÎéÛѵ‘=KêsÌT1“ƒ Žœsf6>å†AUˆ¼™£6àö¹sÎeÚWN´ ]ÅmÇ RÃ/9uç† Ýu—@¬¤¶kÈüâeýN¯¹<Ì%¹ZÞkî4îoëú±‹k;oÒÏ¿ææ ßùJæKš¾Ö°ožõ}(7nlp ,#VBÔd¾ÓY}¤ü ”o¸jJjœ“®·±O®Ki›¢«R¤$™Oü~’ayÕwÛj6¿ºiÿøßþ{.];ôëÅÙÃ7ßZ,.OŸ4Ož×RÔ”„z£ÖЭ©$I5Jê-šZÆN$£6M‰8S6É^q"x¤ãäëÌäT@i”£R‚ D˜SÞÒFØÈ.Ü„Ì @™ÂîÔ à:(’ªè?‰-s§-¦_kΤ$œc3ë;»8¿::­Œ©ªB28çæó`ƒ2c6Ÿ”ì×v}{yy©¤ï½wx}}suÕ”x¤ýißG‡VÓpyÙv 6ËÕâêzRÕç/ÏŸ=;+‚Û?.H‰&ÕdRaµjÒ€b¯j7ÍÑAùøÁc•xqv¾n{G ÃlR}tÕ®VíƒËàqxt†Åf…—¸<9ùª åéÉäâe3æslV›?úD{;˜Ð[«Í*öM²bsrrÄÁ‹¥¾oOŠ*¼¼¼0²®ëT•Tž={¶×L÷ïï×µO±yøàt:­Ÿ¬ž˜è|oºZ§º®ºÐo·ý7µeÆnvþϘÙȘY"’rœ'™fpùsQQÉH\QQKÄ£‹dg‡Wv.Ãcìmè.ÊPVEÛtèûQDÌÇcÌgVIRØ¢™…PÃ1E(™²"öÎÖ'•˜ïZb&ïÌÌ$æHç4% ¾ª*Ç¡ë© .óW qk‚$Í8Hff2gðàà|Š4 Fð'&arÁ1¶¶ƒÄ¾â\aÄØ²±c²”¡­@ ›ÅÞ¾w zºY¿M©ŠþÁìÞfh²¶d*¡Øöë³–šJ{æäœåÐR˜­UfÊY—ó͉=SA†lÄÊYáªjÅ"QÊ©MpD䙼£Â1;ƒγI>òh&û“ëº8ËÃý¹ÚöUÏ}W’¿J2åV»©Y^c²þ–_hv§ðW@²Æd2Y€m;Ùå ÝW²Däë¯ Ð]¡ãŒä•eoœ£ÒØdÿzOÉÆˆÂüð#¼ž&9Ý“”œ9gÁ´4›™Õ„Él~®ééÍv³iÖjbºÜžºâhŠ·êÉêåÕu“ÕÞ…‹U|ð›æ%µÏž~qñÕjÛ¼ùð-Wñ°éX…RºMÄñµ Êh—Á«$YRší'L ñˆU¦Œ¡v° E¦Û“SÎèÊ’'Á«åaŠ,ÿ(0•`'@Ø¢ê ( …ã‚(;ÎßiÑÛ@6˜(ÔC…þMj!rx½xÏѹÜyTÙìp.«“Ú IDAT}¹<QÞŸO'{b:©¦N¢"ɼš²š¥¡úþÑ[ÿÅõûüñßÿåßìm·Û”ä×ý×ã7~c½Xÿñÿñ|ÎÞëùKû“ûï¾óoœ z•ÍrSO¦!Š"ØlšÔ§½ÙüÑ£Gßûö¯oVkJŠtØüÞïþ³˜Ú/¾ü’™ÏÏ“÷‹é„=:¸¾^\œèñƒ‡–žå¶æÇ>}púþþ|ïù³«õó î?80³d1}5©]àýýý¦k//·ó=ÇÌÓ½=0ž½XlºÍƒwî«ö—×—çö÷öxëÕ꣮º&U=hÔ”¾ ?à½÷Þ‡”¼SŽ 8çbAf955ÇF™'# Q5â<‹Ù.§gç_¯—)%*Š»ð.“É9GîÕœ<ÆLÚ÷b]ì"tÈ9UH DŽÊèöјIÞ9…I†Õ1ÏjIDªªÊ4…AU5­W+æÂ»šP†à$çæ™<95r9 ÛÌ™æëÊÂ{8‚Ä–3‹ý˜òÒîaFŽ1RJI•\öz‘Ø`ϰ²âjÏ뉷#ëªØoQ‰Ÿó4Yãļ¢Í]Q ±‹ÐÞ Dæx¬GG1Ã8iÖ‡L;gidй¤Ä #çÈ@ÄŽ]³Ê…Ò9²!²9ˆêv²}·¾Í»©+ ºë¥+à«#ö]( €”eì»7ÿÍw„ÚÏ/ëù+IAÍP¢|78¢]RÛÝ5Ýîã~É«½þà3žùÎ@Õ¾iQ‚e5Áø[z@ $ã¤FU’ OÈaÛlÊÙ|^TšÖ±“ro:¯f…Ò£ùüXÚïß;Ý ø»võìyF†½½É³g«ºÆÞ^R¼ÿô­Ço¼ÿþ?|þùùáa±7Ãv;|òÉO«ªÚ›Oٻ˫•RJ“éôòò²ï‡õ޶uÎUUñáû_¬V+"šÍ&eYí¿ùæŸ}öÅÍJ=(¶ípyiëõMYáÙ³ëßüÍoýà?ˆQnnn®¯—Þã£>º~èðè~øç¿÷»=úÉ'ŸüÝßýèà`ï·û‡_|ùäãÒÇáôþìæzC¡Šêì½_»wµºø›¿ý‡·¿u|xtb$èéñéú¢Y6˧ó¦°ÕE4¥ñ2ã5éWžªIŽ%+ËrÛwQÚz^§”8ï½cCŸÓ„`f]ÛÇ(¸ƒCÈäîì !°§¾ïÇz‘3oV+v…+‚÷.¥ÔÅîYu»$eœCR¤4¨„*1UuttÔtq³nˆB³ŠìOýšÜm'¬ù/l7•ƒÙ×ÍM¯ÍÞ,£d_a ¾)…ó?Ö¹£gÔd>šàV” Üò®_qþÁy¨1*sw™ÃPM1õš¢c*½/È1LÌÎo®Ru2Ý?8*fKÈz±Ú+&´0‘ë…[oðÖ»/þ«¯®''Õ?üô³·O¾÷æ;o~wè>ýèÓùzU»r^WýbêMÖM‰Ä Ñiî·[Îd…RRSM9Ãd÷™ä(b‚Q¶mÝnf¦2¦Ò˜¹ŒÎw.©%SOˆ€:2GxU'ÆIª¢j«ÂªžA»êAš^!jj°_=¬ãn Aÿø'¼^Ë‹ç®òªX,VÛíÖº¶bÿüùW)‡CŒ_~ùbÝv‹ÅÂó߯ëêåË—ø‡¸7ŸŸŸfÒÀf¶Ù´eéOöNþËï~ÿfµüè£Ú¾%Â|orxä¿óoþÙÏ>ÿü³írñä‹'lŽº®{òä‹?øƒ?ضkçð»¿ûkßûÞ÷üÁmûÙéé̇r³iú¾òäÉË—/‡a( 7©êõjã­xü úá¸i7—Wçǧ{³Ùìfy¹Üܼ8»i¼û­“ù¾®¶Í¶múd䩪*?¡I]æàP†R¢ªªs*ÍzÛ¶(}e)Ú7l®w3¯ÚŽYvlIDvVU"Âd>5#‰1"ŸÚ!0É8õÞ³ÙËc„÷`vιJODæ=ì}Ö«$½í%vÎYDäiÇw^Í *d’’IŽÛ4˜Å¾ÏB0"RÉGLfï™,à fÞùšÄ¦íá&“r2ÆÁ¶ÛÎ’ùºN)‚D"ÉTäˆU%YL£Â¢$i4‘Ñ\3S&&‡ÌZ1UEL*ÂHŽ=‘0ÌÙ;ÕЏ!tÂ}¢Cìûîðð0¦Ô÷†!ø²m»½½ò½÷~íøøðoþæo>ûì«É„9¸Å:¶mÁ½{8>8îº.%%Ç¿ýÏ~ûææfÛn...bŒÕ´xôèÑïÿþ¿xãñÃÿðþýruU–\8ßµC×·›-nÖëÉŒëÙäèÞÉáñq]×)a½ÝÀf^o×tE"1¥÷Û¤ˆíÒÞ~»øßù«››?zÿzqQÖÕb³Ü Ír¹ \…élÖõC߃ÔÖ ªÙv~0d¹\ö‰Oîí·Ûæ`ï°º7uq-ëfá¢ÊÐIWº_ÖsÏ<[%ͼ%‘‘ù1Ö2cŽ9ç겆!¥ÁnÅ‘ìˆÉ†(v΅›ißÇÔ÷®®òºszòÍÉÎÞ§±KofÖ÷ý˜UOÞ5v-IÊúå˜È˜‰É±´íüxU…œ !@‰U,†¡BÎ3s¹7ï{‰©¯y gÛ(¹2öâ™À$i8°3±Wé;zÈàÈÈyvìˆÉoc¯&¦€ƒ Ž )YLJT’J$³à„X™,T }“=ÙúîªYõ=\m°]Æ‹Ë &{ao^̘µÓ´¶´²¶M"™…C0KªŽ ªeYFÀÌJ1†k܉ÜþÇ_™6óÕ¹ð5^žÝ•oØ. û”í·MÑÍdÎŒ€4εÁÊ”i£,έ½ ”ntˆè^ ÝBt`0¬cúìùå·êâñáÑÑý·6/.×V«írqÕ®š iã·ßyï;ï|[NÚZ¨Fø‡¿øûœ ƒi’¤ªbÆ#‘Áx*>f¬ŽSO ¯éN3"ÿµi6aŒ"gòã¸[ !Ê(º¤êaæ‰q'J¦>Ÿ“±¼!$e2GLÌÿ)Ã:~qïØc½ÄÁ‰MÊÐlZß»·º¾Z\¯Ž÷&àùó Ĉ뫭s( Ÿ"./®³Ø¦ë’îíqŒ8:Á|>!l¶Ûóó.ÌæúgâC¸Y\$êYå=?}öÅ¿ûó?‰]ÿé§×eÀþB))Ž*ƒôJèûþ“O>9{y~³\„Ë%~ç·Ma‹Å¢m[ÜЦSO¨*¼õæ;õlúÁüýÔ ˜ÚæŸÿÞïÓ_ýÕ_íMBYM8øÇo½ùømº\\œ_ŸÜ¿·w0é‡Í2ÞŸïç÷/_,^¼xñìË.v˜Ô¥³ãæ—\Õ\‰+EU…jŒÑ½ ZR‚²#ïœs”{8#üÝ“edè;8ç8äz9¥”’BÕ{Ÿ¡Áz#8rÄ>$Uxï™Ù’tM».³}ÇgÎ1;v©ãã—„˜C> ëuwT´ G$¨i’‘¢cÊ~öP21]]¯º¦_·«"Ô¾v©µ8´0ƒ8‹$óÊE$Æ¡‡ ‰ò|.3i2™ˆÆ VyW{A|”NdêY“Zt Wcò¸.•áPØ£Rª}=ákh¢Ö˹›Õ âU§|Ä¿ä?ÓÏÏFGEúÝבÃk_{ýe2Œ»Š:Ë­v'½öÕ3ع+‰2·òV,o ‚Â+C©ú«~µžmÛ óÿÇÛ›õX–ey^k­=œáN6ûsdDFäX•U™ÕCA7´Ä  Á_ >€Z´Ä#B‰ªèF¨(5ÝtVÔ”•™™s„‡6w:ÃÞ{­ÅÃ>×Ü<Ü#+£Èìë®+‹p3÷kvÏÙ{íµþÿßß~•ú62V!&uMLݨjѦª\†~‘b±³åaQ`ªV‡—ûOîîìÖ#i۳Ó±µ „½á6I†51Ë p?\Ó‰3ÛQŸtz"(ëõ,õ ¢îFª‚ˆ9» X%g™°2#Xƒªª¤ØçœDT%B ê„ DCdàË÷ÜåÇŠ/|( >…fÕæ4)")Ë2ÕõÕÑj¶5™_5——ðõoÞyå+Õ§¯.Û[·¶cŸŸœ¯º…s9&Fv÷M=3ó|µ­}§ª«vuöó“ÉdÜ÷Ý‹/¿ôæ›_­Ç£üàþç?>8˜ììø¤v-}/£1LgãO?=S«F÷ö i»ÏîììíWëõoþÖwŽÏÎNOæ!@ßÃt±cáÎí[‡'ǧ—§{[õØ_ÏððøáßùÝß}x|8žÎF£ÉñÉE߇³Ë _Ú¶ÓùüÊ(šBêû‹Æxûà–D™_5¨d ,;€ØOë*Æ/Ü,sRGAÉgÜ F"H –‘Ìæ3CJI„‡ú›U¼wÎ9ç¸]J TÑ—ÎÂÊÌD(‚„@ Â)¡29ë­CľïúÐ*´ÇŽŠ†œ±dMÓt™²Ì"ÈH¨*)MêQJI@Á 1’ŠÄ.Y0Àà t­lÑ®ëŠÂ!˜$œ¸·Ö°Gm# 2:xã?¬w ·”’pJÂ!¡ª)¼ª’HM0Œ%µ(½J¢ŒœtàÇ@{È3åR-X“\ÁôE×j"ägc¢K(Q¨÷Ü2ƒBaÐr cr¾$g{I}C "CžA 2)IÜ+X"Ôœ¶¤jAI’„~ÈO̱|HJd ƒOCõ1즓áóm™§“1å© ¦g~ü¹¯Äg,ï›EíÉç›0²§Ÿsm0¬eúW‹ú´4Rò×3S¦Œ)(M`–ä rBi¢rRàuL¾®·½7&ZŒ¨I™?¼¸Z?:?_Æ„î$A¨‹¶ïîp¼[RY^œ5£yííKÂÕrl T.ÆLhO¢Q†×¼K)!€æ T æõO=synt;ðZþ3œF•rÆ=¢:d2xš`÷üþá½ÿá'ðꫯܽ{÷í·ß~x¸pmKDï¼óÎåb¾îÚýýI]×W‹ùt²õñ‡G…uËå² md]4—Eí¶v`ÝÁéùIÓ­¯–W÷>ô®¬ëét2‘º®G#FÛ;³Ñ´쯖§¨éèÑ#Žb¥~þùçG6üèìÓ¾‡¶mñÅkm´†«xèÁP¶›28“[79DÇZ«ÀQ$‰U®ª±sQCÈW;“sEá YP"ðY­ 9â‡YA EbPf†>€7SŽn"HšHÄË*’D@9jФ‚O…ó Hr@Z«WŽl1‘ª&áæðQ½½3žm'ѾK‰ª# —³9½$×ïŠRŠÄB† x8€èº.·5-cH‰‘D‘}”£qÆÛ•N´ñ}½ªšh¥ÁõUhæ)‰p,ÚK— C² 5Ùt¨Q żL«(XƒYcŒ)1dVéK\‡^À+ !½–i‚:„ èDÉ>9ÕBœ«ÌO.Ü”‹÷'ªÝ,€Ùô£AŸÕ&¹™}z£f~œð‹& O>ë3ž¯+ÓÏ=ãMVÙ¦-Cá‰û¦·ö梲9½ˆ* ™{0˜B³üÓ ä*?² )€Š$UWT³q9Ž>jLT˜6›¸KÁ 0ù³UÛJó¨í..Ï›å ³íƒÝýº. •þì÷ÛùÒ“9ØÛ¥cH±—Ô)w pE%È`2VUÊ“ ÂbQŸ>‹<ã§LD€Y:“½ƒ†áhöRdªÛp–JCn2"çSC6½Y2Œ`|ùž»þ2ÿOésÉ|1JÛ¶wŸ?`iCìÆeñúë¯ÀÖVuuuº®c†Õ|=.&"3ŽËѨjQ;{Û_}ó cÌOßýù§÷ŽN¯ÛÛ“»/Ü%¼ßwj$?üËë1Ô5½öÚtwgço|ëÛ‹«ù½O>ˆ±?;;qÏÎNf³Éî~QV#2îÅ—^ ñÃË˵üè퟊ÀÞÞäßúæÎÎÎáááÖÖNìS{λ·¦ÕÈß{pf»¸ÿœOæËþŸþócªëj½êöÆ] óå"A¯ªUU©jÛ¶¾Pƒ$ªÓét9_-Îëõêsc|<¯Vý/è¹_7R‰H”Z "hÑ9g0K Ѓ,", ŒDd­ÍJÇ£2çõ”Ȉ³2_ƒ 0æÐ‹!4Æ"bîó *X  š”I$« ~…+HQò™RóQ[A´o»$¬bi“KÖ:2… ²$ì( ÷Ðu-Ú²š¦ëC¼Ñ( j­5Æäî“ö] ‚a’k!9 ±¥%, ”V…É85vÙ¶‰“æPaC0ªq÷`6{n²Øk‹1ÕÖ8I`XÀ˜Q±´¶VÀ sJÝĈGêÐdÏ®1†E9&k- KŠ¢ˆe7©–Ö×£I`Y·*™Ä#8gf[“ñt8\\¯].×§§ùâó»óÕºëaoϼÿîÚßüê×^{íÍ{Ÿ~BPÂËË«¦‹yÓG>½8ß¹µ_ÏFͲßÚŸ’ÅjT¾ñõ»G'‡ËUxù•»`àŸýóG·nÁhR~z?”ãË® жítg|û¹]æpyuT”X–n2Ý^]Î'å¤AyðhÙ\÷À.ç—ÖÐ&%¿óyº˜Ñ§ÈÉ X„ @cÀë ['…óD ÌwˆˆÄ I!H¦ß¨rJBˆ1‚* ÉI«b(hG  œô²ÆGˆcŠ’ÀKÌ@ïkºG°AÈcœñB)(¬ÛÁXK9Ù’ZGEQú,QUüÔ Â[·v®.ç‹ó<8˜ŒgIC»n! V3M †Ë•k¯ÊÆ`]dg5¨+GȤ@)TÎ’ PbƒàŒ#W¦Ðó†/#Ô€™ ß/»IZÛØvи°ŒÍº mï MŒß1eSZwÝ’û¦ådŒ+d­!B‹hPKJ`‰H’˜RBU‹F@#‹–ª*®›&E´H#39#Â$l,`aŒ³…'²Þ‚$1Ð+tF­JN96BFÐ ‘j.س)®}ü7Úñׯ¢gõ[ð™=ßÏkQ?Ë/¦ÚÈë¸á‹$Ñ_‰O»ao&»Þ\ÙŸŽó~âÛC `Œ%0±IˆBÒEá6±¡¶ÕA=m v]ÛjÎVŸž5ËU㷦䭴2©©(ª½\µóåÎÛ{v|g'åx’²aÛX6Ö©‹‚½Þ‹ áT‹ÄÏNO z2"ø~73âJÈ H×Yæ¨n £¹Œe¼æ&©(2`NÓÈ4`EøBäïõÜ¿è ”'„¯rc¸o••5Àƒ^}ýE2úþ<¨ŠÉîduµ¼txkoÏWÕ×ßxí§)†¶uB×ïìÔ‹U³3ïMÆ?üÓ·>~÷=íôËeϯ®îÜIýýù¼ã˜nßžüüçË;·é»ßýÎx<þŸþÇÿÙ¼ôÒÁÑÓÕ^|é+Û;·Þ{ï½Åbqy!Ö‚ùjñ½ïýíÛ{ŸüÁüãuÛØÂß½»óßúîÞúþÆ·«¬ÇŸ}ö¿Ì硬è7nÝp¼½=›L&ÖQšÝ½ñby:Jê<œŸœînÕß|óÛ÷>ztyühRÍE€"j XÕ Xr¡%&à„©#^8@Fô^­ ²Š"ŠA‡ ¡ï»õÊVE„#§V5KeY–eú¾oÛÔu`­óÅ&†Ôô]„Ê1t}Èo¹©=‡N‰Ð:"BH*:$ô¢Q@åŒD1ä¨t¶ï{í;PE;rÎ0³ZãR’"pNv»R;TS’sÎysu~L…wÎÍ/Œ'n<çFgg Å%TP`Ñ5M×ïL&±(æÒ8kºÐ‡Æcå<B—(Fð ¥gÍb!$èK˜:Q3{Ç÷;Qv}S‚×*¾‚îªÝ*uÝËûBQ=§# ábuÙ­{•¾*j‹LR‡›( P(H &•À¢ªFP<:oqº{pÑ·ËЉwLšcå¬7E)\Lª’È.ÛnÙ¥€Óù\ìÈ`‚qé%°aÒ^'£ZÌYšÈ:g­ ÈÍ\ºA&óØÁðD7ü:HäêD¼Ñ1ß<ç+dйƒX¤œ)ûâ$ãrÞ:!!ëÍÌÛëÂü±Õë,é lŽÞ,ûñs%ã𠙬ÝÄtd`"i+°êZ?ªf³Y³ZI·Ê25«ãÄšBÂîl:-ê1˜¿ .§wø£¿L/½øšÏ»Õó}´h ¯éêd\Õc?ާàŠ=?+Çå½Óãé w§UyÿäQ úÜë¯Ðöôѽû|tå’ˆhÌ\$&½BF…3ÔY‘„ {׉ÌÂ(ƒ«Ðä¬Í8Ñ ™ˆ`^nfŠ×ÜkÏZ© üN³%BDí£ˆ’U@ýf¨~q)@¤ÊQú¦_,ï)2ΫédTT•ôýb±8?9;¢ËË«£££UÓnïøýÛû“z´îÖ1u)ö‹ùüôøp~‘ª1ºusï“V«è1Æ|ík¯¾ñõ7îÝ¿wqñ3cÌ»ï¾Û4MÛƒèûøòË/÷}˜Ív¶·÷|v?FæºáŸ}òY¿Nó«VY,–—ýö^YÔ¦ëÃÃÃGÇÏOSea:E&OÏO´×[;{?yç§]Hm3C/¼ôbÛ‡ÅbQM|âØÀÇŸ¼×vWu†ì­ƒQ·nææÊ»jçÖÅYCyFQÅ ëêÆŽ4ëJ (R‰lˆQ(ÿª‡…Y"33£HMD`l‘Õ}ßsa0 4¸Dih¡Pîw¢pN±UT ìÖ!Ä^3)oj\‡ä "rNbŒ‘{«ˆÆ¸¬êMÀÊÀšOŽÛë­ IDAT’Z8§¤ºI–Ì«*Tu%ÙÐ’b—„‰h:-ÖP“QAŒªPx˜ÖBRQN"¬ÆZc­E¨ H`-@é¹v¥Ó[QƒT775fŠY3†¢/i­qɼè°ïœÀ ¤Xµ±^¦þ"I·‰¥Ùh!!ïyQ8’&åÊ‘2÷/W×”„#3ÉÀ_@ ULÑúLL¢†óš"‘ÑIJ¥Õ|-‚)Êl2#[>Z,ÖÇ»lÆíºYÍ֘ĿZ!ú“½ò›³Y}ïûFÂ)ü’ý›ÏCð† ~ñ”¯ûðƒ¦Á%‚ÑÄÀbX+!´ÅEVÉ{‡ê 8U…ÄËÅÅØ—Õl¶µµeªjú1ºÙd4µÔ.’7kU45ØÂgÁºeÛ%C£Ñ(Yðd<Ú»Û{'§KF@j‰))+§dŒqHY²©9Ô=“6wÏ@û$*Cî¬"dŽÌE‚›•aóßCBU¶‹È5xàXÈð9¿þÅ@ Ã*ëu;ŸÏG£Ñe]–¥±¢#šp¹dÕû·îÜ^ÞІp~ya­½œ_±ÈrµzëOþ„¬þ¥íùb±Zñövåœ;¿¼BÃQøj±ºš/g³Ù·ÿÆ›ëõú/~øáþ^é=ô+(Šâ7Þøä£O>þ𣽽½Â¹ÐuÎPéüb~yz|Ɖ‘qVÊ~okkÙ-RÁøö7ïîïßzõÕWßzë­>zðáG¶wüº ?üñŸqÒ®X5«û>-Ç®žŸúÆ“bµZµŒ+B¸µûò|~uuU—ûÛ[;óËcæœJx³)÷ô=Àù·ˆ ²HR‘ëÐ Ñ8%IÊšb¶½‘ó•÷QÇ£²Š   ‘ -0ˆV•qð"euIft Ù»‡€ &ŸO޼SD²¶ Œ 0cT‰Ð“ÉdHÌš{"Æxç…i %g 1Zr"b­ER Ø´¡(в-Wk’äª$VLhe ÈÆΉ÷Æ[ì uÖAeF†mÓ0$Ë* ’˜èj˜Œa:-¦µSê‘À*§nÕÎ{],}€Ra§˜”Iãºë®bl…”J;bëWq­$²’H 9¨2BB@CdH5ÆVcK& Ü€]¢Xg«Œb Eädf´…uëË52<çöÉñYhÛ”x\WdFkPËR9š–…ÈÌôë¿‹¯I2út[_®Ký\±lêô›˜g}?§j¿Ù|ÿ¢á1¡l ä$Ø÷ͪ!•ÆØ¢0£0rž¥ãÞÌ kf’ý»“­™«‹ ©5šîlmOTæ}X¥uˆ]‡ÅX²+ä%t‹Ë•´U*\”tÚ6®ªUÑ&ÍŽAÊ5ƒ$DÍ›¬ÞBRd³ÄpÍkF?äTn1‚ˆ"™ÈºùöõqÒÖ&[ñqÈ¢`Æâ&¾ö¯áPýr ;“RŒÖ‹µsƌǼ\¬$¤ƒí­msViºÎ8SÖEÛµg—çëÝݺ?½ÿ 1·m{~¥Ž ¨FÔ`çà½NÖ}ûýï÷»ßýí£££ÃÃþ‹ÓÉøtµº¸¸:==›Ï—÷>9ÔôÁ7¿ñ"Çè‘ËbÌ ÎûyÓ6ˆðÜsÏÝ-÷ÛÔ..šÙ¾}ýWËÊmïmÿà­?.*»nÆA`²=^<ºx÷ƒ÷ö÷÷ÿµßûþ½ûŸ]^¼ñõ×C?üáÚŠ8gvv¦m{YvÝ$Œg±ÅØ'IQˆ ùí‘M[S†,bPs=PE$P@Î(¬Ì‘Êuô0¨²"j¬ñÞyoÅ”BŠúœªfóaÑ‚µœ‚f€8¡ÌƘòõv¢|æõpÓ[kA•¨#ˆ†“‚[!²ŒÌê`†6­€0³êãùR×ôªèF…·kW=EðÁ¨ZMËÀk¥ŒªD—© H¢v6+1 ˆä󦿤mßwÂ=¤ 19pÆ[¸µ[oÍ*µi”yÓùB/“m f¨ÙšÈÒ’´À=±X§èƒ®%;fQ‰0$À¨Ê”Õ )O†Œ!¢ZM½JÊe !; ’ƒ÷Ð ’f:»Z…‰w]Ä»Ezåù»¥)ê²üd¹Ø¿óÜÙ£‡@Cv¾Nf{{\ã²4ä8ýúŽÝrceÏ'¹Ì€¤k>MŽ5R!€l°ç_ÔaßÈ?GœæÕõ ßÌÐ: òœÙd¢°`߆¦iZG¾¨k_ŽÇ6tqÙ·«®-ÌÒg˜q5š.ÎŽDq1¿‚ØoUeÑ÷‘L2N(u =ÆVW¡ï+ìzA$@}â¦K«†‹˜{8l=Ñ  ‰A”sP”…Œj¤a8ô¬ø±çvPÆ (+%‘,œ±Ãi‰„À0°RPrœTIAP‘D ÇË¿„¶LÎ""JQÚ¶­ú‚cŸŒÅ´m`Tõ¥5 (‰ÎÎî\Úu<Œ1®Úd Üs”“³sgýó/l_~åµWïß¿ÿèhùɽ‡MŽ×«ty_ù ƒû]³ü‹­ét:­.NÛŸüä³-Øšm«Èüêª]§Qí§³­çŸ¿;Ùš¾ûþOïÞ™þÆw¿ýüËwšnýÁÇïM·&§—Ç`à7~ëÍÃÃÃu·jzxéµ½ßùï?xx蜵Öüà0ÛšîìÍО÷=t]sëàÕ‹®™‹À|>ù¥×çgáòl}q±Z/g dߢ@æÁ=1Ô2ù§9?‰‡l!îD­%ƒ„&—0DȽuUQ‹Ì1…˜BT›Iùz"$!ŠÌ:P0ÙøŠ ˜@SÎT‚é9}îöË\Ó”Y2–<æ‚ Æ(* ŽY \NˆH–ÝD£ôF@ÇSY°SEIÔ°9ªÉHB RUAÌ9ˆ`”SŠ"‘4IS”Ä€` €?†É®Ÿl»º†0uÚÍ[>kä"ÁìœBw²*ÄH€ØPפuꬮïÁˆÍ:†Ì4ÖŒ!3Š))ˆ€5HÖc­Á¦mX9¿É›Á@"u@ÉÜèL wrÇÂþö^»h:h^~é¥ï}oôÜ+¯ü»/½òÿÏýàíŸò:å‹ó“¾Y,.’þ:o_†…:œøu³ÖËõ|6³•ðZÖrcu¾ 1þ ú/ÿjÀèã‡6Rq 4pèR¬È£³ ŒçKÛµ*I»c¤kÝWfÝÌÛ¬Þ•!eæ¾+ÉrKk‘6Å&uKí/ºvÉ)zcpR¸Âƒ]͵À†„A$§ˆçÉ2ayY[E À™Ò>€%Urá…„€›&%2ZPÉWNDË6ªMô^„.òœ‹­ÃèCEñ¯ø²=På”$éB«ëecÞîêêòÜ¡IÌ d Ë$m ޽÷MèÑBàôªm×à L˜Œ&åhÒ¶íå|ùµo|í«o¾ÎŠç?ýèÃ?9<>êÛ® P ô,ûû6õ©mÛŸéwÿÖ‹}:¿º8;½ƒ[w^ùÊäâ|qïþÑb=ß;Ø¿x4žº>ûðÓ÷"‡ÇóãßúçýÎî®+«{î_^W@YWúçRºwï°ù½ƒóó‹“3øú7¶%µ[;U]—3ï=\8óù2vÑÛ¢k«Åz±è†ƒB°ô9.wV:ä"H`Œ ˆ ‚&QvÖ¡ˆŠ(R2¨d01K!ÄŽ%äd•Mîŧ@U% æ 4"›S\XÒF8ND€h‰ %Ý„,ŠfÃ:l‚Žr-Õzª‚ ¤)E!@É· 1J¨Æ¨¢¨ª•:>ÝyN¬ËÑMêæ—sŽËÈÆY f-ŒñŒÚ±Ýr‰PÑ–hÎŒT A5ˆˆd7V# ƒw… ·mA ¡ê1/ ˆŠ˜ñ×H$™ C~µâ›öÎ…%ª‚˜S@Pð×^¹€¤ÄùŸâͺG‚i5r®,}ÉQPTcPArt6¿8úèüçïík;!„Ñf³é6h Ñ—ÕzÕïë{ßóëß|ûí·ÿ÷ÿ ’ýìÁ£åº)jè£ìg_{ó›ëÕòøÑa]«E»½½K ‹«ù|>¯'õöÁη~ó›ÎUï½ûÁÿò§ïß;‹Û/œ­úåÎþDˆž§ÕtâÏÏÏnßÙAÄñxÜ·áþý‡;ÓçˆÈ6ëaÔ_”Eêú¡óŒX1~Cí¬*ªZ0=pj ÖÎÙ”b”¨½÷ )t§””*«Jî««D!´DVXcì€)çΫpþØ *`I9“Ð3 N²ÛREEYE†<`òÞ{õ™9õI™ ‰ œç¨Æä U2(y8𥉢”QÑ%L¤â-…U•¶Y‰pËX£ˆB dƒ1‚NI0& *Dh¬:£ ÀIM«Ð/SÛˆÄà08HHZûäl“Àvãþ2®Nûö‚´#+êÕ‚¸Ðõ]’˜bdÓ£ ¥ïÅ2³A[€€›a‰šDsò†‚0Ʀ°h5iÐÔ ÊuöŽ ¢1€Šè\XØ*"ZcœZlÉ£ÑÙâêå½[ÿÑüŸ¼üÚ«œâñÙéöÝ;TWkNïÝôßýÿý»ŸÝ_¶½’k~½eûµÒ]6Ýô.¦!@ Y¼7 xá†<æfÃýff¤^Ëzàó&Û_fO’'Á…¢9@R´•Ô!Œ ×#Å>4]@èœ+Š""­û°°1pÜÙš„»ÝýŠÙ)ZE¦óó¶ýôjc䲪G‘CÔ™Gã (UE]G½@Ä•i‘R°Ñb" œsd5Î&@A”ºŸÍxˆ6Þˆ?‘€XU!× ,’[¥„ug{Má0H7 ýWQ„<`Í;ã¯}q·–B°HIE8€(\\\F#P^¯“zäU2!%(Ç0—ßúÎo~ôþ'+Ó´»»»ïÞ;zñ…r{oO,×vxx\ª·ß~;0ŒFÎÙâè°/Šó—_~µñìòò·_ùÍãÓO>=¾³?™N§÷ïŸüþ?ù?¦»õ£«£ÂT'ǫЋƒN· 3òç«y=©..Z4°µëæ‹Ør;šÁñi;_<ðÞ°Xù NN¯¶f;UÙ[ãF“úÎ;ÞûÕjõÜíÙt«øÑOþ¢®@Çã‘—ÏîfË‘+‹*%Dð޷ݳL( F•¢B¯mÎÁ ¤¤ÚX4hŒgí!¶,lŒFŽ©L€€‚È œ;íª"  SM’ë|–<'aPQAB2¢Ê ¼¹_-!krÒ6ˆ'ÀÊ®¶¾@ïµkS’uŠ’ e Cn%⌣ 2¬ª9ÜA­(qR²Ö¢1žªBëB×ëu¿ZûYÅÜ& ‰°'%ÒÕþb5ˆ—LŠI ;ÃÈ X Ò¨¾\…v!ÔËÆ 7±è¡d­+3¾‹õ.:7¿Œó“þühÕœ:š£ëƒådD¨m»UÇÊJjb’š¨±@†˜@éE;a&Rc½óꊈÈ)´Q;r¼‰¡PDT2€„h\Å**‘Äzu…-CÑéó/¾wzüŸþ—ÿyß÷»·ölé—©_tÝùºU_<<[ÝzáNµµÖÉ_iúÿ_›åÖ/<¶ä<ß>–Ôà¯øøË uõÆú®×kž‚X#…gï´ªìlFÊÝ Õâ2öd½A»´n]”bLS”(Ž§Ž °zë*S4ËÕ»çW®ðãé„&•iKê[í*âB„ZNJìCR­êùr çc 'ì"¨U H¤¹9žáÈ™ÙÄ 8´+U$£9‰“‚QQ0ŠÚ£")|®Ç¥d®÷¬ÏÈ‘xéÆ É~ÙãÛÒ"¿àïaæœkÀ,Æ ³Ch×é³OÔuU”nÕg¢1Öy÷•;û?ÿðÃ$pzv>ÙÚºug5¿¼úäÞÑlÛ<:¾z¹ªÌ»ï¾Ûua1³íúöíÛŸ|v¤ŠëuóEûÿÑ?+ s÷Ö­ó«Ë>¦.ÂéåayûÎÌÕxôɺ°xy¡·öGýÕz¾ÔQ¾÷LÜÆ{ÛfÔ.¡‡oç>ø(uü•¯¼:ªÇï¼óÎéy[0™TˆpttV«««¹s¶(1öç‹wNv§]×AQ8ë}Y,//çýÊÞ¿d ¼ÅÐëb±,‹2piÛYÓ¤¢i2Íç/¿òB¢jQM¶BÏmlŒMh½A‹¸ÔI)ª†PÑ¡:E¹™š ‚ôd<±¬ à³b‹4Ëh¬1Hdˆ±kÛ¬|Ü„þ)¨ °qXüh4¥®›t]Q"»^¯‰À‘E;äìP†Lʇ©¹ÿ‰Š0ª§mèQ´ÕeÉ{ûU]c­ìƪ¦¢ö¯þÆ·gH¬( š$YæBÀ9d“VãS£¢¨\=Ú“6yßQ”"ÕûÅíW·'ûûÅt6™ŽWË#O;£bÇmÅ¢°E°ºˆiÕqɦÄÒ"ÅhlYU•h!±$ªlI€©ë¹mKºôM Œ ¼÷¥u(»žúèKD*("¨DD…uÎÚÚ}׾õDUU¢%è;·½UÕ5£lÝÚA‡ì©²® NOG³í[äNÎ_ùÖ·>zxTM¶¶ëâÙƒGc~%‹{ÛÅ¢ð}{Y8ØÚ©ÎÏO/pðül±N€ÞšÒSa#`ŒïÝJ:FùÜJ”ÝΟëÉ ¥º¡§ç«7Å6Ï·âã%ž@Pa}u¹LýÎóÏu–t2žíl½ó³ÊX[L ¬A§ÞOw´šmÕÆ4Þ“s5Ú^ÑùÉd_Žï}6ÚžùÝmòÎT]Ѷ3Ž£=L‰E cF¨ H5* eÆ& T!(ˆä”tºí´Ùùº½y³óÅÌÕ¨1 ‰P æ´dºn@Ý<Ü|ÑûnÌÆ¾tåþ¥{y7Fù¤·ÜÐCŒÜ÷«ªrãQmë’¬7–VMxáùnÝÞ·¶øàƒ÷>¼ðªÊ"âlæ¶·vG£QQTGG'mÖËÆ{»Ál÷0N2úðb¾8::*¼}í«;—çgÊrëî-(pyÖnoÓd2³õåöÖž®.æ‚B\G–Èêàöó{w^xáäülšxo¶ûÖ g§Ë“““wöQY–}€ƒýíõz jcêBLˆHòÖpÒfÕ&–íjkk !•E!GÕ(4F’HÊ+8)ó³Ì›ÇååùþÁî¿ù÷ÿî÷ÿöß Q‚ *úʆ¸$ÃyFšÇîºá<lûø€Ïtžý‚ÍXðÉÇõAûsQŠ® ェ†bŒyA—Á4‡`Àl%„An 7¬Z g‹.DeõEám‘„cŸ¢Ê:µ† dì//ÿ½ÿðßÿìÝw_yíeõ¥SA•L¿%"‹ ÝÚ¡±¶ ô Ž“IL¬ë!&qD~Š~Lä0Ý>@^‡4ÚH]‘¬ QëªêcÞpë’#,3C½äÁšÕ˜ú” @"$5ÆxCVQcQÅ–Jn°Š"¢3ÖC ’‚H"Tk!PŽQ"MÈ"€T-d„«õåÑÙ’w¶<¿XݹýüßüßýÏ–ëɸ~fùþ+YܨïÓx<Ò¸Hý¢.‰Ðg-Û¦‡Р+ÔZæ‚•ŒBµòzõ¬­üå†|r.ˆOÒ–—ßøÍïìîîþö÷¿×/—ÔÕEÕ4]T‚æý„¼³ÉT€Ng]HÂÒç›#3Y²¦‰™T ‘,ŠHÒ§!™ýñ"®9_o3P|LdAaÊœæÁJ&D*’Ï°Š„h‘4ß5‘Y73 Ô'ÙÈO!h‹xíòý•-î¿ø½ÁÇt¹A°i„¡ï@%:ÇE‰€Ð8oÊQi\µ\·*fww콑º¬¼÷!cL·núf=W}ŠëÕªòP:c¬*wûà–¢\^^ƒ)WwïÜyî`½ZnìnßÞ½€5X¬Ê‘^-Õ›Éîv=ÀG}rû…ƒ¢,Ï.ÏæëæÇ?ýÙÕ¢MêÄpy±¶uµuzrÖ¬£÷ž ëŒ7HŠä-V¥/+ï,U5u¡I1ÅÞTÁ¢¨nß¾ûÉûGmÓ÷Ý ÌÇ4á§©ÃÉÓzÿýŸý£ô¿>8>V0j¬5¾š¸Õò)]çv>sqÿ6à_õ>nÓô´°ÁZût¦¥`BË@še0’†Þ4Ãî“ÙÂy3`@ÙĵaÖÚç1DV4dÐæa«ì¬µ[E=tòü;ÿö?üoÿAå kmŸR ¢šÍz¨`Á!b&R±Ô[V$"«¶’´oSêt\jX›Ð%ôjœ1"ܧK”í¥ *(Ä!*)X´F€™•HG=§È @<¡! a‰¨âe2Kî–’AФ9ý: ú(£‘:6‰ÕYUK¬* ãñ´k“D•cGõô£O£)>ºw/4«gæ?|‘ÃüË.®¼‡5Äùsû“¯}ý5rþÃÏ>>[¥óE¸Z&PSçLŒÌ19b|Æ5ö¹¯‘Ó/_;*B¹Æ\_ð¤ðío}œù“ýeiíý>™MÇ{[³‹ó+çJÊtÆÎ‚ –rª‘°aôªFQúÂER…È*b½sY‡ÃÙšAȆÄ`p›p¾k†&øpUËõÝ4°„D1óo,îù$B$£HYƒ…Ð+_³ø‡ÍRùFmx“»É7Þö_wÏ]?·¾oLY˜‡I€šu!$ã‚«9žªF­ÊQâ°^¯·¦3cÌÉÉ ]_-òÜs# TUÕh:QÕø(Fá®ëXÓÕÕÕo¼û;ï¿ûáOÞùñ7¾þÆ£Ó÷þôÞK_-§wv›u›¬›”ÐQᜫG£ñd2Ƴétkvµ¸\þôg1òÙéÅÕùz1_ÌfÛ)¥”ÒÙÙYQzçÐy[9šNGE‰d°.i<ÚZ7WÐ45ÈIM媪Š}\­š®R4TéÌ ææ¢üx¾³»µ\->üèç'çg£éTÈ´Ë%hÇ€<¸®¯}ÙªðÄÍ|CÍ"_®F™¯{seÏ“±g-ŠŠNU#†/*óŸÝspöøšûWÿÞ¿ò¯ÿÝ¿÷_ü7ÿÕ»o¿ ãÒ….ò€ç¢› œ|[2( À ·S,"-5&Ì…ºaJ¬Œ@Ù3Â›ß _ªð4Ïá †O‚ŸŒ)ü%ƒEóòhnüéIçúð„DZƒŸ5  n~}éÅ]¾ <ñ—¹˜68"…Ñb]7iÝ®¼_‘#²¦¨‹º®}a9ÅårŽÀu]wM㜠]g­k@8®— Ç0›MBŒœ'h𦬋ªªæËEU{_¢ZoO¾R½ôÞÞÁ®Ö}[UÕíÛ·AðôèdÑ-­µmÛïnïNÇÓ²®FÓIJÉ ÉrŽù|¾Zƃ°ÖfßXè4t}UŠ·¶®]]!+[–^±4E­Ý04ÆØ41¥ LÉeÃÂ`RÕ ÎÏOChŠÒ”#ƒ&„;¬ ©ø$s‰ÌM^äÔ-”ljȿèMô)ÊæóõéúKQSž‰n‚÷@¢(3‘@2)cã5ìÔô䣂† Œ"Vƒ $ÁDî—çÑzÛÆ$ÈŨNÄ497›Q”PQ¼B¡Æköq¨E4yI‚*ÈšY` Ùr°O ¬„N5‰–uÕKNŰZO³G–ºžC©š@»˜Ðf]3´`,C¶¡sŠ`LAè1/î’²T” &L  ÄàÈ”† c± 2R¬ 1‹&kØ„eM'ºdM0Ù¿øÒ]è[y6]ëWeBt”˜UÀL=·3U4{E‘+ àЈ1*’$æ=Fn,wúl>ø W^¾Ù IDAT—ù\cýËIàŸ‡•®|á…—šuÇÓQÝõ}ØšN/«¡tmg‘Ü0d@ Q#9FJD* ÌŒ7ˆ69Ä3àñSxcᥧ^®ÜfÚ|Ê`˜È°xÚTÃC0ÊP®4‚CZÆã– )! ú/?ð¹õ†³¿ 2†PRb€Ð¨XF²lòÞ;GÐ4ˆ0n‘ KÌç#chkËXkÉ@ÓÄÐõMÓ fýœ–eY–¾éÚù|þü‹/¦î}R8¢Â|öðáë[o†.JRgwA =%½‘gê¾0_žÞ,'Ö§¿D¯±1<8EâÔá‰^áFt¯z£ÀQã@eãHb(Guß÷D¼÷u=VrJ&lßC5ŒŠH.eÚ“ñ÷˜DPÑ*‘úŒÎaåÜAv“ŠEsì]üSEiѨpVÁGšŒÌÈuª¨³À€L®Î€Å5h„"ƒ)Ѳ˜GdbSŒ`¼J¦rPõÆï{;VW: îRŽ äжWœ/Vk_Ä.¯N]‰à üÚ ªQŸÄ¶ÆÀ-<øðýŸ¼õÖh2‹«¥¶` cÅ8UMˆaèµm.§Wê›’ÇaTú DñÏt¨>®V†Ø €fµ¾<¿ ¢ª*¢0+*@ÓÆ¾»É¡ß\߉ˆ HUEœ·ÀÊ"¬Œ,&ç)‚OœlÖµ(«fŒ‹"¡^Cà&ggsÒUºq³åþL~i×Ía‰'$ ÁÜ­WÎ!¹ˆ”1a9¸²3 Õ‚É–XÊæoD£*š!“Š¿þê³ûïdÈä ÑX§×!2©ãU\¯Î×åÅöÎ8¥¤óÕÞÎt5_(K³ê ÂÞζˆÔ¥líîl±Ä©Ö´XÎ¥(ÜùåEÏ2ûÿ¨{³^K²ì<ì[kígºCÞÌʬ¬¡«ºz¨&›lŽ)ȤDЂdƒ2l†ßü"ðƒÿÿÃïü`Á†-Û4MdŠƒ(MªIvuÍ•ÓÎ{ïµ–vœ›YÙUÍ®fw“̇DáâfÝsωX±ö7ÞZc½^/óå¼›wï|ë[>‘=ŲöÛ>Æ©”Tú5ŽOAAÈ͵”Ô3ùb1»}¶<9]Ì—Üv`ªÚvrzk9ô£y¾8/› bØ-NJ·›}ß}3pÅÌP¢7‡ôj~Ξ `»]÷ý.—A«5²Ûmv»MÓ< Õ;Lâz Ÿ4¡L?ñîÿ”ÏÑjúÀ·/é"þñ³Âä¥0&p%|jýWm|½y%ôô>7’ 7ôªq¿Áñ‹‡©¿D7‡—Ñ×zëîÙÕã«&F"rðfÛË| @ªà¦Þ-µ²ºÍÍ]É(9Šç=,‘݃{c‚yš6ÎZ"J `‚4è4à–Úå\:#ÛXbSˆŒT•Hˆƒc‚JÆð  [2bwÀ œˆA(€¢71x —R¤äÆ›¹„eK§™O¨]ÎŒJzËÜ-B{vçÖf¹Â•òÆOæGCÞmÖðâöýî°þøŸaÜÏNHŠ÷ß*ÿê×þŸÓ³ÛçÎ}„92¦âà ºª»Aÿb¹CMñ…}Âè g]KÏlÅ‘¸•pûäìo¾mnmœ™Ä}¿÷éúÓÃ?Ÿ~  Ø”œì^G)0ÍnSÙ ¡LkŽ–ýëâNxû²ßcØCn\« U“¢@j¬çó›{lC×µMÓ¨ú¾ß‰…Éä+ÏXA¬Náš3Sž{rã ƒ>ºS‡HCÉ ¨¢.nª` mlÛöê½óvѬíòzxås¯,Êì¦Åšœ¿/KØs•x7—„1s4ŒÍUV}¬cY¶HÉ U/È´¯CR<|›´ñiðÜs‚™ OåÏ~Ã'¾þgžÛ¶‘qÍ­kæ9guíÚù˜‡gË¡{{mù»Ù:ÀBpOc!´ Ê0÷rƒŽ@ˆˆYf\‡;T›Oø¹½ÊìÛ!šú¢é@¥>›¬/pEULR3+ÁëRT네ô'}ˆñ™<çï¡fï³=k?öÝÏœDÜ su¿St!ÁãfG€0lDUþ¿·;gFׯÜÆS+üÖŸ?r'C3dþðÉel1Æ1•[ËVú\[ž,É"{·¿8räå;ßzÒÈl¶âók3èPÆ1ë¨f>ŸÏK_.\eSM0Ë]„Š>b˜µÍا×_û\±üîR·?xïèxvtܶ,NNgÇó¡ß½ûáƒ[Góåjþ÷~ñï¼ûî»oóý?xïÖê, òä¡ÎZÍJF%‰ÆÀT´0±=½ÂÙëb«n»¾„& È •óà)¶[>e~û€Ã1öÜÇŸtmˆW0(C¸Xrqƒ ‚ÖÊkB›3‚«¡D¶YÓyr+NÆ…ÈæÙ‹E1ªÁÊáÁ H¤`f‹“øäâ²=9í¬›íÜ3³ˆ;ÊA@Z½6d 42-ÄSõA}e12Ѝ{ÆÈ’³_X(Ä­sK45DG VšÜÏç³ù|á¹lvûa †–À†¤L܆P3~Šg32z)fnÅDÞÍ—)WDZ _={ãwnðŒ/v—}.¦¦Èâ…ÆíhV(d4g£¨—ùñjÿhÏMwtzôèÉõë·¹™Mk§Ù÷r|þî¾­YpÞú®`Éè3$-íüÄëÇo¿ÿ/~çÃF0¸ Ù^zíe–ñÝ÷Þõð…àN“ L‚ªbR yýZmr/<Ñ9§¥}„H+“[°=“ŸLdH‰‰‡4ТIc¢ƒ“³¢†VÅÃ(p€„™ÅÙX-³¥ˆ0-îÐZQîJP3W"f„©RÇa.Ï? ÄÇ S`y!ÈÄlùS3‡ð”‹58¼¶¦²{M¬'xEaèfÅ:ücõRåËÁ©µ‰•ýa8T?µÞãð„áçžx7Ož÷õjöÑÍ-3ë xGâ£ïM¬m,Æ5µ%Ôù³[ï²­‡4šYÓ¶ÎT K8‹œÅc$b1#ÛoÇœ•(09"KÓ4D4lrœ‰aÛï×ëµ DÐÍ[…^®/“5‹eì‡õõzXÎðâ‹'êi³YŸ__?%xï“ÿ½<ÍÜZ;àp'F”‰§¥Z«0>‹YSR®¡ñΰ€QQöû†™ÙÙ̦0#ƒ«þºjiH§­hB@I@ꓪrE7=u*`1\7€}xªª«1 b5‘FjÛ*•úrj‹CŒˆQt lBìâ…ØÄ2Æ}Êä»±÷®N6ÃÄ02RÐaîÀLD˜uzÀÜèib¹«ŽãÈÎiáuã%Wx†¬( ›’Ç!Y.™‹2+ç„”½¨ƒ>#®ñÙ©Ïm‡³ö4]]máiô®›ÿ—ÿÅö›¿ÿ‡o?ü§üniƒ97ýv'm999ÚÚNÕØÙ^ÌnØ\ËäôFèáîZ4°;+= /˜ðöCÅä³0 Uì§ŽuŸ’o„4t˜SF‰SžpªýTNzC@S}mdd\{òàÎP³C½b),, ƒÕÌ» âTÎ` ¸‘‹b£ŠÅ«KÛQ¹?V”rjÊ|ß< ª$Zا(Ÿé¯!z¨ ¿³¹™»™7!Öæ'ü° ÕïÛq”¢¥ô7sá@€Cœ ÆS¾¢—R+ýÆ>¹fNT ,@J ®dg1v‡©«ª™•b@ŒÜ¶ml"Zœu·nÝrÂú½íƒ—Ô@9çó«uQŸì^ínݹsgu´KÃv»Ýž,»~¿?t~ïvc¾~²I)ÔôrLt…œ°hé÷Àš8¡0”Q•‚åRÓÁˆ¨ÜM×£0Ô2Z'1ÁË( ªÙ"‚;Y³Ë`ÙéÐ%Ví.… ÄÞÀ@îœQȨ*xª‘ŸŽáÓ-} +êß rª³“«‡ž¶Žº Ä&ÄD0sW+êV55-ÐÀ %Dö‘;±ºxB±d#ò˜Æé,£MÍ×)>MêNQ dµÝÞjÝ¢ Ú—\•ªµÅ<íGíMó©wºrvaTPsM°a)‰|²gËÑ}IC6óïyd·2f€\Åühºæƒ÷Þ9òÑÏþì¾øÏ—òöU´QÍ·ç²\Íç1xp8‘rÞjf¤‚X툛VN™Z¥QØè鶉©é„ UYôLS6ý…Ñõ“ùãc²\ò§2\ÀŸÉàô÷SBtÈrd>T’3ȉƒˆ;+´2*‡·‡|J]ª#žˆýô1žâã+‚cØâg?ôôXR_ZÝZ™™9ù¤g7¥ÊD ÌÂÌ`˜™©Àa^Ôë-%ÆûD>?£13WxÁK}ûDîF@^,Mp‘ îYKÖ@mÛ¸•’Ç’UÕª–œˆ¸m›bImÁÄLfVJ9»uûìì¬uC.¯/ é˜,¥!¼þù³[g«Ýþêí·ßëf|ÿÞí[§«Ýõya·ô61Å®]<ì×»Mv­—‘9˜ðôzsúÁ†r|¦È@RH=Lv#°¹Cˆ…!„ÈÄ$BJ@#¶hgp‡؃ìfdÆ`¡pqpåÒYœØ5¨RmZcR†0iõ3×F1÷©T LÌLˆU!N“ú‚É dFð@‰É‹²Uwˆ×Åœ0cëáù\ ÔÄV'»™R ±@ª'³Ï °À|\Iͽ6Bñ¬3žP¨9hpP0ƒäRJ)†Ú 9톌Œ2bÖP`ÊÎÉ”µH±‡bfDQ“m¯GÛJn™Ks23ƒù|ã ¬à|{½ÚùŒ#?z‚ÿåŸýO¿ô~yØ_µ€)¢&s ]í›–™‚Ä C4§RéÕƒ;™áD…H*¤Tƒâ«U§öLà+FSIÞœS>Á‰ýñ„áCZ™síÐfÀˆÙ¡p†¬Æ·±CÁ™a-ÊЛî>@ùýRó‚“có´\L¾R‰WB ö8(~ÜIkÓ)£ª“yêÖ˜z“kK“‚¹ „˜£ ”Ò@7ašÓ)Ž©bEv˜³‘j|8-ý îìîDwF˜éR8•4v°Lº2Xìâ|¹ @ý8èh"¡mg«e“ƾßöÃ4A"f¸˜ŠP×uw7UUÍ|ðAÎùö gÌ<ŸÏ©Á¾ß˜•;/ŸœÍf].ûù¼]®ÚårÙ¶íV1kfšm·î=˼Y±¯ûýð3WäÇ"`~ÀóÝ?–Ÿþ6wU…ϸA>j{e!GP`c@ÜçÙÐËÛxõ‹/ŸÝ}áêêêýw>|0 A277&'Ë>ŽÚ´0vŸ”ȉêýäNîfÎäHªœÓ¼†§K¦nFæÄ\7¤ê:TY²ÃàTjwÄ$¤©uTUà9¼1D•$p©m9FêœA£¡Š»*2HAŠØ¢kPBv<¢rã`·¶€'¨£ £Ý•}W2‘ÃH­ZM§† ¨û în.ì‰ý úg Œ†¬5 eð²6˜FPqË¥ò7¿Ëò ‡n1·õ Wûþjo/½†«õÃßüÍ_EÁ½3¬w†³åéJÒ‘5¹‚´‡&6ë€&"IY¡Šbp‡+Zc%ëÁ³B4NLm‡Mü»òÜN7µ‡& °q­°uMa¤‰”Có,„8Pï·ºq)™0‰ ˜(Jbš S¸[ñà¯>$&šled~ÊD ÷Ä©Â3R;È(8 ;9¨^æ@oäÅ…‚C©™¢S% Ø‹«(3ÛH "@’ÖþüèÜÿòèÍxRÕz0u‚bR^ˆ Êðö»~¾èÍÛà„6v1 ƒ‹E%P`Þ¥!ÜJcS¬Ã|>S·l¹!jš I7Ûë1×Û5 nß?{au{¶lïÞ¿³Ý]îö›Ûwn}áäÕ\†ÍõùåÅ£è6oZ0¶›©eâZ-ã!¹ßj¯òMâ©ÿ€çû§mîŸøõI‡%ñ8êúé.@€E 5"•áѱ`áÆ—/,¿ös_û…ø‹w^ºûÛ¿ýÛ¿ºÿ›«;¬(…²7*ÌàTò¶ß«BÝ ©Â3,eƒyÒV?¾£("ªmpr«hvŽ!´  1"‡g2w3( N@Õu *…Å™ŠV®KPªUC`Wq“Ô¬r«µ6ÈàâÈ…Ò4ÖŦÅrFHŽ¢æÙñƒ3Xæm¿OÛ<~áîQÛ¬gKûÒ—åø6ÿÙ7óõ‹yײm{.ÉLjßKd4‘ÛÙÜ̬n9—~sF±jñ€‘¹  A&2Ö|ôI¯Ì>es—ÉúCÄ¢ ˜Êaf œ} Î3:ˆ³ëLàÕrUíÄCNƒyE’ÄE‰q*j1c“ uã™Ò–ÉðG¨ ð®€8Ô©©¿>å ¤îì ¤R9^;­Àž‘a`§€Êè†~¨r U¥šœó ¡#"¨û ùðÃèPý~!Å5‹°Ú@¦õó`Eº3Á^%Ž~TÖí\ŽoŸœœ0cúqA&´¥u…ª×Êœ¦irNÎÄÌ¥(µmß»sïÑÇcJCÙs år~rº<:™Ÿ­ÎîÌ™=åýÃG®¯Ïãh>Ó~ðŒ6ÎJ¼Y®/6%sÉÏâ!tS7ùÃÁÜ?›À‰ën+M15æ\€h³ ](¡ ¡1º?_ Y·è^ ó,'ŸïR¸ÜÞ ]‡N4¢ãNmhó¯øªxÊH‰Æ{ÃèÁ ‡’ ÅØÀpË0Ì¥ %µBÔêÕzº cR5U/J·Á‰Y]ü`žâi7×ʶ†Êe ¦É*RãÊF Fd4ŽÌ„»Vâ mi£'J©¸ÈÑ1f„.€êƒQƒbt$‚)*í©ŒDp«"$2çJ±¨ë˜I€šJð€HNœ÷š PBJƒÌ®äÎìYªØZõû<ÊŸ÷£ÀX°ÁÒj†±)ë7¿öê—¿ô¹îÏßÁ7wŸ—‘<CŸÅ=D ‘8€bÊÄlÚ5„Æ™R*B4`0ƒ1Å“ec‚“ë¦î΀N§¡g_ ÿ…˜ûaÀ¤Jð¦ÝŠhâyˆ‰j›Qe$A$Ì"ˆ…Ù"{¡’Q…<™3´ræ6…¯ šj̨¯Ý& l}f1œAN`&¯AÜnV óüÐeÆ€‰kúÌ×㛋ÂhjF¥I©#DÄd…{)溘jí|=üÑß4Xf*¢)Êajî† k ÌäÓÅ<¦’ów½s§¹urjV†q7Œûƒ‡6DUJ*BŠ›e3hŸFwå@!tW×ëõUÓµGGK0ÌÓÅÅãÍžÿäÏ®_{ýþ wÏÌÊb1[ÝOý~sy5“h† %4q±Û\ö;K 7 ¢©ýÑñLHÄq²ÿ èÚI 'vED¸`ÎXFžwݼµ±›»üøK¯÷××ï=y÷·~õ_½õgß8½{öþ‡¼ÿÇW·WhlŒÇm»œ¯’äNuÖJòaÀn£×kë¯Û‚؈¡˜Uö€wÀ :ED)MpÕâŒBòí<[tV5UÈØB;#ENÏ•# fQÀâäòvaÊì-ÕG±]u³Eׯ&PLKÓTöÉF5 àNøH¨‹hƒ1±‹gÂFm§´W.V’ÜÙÞ¼ÉL­#«Kuµ(j®P)i¬¥ˆv­ãHP"r@FÍÚd‹ä¡¶ÜÿÀd2ÏH§›PÚÒÛØ4™ñËÿÑ/ûË·ÞyoL{ÄYØìö}—‹–̺‹åb>Ÿ+|»ÝïöCzhi[—Ø \|’¯F ¹”šKíOÉFsc"«MÒvÀ.éiàŠ}ÊÖÈU#Sùö‰Œ¡úfbêC84ÖÕÈ:÷*_™: ”Rf‚XÑZ%F`hEÔF­ï{=uc{Z„ZGs¼¼1„@„á†é…3“ÔÚ ¦ ÙTŽlÕF^ë ëГÂ-"fBªJ ¯} ç .áùxåOŠ”üëð§²Ær(µ¹ Ec©g¢‰·â ‹×­@Ji»ÝVJÉ¥Œýn`–Õ|•Òîr}}rB¥w„ŽNÖ›«%•QsÎ9?|¼}ãK/\^_¼ÿèêåWºŸþê×]²ÀdcŸ§¯ò8”1µ]X̺!¯÷Ãn·+Ö²SŬ "Òu]˜sÍË~°f·Î)¥­íÙY<>>6Ê…///‡õ¯ÿÍò8H°bööÛû¢h„Û¾^¯ËÆ>¹vÛ͸¾úð½wnÖ€Cž©<ü“`ß5Òõ±6KwroµpœƒQKÔ¨µì/Ü=ZÎÍèäèøôø¨ íåånÛ§ˆ¡å0pÚ$@B©àlybcÓ†q7</›ÅüÞâÑæbØ_7–÷þĺþ'lö·~ág¾ü£_ù­ßý£?ýÓþåo|k¿Z¾<·6´=öÒŒý7ÛKô›²ÂMKOœÌU‹š‚Šs°Žƒ4B0J ¥d˜B³£À‹œäÅk­ ˜·ËnÞ=5²TÊ~·ßm¯¥1—„ÖeÁñ8,N[>m°F€ÄP"õdZJ²^]ݳ:Ka…y‹2ꘆ,1 ¸SpŠ 6„д­¸ÅYb§Ð\ÄJ«ê ÙP¼ ñ؈þ²;ù'çø9¥Ì¦o—Í,òÉ’ÿÖÏýÈ+o¼øüòOõyÿ‡¿ó‡€wîž-µ½Ü{ݺ¦.v!b¿¿Nè9X·@h$4ÇìÅ]'£¹YÊY… @f1‡™©y¨&7xý”áâO+:ìÛ±¤gZdê…ìp˜YÖ<%NO!6SÙ¯÷ ð:Áù€ú:™O z€ <)3!lV¬Š2‰˜œ fÎB DdæEսД PIâÊiÝíª«ãð„˜ð†ñd.!<3àîgvÔ^TcuMñ6Õ‡>}¶ÜJôê’††ç>ÚïÐò}ó¾oBÜgõªµ¯ä€rÕì7û«ö|±š!˜»Ç_~yÕ5³Ýz»Ýî]íââÉ8æåUîVE IDATrš¨šÉ¨ip||lª¶ÐÕbùÁGïó­?ëGÜy©]®ÚbýòdÁl,^›Ób”Ŭ‘¦í¬µ&œ¸Îß¿xÔoÊ¢ ¦R›hžNöD“þê'ûͰY+`sQ°StîˆgB]¤WïßKyÝ´í|ÞõeHp a×§‹ëó(a¤´Õm–4’°ær9-£ŽÀUEH$ÈædUåòñÐ$ú4&‰q€§'¦x#—§Zõȵa8?·ß< *ðšÇL1HŒ!†D„(—œ’;(¹jÊ®±T&Õj !‰QÔ‰¬îÙum¯–¦@VŸ¡ 4f4QŸÑÕø½š?ÌÄ rWƒL& ·2w¨¶) Ç)QþæÏq›Î’u:$¬>_›«Ust¼œ-[ ~Ý_«©ˆiÚ¶ A‹¹™m·ûœÇ”’ÚH)yJi·: C‰q|ÔR蔤š‡AsFl`V¦N™œÇÝ®mO]1ì‡Ýºô» Trù“áQú«|ë*¡ô ×Âq!Àæ±ÇyÃrW+õüõWîÿò?þ2›õÿǯ˜¾~¹~´Eib ¢BÈe“ê'˜Á(9P Îwо1{ùÍ—?—>þ{›/·?ºß>x룇‹ßûãÿüWòlq…°õáýËrßá¨Y¾ò¹³~›_üꋯýÒçéúßþÑ{ÿßï½Ò`ÛMŒ§óvžÇ¢v8¡+Á„\yLE%7°£!jĉ‹†[ ÔÒpBT4æ¬`‡F8“g™ZÈAóy˜ž‘Æ4b_l vHž#p°{P†Ž llᥦ–™ øC‘HÈÙ«P¹‚c&¼5÷±W$pØ9%"D„…´ˆ´lÔ¤p0Uš©bîú½ì>þmgߺò°«|¨­”"pÿ!mþí¿üÕd&Àçîßz|1l/dsÞ-|y:;ºË³³TÖ±XÜ ¹ÍmäA†æ„r¯’LTšßû˜“•âŒYË5£NkŠ?œ¹ØxÍ¢òÉî矰³ÓÇ.æ*¢«mÒ7MOÌÁÜõ°Î×ÐJ»én578O“}2ÓLå›ìU‚hñªÉ2ÃM„‘ƒ’¢OjêÈÙ‹!€Ù'òÌ|ʤ0s ˆÝÙ'ŸT"ˆ§ˆøi–Q—©Šé@± Q‘¹æ¢–ÊS¥ŸNûþ”¸!z°yªcÚÜŸÃ^ñ}jrùáÎ*»É]©yyFm4m$ò”MÙIgËùòhÑ„–€Ý¶·b¥” Ø…¶¹wÜœž>zò8´¡ï‡ÕrÑuÝlÖ¯œólÞŸÌîÞ?Jÿ¹†Cd>9 F)"‹Å¢,h¿‘q,Aš®a¡FGùAOêï»™ì¡ #xÌBs4_,š…7 ¨ñYœw'Ëåíã:J­ì#ãhÕo3 F(ÄNP«ü/Ï»ðÁ“~~‚/ýäí/|íþ׎óqoûrû•[ßüð|¾UÐÞ¤†( ÅK)$šàM7[FoÝo—m6u*© (°bÙöÎì“v߉M¼V‘9(«¨ …9Ðl@&©¨: m0!f±Ù—RTsÖ<ªe@Ö€"ˆŒHÅÜ!ލ¦Æ³#€Û€–­j„bU…4‚@Ä ÖœŠz‡=#AØwè÷£Kž©pswždùDDóÌíxi9ëw}køêWî~ë­‡\BMyÛZsÐfÆ6;»~ås_Ê;âUIìSJŒÓ[||6¿|¼–^½¤ä¾¬,—J)!›Ù$ˆ”)A£3©ùAIâŸvJ©¢›ý½ê âN~ðBYõ ¨ƒ€t Ô;ôOÈ;ƒˆ\¹À\^Ü©”RŠ•«¤Ì`fÓœ4g3ha*ˆEµX6+ŽBæ ¢0³"ÕÃTOGÓ|'›IŠRÓ°«î¦‘&„ÐÆFDPrvPª“ËDK RpBVõÉ:åá¹ãù“ùLqŸU"YÝŽþ<À.Út<›µ!„¢)mǬéî«w!ôäÉ“ëËuaŠ.ÊÑÑÑ;wrÎÒÈñññòhyy}Õý0àZ¯WËå /ܾÿʽ±ìdFÌ 2i» B¹XJɬ¤”rÎþ·l××>Úïw–SŒã¿¶ÏÄg:Ï&(mÀj±8;9mÃ< C¶ÞÆÔ——_?—ÿ½»†óßøèñþü:QcÁ 'C]&_ÌæcïÞëÞüÑ7^ùòÙØ\=Ü~XçÍïéQZëNÇBo}ýQLø—ÿÛ½xzÿåû¯ÞéÇnÝï~÷O>|ç…{g¿ûߎ?øÒ×Þl›^<>>iãÒyÌ[“¶6o†»ÁÕ#r¸! ÞµÍlÙxkJì¨dÓ’RJÖ« n9¹gí!tŠ„HkF=;Æ~¤×m‹nùqHÂÅ8Ä·W$ÇA:)ÙÒ0QÉ>Bu7ÚNK_€ ŒÈdÐ]¿-;ó-^ÓÑ ðb¤k[îòlg]önfM$SP@êûaØ d ‡BAÔTë¹åû¶‰HÍó˜¨@â Ò(Áõs‹öÍ—^ÜàÁÏþü_~ýÞ£wþ¯?þ½G—âê:ìѹóÒ}6oV§h²ÆýNGkr{ ï1ëpr{ÑÎ)î)ìáÙŠP¤E»ÀLÚ–;O“N̬6“úS4‘°ƒUˉû'N•çŠÛý0áWŸD,~ÐW…&E$O)fp7#& ‰;5…fËž}ÂAŒ`09ÃÈâVŠñäµLµ‹Z6¨Uó4´ž€Æ«M QÍÓÌìUýbðjm­m‘Úu®ª^Lµ­øP“#³à5zÅ‹YMäù!ªenR¿óß߃EjФ0€õ)$gfÚîfÍr9ŸÍDƒ"»\=¹Z¬–cŸJBPÃ0j3 ¥”qçóùjµb–ÀaÙ­äT†Í^¢ˆø˜†óë'¼óv.!ZŸöùA¿Z-^zùþ[gëõú¢Ï³f•S0ý¸ÛìÌkJ®¡m»1õp~¦`òÙ÷å»~ìùg^ʪpØÈ¦QÀ&‰ À\g)$± sÅJpkÆ'«†¹Ëª›aWFݘ>z2^ýöî´\ìÔæ§玘£A ×7À˜™vÛþÕ_øò›//)¾ýõ?½´‡e9®l6›SÙ W›ë¹ÈâñÎ~æÍŸzåΗ®Ï×g÷^Ê–G+ä–È‹ñ×û×/‡—Ÿê–?B{ïæª<Ri's3+H`Nd5™ØÍ•,rô¢:dÛeß›‰´j0JͱòŠ›Bàï°Ûc«¾19BGwË XócD’Uˆ§Ñ:sNkãæDÞrÚ%l¢ÄàP@Ê~¸ÊeÛcL(  €²yÍgm#GÍñ|4FhçmCé•5l‡9ßtT9™C‹kFÉO/ÿî¶«g±`?&S[±c¶,T"Y+yüøæG>ûô>þà[û««÷ÖòðrƒÑ90u¶pNB{Ý éñ6oò£«}6æ/©)nã` nûë}袴M dDž!‚Õ"žÌ6 @¤R ô 7d3O*Èâ6eõN×öD#NµN=éFƒºWÃ?1;‘G®¨wm2‚«‚pu2+Ea]ÛŠH Q©Ì êˆ1’óãê¤NVd¦î11#EÌjû"Ph: ¹;1Z¸ì$Ì s`n™y†Õ(ÍZ|f\­˜Ã¬¤¬È5£j¤êÔKŵã L:E2`¡ë:U-¥Tÿç”¶ÈœsþLÇÿO[ùÂmªºÕ›:¹§©[ôYŽß4vf6só ‚„ ÂeTas¡Ó³“® cÚÍÚÕÕæú½/f²’: ÷îÝ‘‹‹ 3{ühsûöîWçPndöàÁ#³¢†‹ë‹^¸µÙ]¹X;‹ÌúøâI×…að®.?¹xødÖÌZn]^¬†kl·¶ï‘3b«l²72Å ÉSÁ 7õu"(üÙ·‘ku´UŒ+`þN¾•oï:P˜y"X„GÁ ƒ`Žìž‡Ð:ZÝg´3¼ú"îl t¸¯?ºÜ7×…?Úo¬Ÿ÷öªÜ¼ôÒëâÖ)¶šewóáÔ÷ÃñéI×u«¶]¶<Û«?yb]>>=þü›ŸÏiýÖ[ÿîÅ7š¯~þ‹öûï\½÷à˯þè齓þjûdûÑ×ßN_ùñ¯lÏŸìÛó|kÿGÿàìöré_üóßZ¿ñÒ?}wþJ3.Ô»ÁC7ëŠPò2õ΀F2’øNâ2ˆJÆH3‘F|p3²–µ–uâÊiÈž s ÅhQËÔêXàÀãÐÿé¾íyvgímŸi>KƒîÑ‚ýv·½”-κnÞ4" %®xìt@WÐp'§ Žíئu*=GŽÁ†=¢á©ß_ûªé–Ëè ¢q‘£‘i°Ýz;\`†~„E”RÔfBlFy!U{I~Ú?WG¹IQ¶)ß À\µ#æì»³Óùîâœ7_…]ãç~_ü|ÂúRpëžm ËûÝæñð„±¥âèݶáb8ó—_ÊóÞù`A'öW«/w_ü™×ÞzðgØ[ðÒÙKOÞ-›>^m®,y±Y œÌf/œž\üñÛ¢-ö¹Gƒtn^½æì 禦M ¼x™€¬Éä&‹„7@Gbiã‚Ж¬ê ˆˆ¸SÎ%a¬¥vÖE\r?¤¾`Pñ@VCHK­ ‘b”¦ æÂ–“Z˨æ â®ì#±&‘ä™80»[ñd6<0–L‘¸ä²’G E)½#j³÷v“lTÝ\Íì>šV_ÞÁàÉ’ v›6¹:dBM»}s·OÿÿžpúË?$>“©8&"ð¤õT¨º#@ZΚ>~Ô6²Zv«Û§"’3m/7M‰ï¿óþíÛ·^¸}ëÁ£G•DÉ9ow½3…@¡Oã¨Øl¶óeÓ-d³»~|¡Í m‡¢e6ÃÉÉI×tûÍ>ÅŠƒE–í.íú’FPÕâàDáPk>E¢?h§OèJ¢Oüe?ó‰`wˆÙ37<iÈs ËÅBš>K~í5üý_ù‰ÿøïýÕ#ýþûÿñ݇e°r^ÂÃÞwíIsv|üÊéÏÿ£Ï}tþ`yrúS?ù·_yù ÿë?ûµ?þ·¿µ²+»~Ri%œžÝêV cY¯×-ј¶í/¯wv¾}7:œ½Øü×ÿÍ:>yrgõêW¾ðæoýÚï?üÖÃ_ýËvµZ­~ÿ›¿ÿ }xïswçw;Ë…~âçâhh_]¯ýßãí¿ý‹CNÔtí*.wê…ÀÎj5õ¥V©1’¸±Á“•’úäÂ$lYJ¯egØ; Î HîZ€ì`›#:ÄIlI{MÆ«¢ÛK–#ó@3P'†¢jûý8l{¤’1ìÃþxuË£GŠ2ú"uÌ%ÇÔi;º!çœ×ÙöÊ™Ý D&”¡^úc†œìß›ûÒ¿<øYL¡òéDµæåàNft‹.¨–ý¾ŸÏÄÙüµ×_ýèÁ£aÜo·ëëk@.œ}Ç®÷i³If—‹Õ1„³á7î^\>|r~q‹óùãÓå~½(5§¸}kùþÿ;쇦퇴ëup]Þ>>ÿÿ©{³_Û²ë¼ïcιÖÚýéÏ=·¿·z²Ø«(²H†”(Ñ¢%Y°,%+A#oyËCžóWä)±²%9²@Y"ÅÖ"Y¬bõÍ­º}sÚݯfÎ1FÖ>UÅ6A*f= îÎ=gïµÇsŒïû}õ´ä´6,Öº»‹ñôæòxy4ÚÜØÿè'ž.<¸0~î¹›/}ÿí*ÄÚ§ˆÊ'jtÚ˜m³á fˆˆH Á'x"´Õ5M"›:6o0µh-ªµ%2“¶"4µ2VˆU•0eô}Ö/|×…œ ’RZV•¡1H ‹'¡èdÝŒ \¬†Æ¨¥-R´ª–E’¥"‘3Oàà²B¬Pi=•ÈMÕœ§ ªV‹–& ¤%[| ÆÌ.g× Rø¶¤üè@FÚdaªŒê”vcª° ¶¤¬nÿjãýä³×Ÿ~êqwýåǯ>3K“ÑÆÝ×n½5Þ(÷K=Á™>’C=E3G¨püÎÄ»ÝЕr>’Nl¦õɬß×ݳáø^¹¸½NãþéÆ{ú©õÝÞõ[o5ããGövîë©%ÉÉàn Í›ŠÊ¥6ºHÂ)™¤S/"VéÁ-i—O'š+hÖê´j¡ZöTÄŒ¼ã̇NÑ…5¨cspÎÁØDMÚ1£%Ù©úÔ~S˜Ä²\EáªFß>%âr2GfPGì ž(' Ž3ƒWƒ¡¼‹÷YKÀR2³´JeÁØØµÃ~†[c-Úe©Aè´jŸòÕè}àk£¬Þÿ0øw‹òûvª-çõçØ¹ÿ¿TÅ;ç ©‘1±EÖëuŠ‚«å´JõáñÁd2ÛÞáõ­Í»·óRÖ·`GG'›Ûu]· è ¤u¬Tê¦d‡,ó›k[»kU\$«z½Î¹½Ýñø¸\.c3×éõ&Ft\×q±XT%ZE—$ð>h›-†S 'þ>x¿ NÖŠ×[Z¦‘›z¤ršL$0®œëñ×>ýì>ô`>]€æ¡8’týÁýÑå3»W/?ôáîßèö)FJ¢±ºxqxæñÍõ½Ý!-uÔéUS}åû/Ô»£^¶Œû÷Oî¾vpù¡+Ù°·{qç\ç¢p¼výͯþÍW¿ðÙ_Ë÷qˆýæ×‚õ¹¶Ø¤e½UFk{Må6D˜A9Z9X‹—õ§h!“J†x6!¸v[×j ¬õ(´bs¨Tu›ÒºÕQ§fV7žœªb­ÔXsˆG$CŒ`”^<¼¦ë±+’ Ô@¤•sIáØ)DCÒ9-°8/U¢Ö‚Æiîà™:pØ‹¹„ßÿ§¿>ÜýÓÿú÷qtoz¯‰i:›ÍO&iÕÇË»p‚‡Î‚ ËcÞÅñ}L÷ÊåÆù]¿œH*o7¼ßÁdóæ|Zå&oÆËXßÚèL&Uu<ˆMî‘fÇÖˆ%q.õ‡¾àŽi1×MŠÝAH‘𩱖­ÂLm’´ý¹¾ïDä攘˜B;/7SB›äÓF¶²s"›™ÆÔ(Ôb’˜tŦ"„Sµñ>ÿé§½k”ÁF,^[§WGSÁ:R #BðôùO^Ø~ãöí|vá[_ÿª;¾÷þzsg´±Ûûà'?•´ôðÎ[U ‹åØÜMï¼zôÊ “Ù1fG[™B>¨ypœÅXûýÈ%²^ìϰ½‰‘%=<’Ü]ªL÷—ËA/Mˆ MŽSl–ƹÔMEŽÒR -¶ MjÝB¸„~ Vèj·î ž˜3U£šFÒ4w ‘k=ýɵz7qÉ·JUBXyMc´|ŸÌƒ)",d 1¡V§p YÝ,ù6ò€È¹)$¦&1Jr­5Á”ÛK˜có0Oæ‰ë 6ß6clfjï&ç¼'oS#%vd€iÛ¢°1É{x†S*äQ~JÍñŽB±þ»ÙäìçðÎAOƒRÚ>Ù‚jÕ|1a˺ŒóÈ ’ć‡GÛÛÍû÷ïÂѹs窪bæºi ”wò¦ŽRE\ž…3»ë[›ƒ²Y,ËYðyÞ ™cIÍÉáÑb6cãà2‰2›–¹Ï½ËÇ㓪l_R¼+¢}ßìË~6±ÌÏx="W3ƒ½ N`tk¸®U5ê£>U“ý?ù—_ùÆ—¿BÞºs›è œËëêÁ[ã%wºóMüÙ¿û¿:#ì¿ôŸ~4Ëpã•o}ù/¾ü{_øþßü“?þôÍë™"F½n‘Ù¤,ßxåÆùÍÞÆz¯ë}Öïôm е­3¥.çÇãõÁV¬ç/¿üö¥‹‘¸_¬õÝ"ô¬Uj“ׯ½~÷àÆß|ûXÁÍx IDATëY–]}äòë×_™7zTjw«·EeË­1‘$†ÖHÇ0µZÒb›«†ºSo£gfnÁ&IVdT±©)¹Srß*ÆÌej UB°Áä]æ\ÇDêɤ½£›¨i„¤\sˆš¦õU)˜ƒe ÒîÅAäÀl­ã¡UÓ‘£ ä‚*C &Åh7i¥€,ðJY¢ÀÄ«”ç¨"¦?üðüØ.þ¥h Ôƒ™3²¢^,3ë—úxò2~í3øà‡®~åËñW¿ò'_«küîorï¼~øWâ‚°ÙÃø$_eYw1S’>>²vïÍ¥Ko¿úÒÝÅþr~€í¢Þt£QìÏŽNBE‹rþà\@ÑÅF'ç^稚ø!º°± .Ÿ,Nܲ*ÑÄe˜GÑ%Ï>°idÇÚ´™Úf+V¦Ž «p ƒy‚Wx˜ó”‡à²Ô ÖMad*ֺ⋙A ¢ïEÖ1Q0Sµ¼À¦£Â;gÚXJ†”Á¼#ù@¦)Æ’uŠœÈʘd™$…´wG5(Á˜˜ˆX½RlƒÛ¢ ¬ÂÅ!B dE`R8oDS#ec¨¶Ä™6?92€LÔ -BÎVÔÄÖ¤ÚîeÌ@þ]´Âûh÷?mlÂüó)î?—šFKÒº“(Œ<ôB挲˜„ºýNPôûÝét^äƒù|Ùé÷,*Sµ¦izƒþbY1;‘&Ö.sÃá0Sh¯×ÝÙ¿¸»¬¦·n¿sýÚ¸ßëź1sEÖ‰€)Kbçòù "mDó$ž?¼<ý£Äœ™‡sŽ2p î·¶†ýaÏ—u>ݰˆyŸÅç~ã×Μ{âöýåw_º}û;ß›Öé;_úWÝb~çdmóc¿÷±'êrò‰íÏ}ñêÎÿù/þÍÿýýëo¾x³)Á âré3¿½¶é·¼•ËN“#ºõö[ñË£‡ÇË£gf}wT±ÛÁ¢š—ål¾”ɤ$Ëvwά†ßùÞs–Ê;·Ÿùø…j>ô‹8_ž¿°{ùê¹n?j`µIåy°RwÁØVæl&O«ä<4 IÈÀ V"²ÕõÎ,«ùª9ÀÄÈAµí1™#$.‡Îwâ¬ôæN»F#(Qp$º”•$ÍÔ¤U1<¼äLÈTUJ :›É1B›YÁur¢h¢mBƒFˆ‹h˜ J]BÓ/4ÙÈþ Dšð^Üç©ÀŒy"#i¼aä°×Å™>ßxö#¿ñ»¿uøÚ ß?¬o¢á×ÿ!þËÿîS’ñ޼úÊý×ïw‹œÅÖG[³ñx2®½íµ57ÚI=ÕÝ8»sxoöÊ7ŽŒg³õþF^öÓ€æuÀ•óÙÅ'®Rè|ÿõ7öçÅêÖ*I½ÂU9´ ï°¨ †.£Û+,±¥JjO ¯X*m‘z¯‹5&Û»wrL]ð.p;§Ø²âRŪ¥hž %PÒbÄMB§³ÜZ`'©ŠåÂ4žŠÜ§fîIJ˜g%FÆD5aÑÆ‡¦f§üþ(#Kl€%@ˆÁ ÇÞƒ$ˆ‰¨%jÓÔ‘ü©¢7šD­b*Å"aHd§J(m ±ª +nðJʺÚI¼¯ºúÅü¨gõýÿŘ~ãü¼ °É3b8f¡ÓÉûk½:VƒaÑãÐëYæ‹NæÓé¼,—›››Ëår2™ôû¾®“žx≯}ãë!„–"P6i8ì¬o =kµ˜$©«j¹¬ˆ\S7sIÍÞ™Ý~¿ßTÍt²„9WåŲ:>šÅL¡-;ä\»c§üÍí狀¿?;ÝØà Áˆ¡téÂ¥a·÷àÎñ¸ô¡?\ˇ#üÿýï~àCtz»“…;Üÿw>–Îâ´Úß/?òÔîK_yîyð?áóŸÞ½|þòúÎK/½®µß\Ë¥ŒË…:P¹X.åå³;©‰Õ²<»½¾³QÄrzûÆÁsß¿{|íèÚåëE·÷¡'Ë;ýoï¥;÷ëK—6/`kt1›¬»—Îu>òøãóê$ë)ÀkëçwÎ|hk}˜—$j]¢×Çiªª)[«—"vŽ„Û+/I»”²@ïfîh« †y¶èf§I ª«öEAì;s^ÌC3Ô™ÔTp ‰“B™LHÁñiþ6©èjTØ’?œÌD#,òÊ0Æ€©ª%[™©'uk0r×®ÌÌÚt§JEAÚ$øˆ´ì8±•”ñoÓEÙê‹§ —Ä›=.nâÉ ¸º[`Vù,.nÞú£ûg&ØÚÄgƒ>ÿûÏøþôxz»÷àðxr0âò^ïåïßyãnæqrŒÍÅx4;:ž€ý¹+›{¶ÈÕ/üùüà®<ºYôºÞq<»¹{iW>ýùO^»{í­×®éñ¼[cvÇ*;é^èÔqµÂÃy¸0bÁY3#Jˆå‘a¼|¼›ÏÔ‚°¥U(ÌæZ“ªƒ÷ä…ÔØ’ª#˜ªµû9~Oß¾E-«]UTˆrG]ǤP±PÎÎ%õH)&®!N9D0[LBe£VU5U13˜Cˆ¨± YdNÁSpÄæ¬}Ðlõ&ƒÑTUS„4²«µSÎÈ·b5(ôÝ„ØÖÁrj'>åà¿Wß 0ÿ£°ŸŽø™‹2½aþ9Z_© ¹àIZ…ïª÷<[Tª¾ŽÕÖîF¿ß½wïŽi yvóç<€”-Š0 ‰øâÅ‹Óéôø¸\[ ëë}çÈL†Ãá çÇǪzóÃÁ0÷ž<ãhÿ`k}c­¿u÷ÎÁøxÞ,0›Ö7®/RZÑ>LqêDhB¼b$üðMô^7ÿÞ±êœföÞ·•Â{U~Ržö»7§÷³b ±*< œC·èäÈÝÞd2IuÃYgsko4ì=»³±ûÀ³”ó+oíÿñ¿ÿòøÒß5µª È\zýåïñÜɽ—¿ý¯ó Þywƒ’¤²LI™RDΣµÞ|6Y[ĪÞÞ¾äy¹±¹õÎt¼½Žs[çPÛ[7^ÿø¯<3)Ë{ûæËÛwïiLg÷.T³òO?ýàöµãyó¿ú²Ïu yæÙä©OøìBÏùz<ë­mé '"ÄÜæP¯ø ­ÌVÃhC&LJL¦Ñ m|&{(µy:&´MócfÏŽ´‘¶»"¦@!KÉKJ1Ú>Z¹‰"‰4þ bNÌÚÐT@¡dÌ`ׄ²‰&"ï7ÎŒ¼›xRò`¨$ÑFRcÖŽoœ J n,Õ•ß²¾ËaÌpïᙘ™MÄ`B”÷‹z2Õóëkën|õ }ñ‹~æ#W¾ÿçîMOþ×?þ“['F|øì¹ÎCßÂ$ÍNîàãøä?ùé§foÞ»9ÍôèÍxäïLpõqP¤Gÿ°úîäÁk÷ŽËo½þʣݵ~GªøáËMïÌníëýéñÆÆP× œ)Ü™üúñÛ½¾F–¢>qÖ¥ÅÒêy$GlØz¹—<ÅFE´…{µ>‘dít…vÁç*ðä‚ËbÙD­yØQ²$ª0»@N‚–çžÔÔDW… !˜JÕD©@¡©› Ñ*i£H0ÄYUƒlfÉy Á Y™š¦ŽBä\.TJ£d”{rÀÒ-°×Oµ¥”jSN®ŠcLÌ›œ2O¬–Ìb¾š´ÄŽùH` ’v¯Ã\Cœ#ƒ™ žÎÙÉ#“GÀ¿äK)Õ±æ€áZ‘wCÖñ‹r^tVmøÑÑÑl69::ÊBKwCl³ÌTQUq:ž9âN§Óé”"1΢2ÔRl潂CFyÑ_–ó(Ïœsd’ªùÌQð®Û)M7×OEÝï-ާûÏèŠyG]ç‚‘Ï-3ÊÌåY6ö«º”*n¬†ýQá]=™–ßþîßýÅo~ëû¯¾u{:7u= ¤FÕ‚Šj©%R*IÛÄPñÇkƒá ?ŒT•Ë:Á%æ˜b¯ÈšT6.ýîç>78ÿñÈçoÞ»}uû‘ºl¾ýü·oÝx»ÔôÈÃç:â»Ï½59™ìl¬ðñÇîÝözŸö·gãÃ:-þü/_˜Ü=¼?ºÓ[ë^¹è:Y0UÕÆÈ 9ƒ¶èYÔXðDP"JáSŸñJ8 -ô•a? Zj9-«œ3R;S¸…z˜á”Õ¸1NÔ¾% 4J^UJ€Ò*MÊ`Šv¦5§Ä¤ 31µÖ”ùžÁŒgì Ä”ŒZ 99ãÖkllFj,ê…ĤlÆ?Ú1ðÞ·”i^‘3oZð…Ñzsrpñ¼ûÃôùßüÍÇÈ-úÝgÿêkÏß|õp–áÙOŸÿÔg÷®|DN0Æò^Ýϳ§)Bwwñú^6 ¯j8K5I¬»ÅâÂÚÈüþ;·×Ö.}á}þzqç/þ÷çß,||ór'Ïßzñ¢/ËÅx ~cïlïÌ™EÁh~r2]y´v’7!+ëÆ$‰$ÓVöd¹ƒ) ¡Õ%´ü-]½‘ i"€<Ï{yQV©0­¨ëL¢¤-”€™Bæ‰ÚI™ˆjrD¹ÙÉmæ¾kÝ¥Ö8ïÌy6ªTh£R ¢š˜ Ž)A™œ:Ÿ ›#4’$™:À’ouZf±‘„¤Òh][ŒÛ½(à¢ÔÎÌÀ°Dh<Äg”m»ž‹V£iÒê`cSË]!ªj-DŒ=¼÷ž½›U ¯wû¥§B)XD@„n·l©ÆÓãn/«#ªªJG‘ ³Yê÷šÁ`àMYeY6ìõc”ébyr2¹}óÖ|>Ÿ4’;ô õûEîË“"£n'¬º.îînoܺuãÖõd|7t»ÁH³X–ãñr6µŸ"\ù‘æê~°9·NS6¥ÈC¿(ÖúÝõ‘ 9žï§ÔD·QÑ€$åÁdøGú—/¾þê›oMAÈ}S§¨ÄY-$O‘$&KÜf\PªÔ`‹bå½¾R¨ËE„ºÜ•MÙEyVôò½½ó©³v¯äÝÉýy'ë<üðÕ7¾ôʬš]~øáÑÐõ±Öï®÷:÷Ëùz¿öz^7nÜÿƒß}öÉ>[Åþµ›³ùx™ùœ|¨¤ýxª2ÁÐÂúŒXI5€EbQ•VC-‹N‡+…°Á ­àÆœ™ð Ϩ%D’­¤È’Q4ˆ š@Òž,§Hg=uØv­0̌ɱ)DÄ9s-?ÁŒp*ÃÔVõ Lìà¼i› Ñ&ŽTX•H”Å9¥ôS‘A«¼Z;–-ÀëY!Íâ©^_Òd«l®}í«·v«ËŸþ(£)kX§;X£‡žþÀÚÄîÍòäþýç6ÃÆÙµ°½S?wãµï.‡áÍG®ôg{RO|-É÷‡ÍÝî¢^îWwŸüÕGŠ~÷ÌÕݽÇÂþëñÚýëÛwn«ßŒ§™ ’óÓª¶E&1éUÝ3l^ Ô8ä™0"Qt§ƒDÍk¼µä­ÓLm¬4¬«BÆMŠÌÜ)òNž‰kHŒ5±ãFjf ŽTš’±÷ì<;fvð $S1°™Q³Ä]ÓÐf9‘’±$5kÔ¢Z-H µ®`œLÖãÈ©p¹äa6å€à Î`=8 ±²X+‚À­üO¦Ð¦•A2ó­\×EÈ>ßõC")›¦D]#)XÉqp>Ï¢4U¬bªÕÔ …wtË„_úâ^61dƈÖÉš(T—ä”™MTTP'ï)¥^·;Z[‹QRJMU?xpÐéäE–;®ÅÌ9ôú<ó"MQd™7‘XÕ•#¬“qïøè@ޏ“Ö/¦cYÌ—UÛUêNG{ ™%qÉz½Þ°[yæÕ,ô¨Ûíkycõ|1-R ®ãÕw&Óy§Kƒ¼×D”³¥ò¬[W²b›£vºA^8f¡O…ê£ÝõMuT§Ø {C•ºtŽNN¾üØ÷^x¥rÓé÷¾º¾³f¥¾þÚ+É–Ï¿t÷á'²á(oRqåRþø#Oq,îܺ¾·½ùÉgžv]çâÚxr¸½µ·»sñk‡¯½þÎÎÅûľÓ¤Æµh<2B»wTSM0ƒE@Á²2º¬n¸%ð‚¶¨µ|´T>"pû¿æ•W ·6%cÅ!ŽBAA@`m Ÿ¬ôæíðž#”[(ZA# Ž™ ÁDU 0¯Ê«áJÖ"×¢®ØÌZÌü©:ÏŒZS¾éŠþwQ)™™[-\Zå3u×,v€GnïÜåµÓý׿ýò·¾ñ77ÇõK7FôØÇ¾|u»3E#Ñ l°¤5"·>¤UzÀÊ`K‚SQ‘ÄÂÁ1)%AÎ-ÿÃúà>…ÓºA,‘b Ì:ÎÁ@šLÉ’š¦–`}ö롪ÏC}gÑTã´l p¹ÏƒzöÞ{ï«è›X©Æ–AÔÚNÄì—œç¾âa1œ9dE(z¢zç@‘ç1FÏ>ë*å!ïvò¦©IÍ;g‚ó©hí»ß|ñÖµwÖÏìmm¯KœWÍ,Bž{ñÕ{c~ûÆøæý†ó¾åÅ<Æù²ô½ue´9Ò m©0[\²6ª«Ï08#&SÀÈä ÊÄÌFĦ„vÒ¤´²¾ÂÀ­Ò.±x¿ lSZã¢]x¶ôÖjÒÜž€fmØNK Î9ÇJP¤FM‰ƒz(ÃÜJ×Òž7 &¦öÏœA]ËWVq"J ¡6Y´È·››vàN¢íÚÑCsù¦ÖñàZäâ¨.'ˆÒ<8IK‚c4²ÇvºçFÔTãÛ÷oŽoÇó»ÃÍ·ç©A3Åç>ý1¦þí7LæûNuRêÇoψÖ¸Ø+¤[Z×û­ü8›Ï®¡RÜÛ?ºÚt]æò&„Úu¤Y i­× ü~=f@Í)cÀ; ŽÉA½&òïë ®ŽŽZz?­ú÷ÕS¸VçV-ËÅB¤j7Yõ¨‘&À Cè†n‘穬E›ö( ûf.ç夔­ÍaÒ´\ΗU-H-& DíáDm¡ÆäUsP@&H±Eá3 ¸!U×AXCg«èõ³œc½ˆåýX ª ‰ˆFk[Ît{3¼õÒ›¶ˆ®L!Š7ñPßDfXl­uü¤\ØÉá¡Î$©&SX„4ššIì€ÌgygKZq/ù;wct{ÙÆöÚÖÎÖtv|rrà<«ª1§&f. .«ëØ”M7/bUWU5ORR3+Š‚ˆŽŽÈ2ò¡¡QvðÞíî‡Ã~¿ß…ò ß1•j1oJôº€h¬“H¬—õt:›N5Õp«Ê~j ¦ÿ_;yBYV‹àع\í¬mtúý£y9NºÙý‰›[Tá“:M—ˉö²ÜQ®¬›vkjiÙÀgP©œnåWæÿc§;âªÏkóÕ¹½ó]¯û!‡N±5ùÁú晽Ízà_¹v­Rhkw¯‡µ‹¾N÷ÜŸ,ºòÈõ׎Žœ;¿wrpô¿ò¥^Ao¿ýÒxZEl|û•û÷š ?3ÜÙµ/S„ãäpÊç‘ÖDn󿕹Í'U8&ƒ7eÓÐÒø`X j¬skSÐDÚnç¯rÍÈÀº Ø!\Ë}7Uakáªí! ¬¤Ó­m^à3;ÄlÄì=›”XÍ™¶b6¹Öµ™ žVßÂØ)˜’ ŒŒ`Ž`¤Ìiµ$ø ï¼ã•£ªaY‰¬QKÍ®gn½9˜  ¸uœNNpç>æ‚Í ì­[îæyljnï>*ýác¸>ÙÜ>®æ|ÿö„×Ïb÷êù½˜½q«>YZÉ`æ‹ yÌßye>ØÅù'ww÷ÎLðâÑíú©³£O?ùìás¯ªÌUÚöå‘?·>st¿žÙT¹&…FÔ I»zÙ´`&GÈÈ;ñL™£ÔÑNg2ü~ý¾™‰Ä¦©´©µCž¸ëŠJªµ"å(6òî™­íµáèxÿ ZT©–Ï7‹~–å õyl6B'j]dE…8 Y5-šÜœEKImÒXT3zó›~Øñ…qš§¥@Ø{5j*\  ³^ôw{kÝn&2“2R²:ÕÜÍ÷Îï=úÑníîñý»ZXZäæB %­¥¢õõÞFgè»…Ï‹yUÏõ!çªÔ,ê²²¥BH êT³‘kÓVí—¿¸ð9z½Î`mÐëwAj&!÷’’šv²<˲~§\VÎæ“E¯Ÿ›BbZ.—M“¼÷!˪¦ÉóÌ{7ô8XŒTI­“‡>õáƒÃ»Ü«ËÙööhÐï8çÎì¢S EB–e)åÞ‚cV€æT˜´Íüø}×ßWq7v¦ 6Öu»ï©®F#ÚÚÚÑRúò`1Ù?9™EƒåÓIªS'ô²é¬îõz¾ÛÏâlÑTe‚ÌCò¶\qW*m#MœÚÍ&ШTRÖ×zƒK×¾ÿÆ­û'[Y“–“*Ý9*3›-‘uñÙ_}ä™O}h0rey´Œ‹7Þ¼IòßþúµÍÁæÃ—ŸØ>³ÃÔä½¼NõÑ7îß?»äçQ–"ù`\§IÒ Ø@l”DÆDâ˜áœC0óPv¯pš<̳±3…:6gÊdÖ•ÃNƒäáHð R³m+{rÎYR£„–' mÁäOïh¥1ÄÞ¼X9˜ ŒT¡ê@¾ušª0ÇP0˜È©ªƒz·ú½Ô¤-þ*Öæ„³OÎ5nµBø±w¿vàn­•æÀ_ô œßëí­Ål}ö;’wñ?þOøÚó'_þ³o•v8`{ WÏ÷PÞ[”‡·ïmoŒzúæÉò8ll‡NçÎk·oþå_ïmÝôYçØÅr7Ätrq.pŽ£ç3±¨»gvžøµ_9¦øü /Ì;<8wîÞ‹o‘¹¥¦ºFž&Æ2„e]:ç2 Ii,V$-¥EX0km“’ÚOOíšúC¾-µà\‘‡"ÔøÂ0ïYpÍ–³y‰+à‡>úlà½E­‹j髆æK—Y^K_¼MÏÈ£gtCÈ:nc)³ym)yÖ䡉M`0Êý,3JZ¥ ÆbÎC ®‹|Ƚº gФ¡`Ÿ±Ë\ÈzÑú°¿ÖG Ù|¡Î’FS!¢NðC¬Ï–Ñeb¦ê\Ȩ¨¬i ’b“$Þ¨7,Èc9›Ï'ã>å«ÙàϺPý[ÒÙ¦TÏЀŸzŽé=Ô§Ó #ˆ¡Èh¸9 úQãñøhQ-È»T7Þq·ßëc¸>9ò“ãILMY[ø@DÎTŒœ‚˲N)õGEØ »¢e§_œ=³3ï\³ªgyÆE>dæÃÃÃ{ûu7G]/šŠ²œÍº³É²œÇ¦„%Ðû G¿ˆiÛ¬ž^ ô}oÉj˜pô¢í!ãùžøðÚ•½íñýƒQ7v»RÝšÅ2–'Úx™•±|p0–’6Öû”aR.â¢'Üú¨ÄÐxúâ¿1Hl®/ǨÑíy³p°?é¯÷?ü¡Gº˜ï߸K¹lîm?ÿ š§îY~øÑÁ•'.þƒßþ<¸<9¹·>\{æ™ÏÞ¿ñÿ¼òÂÛ÷ÞÆÆ£áÁ;G_øÂ.]Ùº˜–Ó¯>ÿýI…½bëÜc›ÏN¥Lº$ŸbuŒ^¿í¦ ƉH ‘ „J3¡ÌÁ11 ±3V09%gŽHIÐrÂ#‘ ²­senuì ¤Ò`œ3©K’d&ÒæJ´.C „ÛD«ŒAOì ˜:Ž}¦j©V…)±ãо•Ò^  ä”•´6×¢ËѤÁ´½g+™'!V¢vî¿ Ék?í2Ī ³Æ ÐÚe·Ñ Û}<ôÄ®áî‡>óáñÍûûó|oû¹õqe Cpˆ†»ýº[s½_/æÓ´–“z´ŽÎÆúhëÌÛo\{p°Êc}”7e]×X(òÓÜ•ïì/Ž^yþüG¯¬ï¬Ÿ»Œåxö×ßüJ1›ndðE¾tõQ žMâ 3sÂýAp!w±°¦rɸŜ£¬ L9P±˜ÔIcÑV£Nhé×§r'gÉ™ö¼Û(ºË¢ÓÌSÏe›yo8ÉTiR[£Î#ËÒl¹¨%°g!E\j´IÊ]n‚e³·a{°à|%òä¢jKÈ98˜´ç¹SgšAAœ šFU¨¢©ÕÏjáÔÄ&sb“´˜`¾´J,:%×X¹?9¸~÷ö­»4¯Ò¼¤²fŸg.d®ë$xøWʽrÒ_ Ù…2F3X5-ª¦Bô½b÷òÙs—Î ³;wn¥Ú-²öcA?KçÞz.þv_ÿŽ^T‚9;ÅðÛ»ÔsVcïCJ1!ö{½ébÞéø&&c ¶9ëeµ–=×ÙÞÝVKr Ie:-ËF·É­­­÷û}Ée®Š’“«WÊ IDAT*©8a´>ìõÃt>_–i8Ú¼uëBõàðÁ²)†kÁisíæþ²œyâù¼^[Žiss´½{vYݘ͚:ÆéXƒ›yæÙ$-&H ·c\{_ö»–:úq;ƒŸü*›y )¥$pÞ,€%‚¸ÓÈ##®Ï $9FæA†|0ÿÿêc¿ý…§ïßxû»_{ùÎÛóp£ÎÚÎ4MNN¦MŠý‚ß[ÆÒ£r!Q Á!hZE¢ÒJT§„‹°¥%5²@†¢“~x¼?;sf¸88œÐúhrÏ0—ƒ‰Ì®~è‰ý£7êt¼³Êg×n¿:?ùä:½õý[‡ÿà³ÿìKôWk›ÌùÞµqÿ×Ï Â¹ó;×nœ”@w½­­|ØçžÏÖÖ¯ùþZL)¥TÖÉ´N¶Œyk%!8|‘›c$mµ” ÁÁ1‘c!$HJH‘!|K’aÏ–ÄšÒu2väœ#SQ3M@SG5‘$ŽìU=ȼ#Ç.IQ£ÀìÍ9%§$ å¢çs'QóÆ-1{£vÎ%¨ee,g—Æ1¢ýYaF’LDà½Ër‰ƒŽ$sr‚$átø§„dmèƒ<|9ª—õˆåJŸ.ìøÅü³ðÅòâ¥Ý~äããd±¸{û¨1lnâ™|ö;ÜlÒíß"—*H¶Qùn¾UÖ^j«Æu3÷ç6/ÜŸO»…ܹ9׈zîbýâ6¯å¯¼öÆúÃXˆÞ»~}Çw‡ q’"ûŽR„ ÝQgú8¶æÎr2Xš¨q ÐÜ“³ö;ýÞÆúÅ=ªjY“"Ë»\4±©ÅAX¢Æ$fê ðUIu\‡ŸÖÖ-©\î6Ùž6ÖÜo¦^™1â¥hÕɲqQ‰]ðE¶¶l–cÔ,‘Eê:ßJ¶lfå¼LªµÅF¤’rY§ÓÍò&¥ª‰ÖÄ /!8G1 URæˆÑÜr)˜Ù²§¹TÝ“YÍJpq¼\¹ªjöê:mnl‡¼³¿ßçpŽŒ¬^TU£jhZ°`à†ÃaY.UQôú[»g]˜îß=!ö1ññädÿÁR™ËZ´8Þc÷ü­ ·ÎÊ÷Þ–ÚSr÷ 㹪ômeË(sÀÙ§?ö˜Ë§g/\ýâŸþË×¾ó›¿ âe&L RÔ¤ QPJ ==ÞÕ_íþ9&$g§«,FŠ.šYƒØßOKØlØ=óñÏýÊúàkßùz|ãׯ^zt´¾.áøÂ¹þÁÑ­ÿã»ùÈcxpçæïüÖï=ñØ“ñG_}ùù7Ò!Âæ;oÝùÓýgWŸ¼øÆ½W¯ßºÿ[¿ýto÷ÒãådiÇ‹£ãå:R¬ùµÑ¬®àØ|7’6RN«¤ 1SReUHÒhdIIÚÔ)Q@U5:‹°¨lpέ^DKj v`1Õ–œo_u¤Ä ™Äœ€(;¢NÙT ¦¦fP€IM‹Bÿž3iAIÔ^AVIÊAÁÆh,Àj³M4B¬žÉ±’%Óæ]SýÐm±ÓCT$É|JÝ5¸ÅXÇ8÷Pç¡G·L•®…so½þæKoÞ¬ ¡ƒƒ%Ž«r´÷D·HeýfÑйËD=]Üš¾}û•;c}p+õ;œ uÕ„ò\t1YSa{.<´Ç›áîâáFGëèƒ;÷îßÂpáʹå«÷R™ªRãI³ìÐ2myæ'‘óbÐï…~¾Ðúx>Ÿ§FE$DP‰T&«E[ñ ÜÆÓÓ¶Ã )zE×e µÌÇ•ÖqYeðnŸ³¬l⼊•Èúö†ó¾ŠM5ÑÔ`…Ï ŸVÓX7MÒDÂŽ2%2Mjbˆb‰k¦6Õ.F@*,}Ãæ VÍáÉqMdIÑT’R£ÁDrøÆR›DN&\S:šÏ"M´ù¼fp ç@f¤FìŘKXÇl»ë¾;ð]OYÍRÏŽs8ö91Õ9üúppé¹ûËÌ™ª¶ ?ÓTæªßûqƒA E¨ãÒQ0èæt8è™×¦i&““¦iˆ(¥B e‚«ª¦Z–'GÇš’gWÅ™3gnÞ¹;[,àXÌæå¼ÓéøàœiÈ8%UÍ‹Ðéä´³³ÓëuoݺզS úæ²õ5N1LÓäd:›…¦©³_xXê? Vz+’µ´s~Jèu±yéÆëVãc}ì{Ï¿þ·þãþæ¥Û×ßøà^øê[.ÔŸûÕgöÎn½øÒó¯ßzíÂ{—.\¸5Þk¨¹?Xï\yìÒÒ\¤ºÖ’ÙyvY Î-YJ1Íy6Õ¨‰™¦$dÂpBÚzV<ó#O!Ë”%S•vKB¤¬ S pÁàÈZ {˜L`fäŒC¹§à³NŒTµI*¦” ¶â>«¦”Zƒ$³sæMZÞx»¡v 53%çA`2Ú|Ï–{)¼Yrð!ó>ò®5Þ7í²”V©§T!EŠ$–!@O1 l|ìÊùO|â‰ÿðú_Ý9˜å{‡¯ŸÜÝFg]3"Äe¿œów_~;jÏ¿0¿‹»“æ­hWÞìv¶Oʺ¼[¦‡ûƒ!Š!2¿„ù§>úg¨qs{c¶´l€Xc&)äjªQœ:ýÐÉz½4èÈ"$I¹XÖ–¤‘”$&›Í¦ËË%U•Ö57óìÉ£–zúWÝà@V“ÆÀÈrmÒ´‰“Ù²¦X[Å>³œ8£¥Úœ¤±ÔqÊ, IY !#ä!+[M‚$06 ÆmN@¥5d‚Y4Ä6ø„™]+„–‰o%SÜC¶•÷û>o ÍìA ií¹"âtQ§Z!¶‚Ò ‰,êJ“°˜˜þ¿Ì½Ù“eÙuÞ÷­=sî”73+3kê¡zîС‚ DŠ”B~°dEH²Ÿüà‡Ÿä7ÿ/G8ìp„ý@ÙrЦMQ@RI±°žÑÕ5WeeVæÍ;žaï½ÖòÃÉênp²82*ê-ãÆ½÷äÚk¯õ}¿1+ÀІqQ9 òÜøN]Wdz÷®~¼;˜§õ»B ò×éÜÿMI‰`=ä¼Õà‹:6d‘[qB±‡¡qLë&mVmo¯*ŸsN]ŽucÉX"ïƒ#W×íf³yðà^ÎØÝÙu.´mÛv°–¬³EáÃ09P¢ÁÀO·ÆãÁp:ÝŠ12sÛÄÅbUòM§ÕÙiÓÔuS ÓãÁÿ®>¤?]í‰Î‹;=VaözWŸ1@urïìøþƒ—ÓÑ•Õ&Ö1ÎëZM çÇ©c”mÏÎþ,àœb}¨J +ç_CÀ D(œSÉΨ7Ø,æÝºÞ¿páำG÷·óäS;ÓâBاÙsÇZ}ëK_ªªááÝ»›Åi7ÓŸÿ¯oNÒ—¯úªüÂöË/½ölôÍoüú¿=êbªϽô•“Ms¶x”ÑÙ²lNîÎÀÚ±US…÷Þ…¡i*Ç- ;†(ÌÔK©K†{+±Ò@&xò®%+qähRî*€%k¬Q¡¬ÄÖ‘ F­Šr¶i²’ªR§ê”<àÉ’³e鈙 }w ‚¨qÆ[kÈ5½ì^HX2qO4eªùÔÍdUDt®¯u¡W÷¥+!T¥õ΀Ué<§ç'Öa]ã*#VÚ¸¼eŸ¿¼õÄN~jkËNG¼^ÍOñàðöálæFÈÉEá±ÇzF·>>^Ôî¬ñè£ï.ŒoË©ð$§Ã5>œ›oRºxy¯¾wo´§¯a81‘¤k–ÃÁ¥Ë#?(SKΙ:² hjÜ9>Ú†:/ÁY7²Éû& ¯SUb®»´n74Y$Û·'¶m5ŸK!èý †ò¬׬gÔÛä(úÇÿ'm³JD¶L¹«Û&åÈYaNægÆibÓ£+ÇÁpHÂ&W8ŸA9g‚XÀÀ”°Î8§ÜZeQŽÆccLìr;1bŒ¸±µ Š:öƒ½b4²¡•ü@Lð{ãiU”›Õz•Ù€l°Áèrffdn•=”@˜Ð.©tbEI§E)™g›Å£ßi†#Ÿb—æË­dŒüÓ&…ÔǙޟªÄ•çí8£QÚØ€àK_ühkRw‹®Ùƒ¤dÖ‚û¢&Zxߦ´^Ê b8pd¬ñ©íî>¸C¡p1§,É+š6M»³[U(Ë‚Qd÷)ï]½Y=zôh³^3ëéÉüÒÞp\M'§îß½Û4MßQY9ãø·ª~9E‘|ž¥Ÿê/ÏíòJgÄ.áÆ;÷ÿ—ÿþ}ñÄÏÎ~üãg‹äŠ©ºÂY.bôÚÄ"¬9+õ…|º¦£óõìçWÝýÅÀÆ»”;”¡ Î/Of“iÆï½ÿ¯ùÞÎd2;F³jæ‡ïŸûÊW/6'xû®ÝZœ Vÿì_þg®,B÷ñÉ`y¶¬]°¯½þréG~ôñ“/yéÍë7>¾ñþíãÕ®ÍÓ/\}´î®ß»E%iŠÈRs.)øbF¦Ü*ÛŽˆÌy8 TUˆ,‘‘Ìà~5*°PORYïµ" ¤Ë½ÈÍÀ¬Â³úÞ˜’”’/,[íQà§lUdˆ5Ld@dØX8°Š!W†!oM°†ˆ”E BU²áÔSúA^VpVõ$¤"Ó“Ç> î"gCYøÒ©CŸË?[P}úg£¦ŒÉ <õàÙÝACŸ¢~|½Lø{¯VØÙûØÏö·qr»K RÙaŒ+ÿä“Oó‹Ë޵ܵ²Y'ŽMW‹2Ù>º°Ïä÷>–¿gî§JPÒsAѹzEa‰Áë¡èøö¿ÿõW^ù¥íjÿÁü>¤]ΚÄQS§MËœ¢pýé Ò«b jzsP¯¿è_÷|PfÌcÎ¥DuÆÅ¶+ÈŽ¥³bW/ï¼òÒFƒòÑ=ùîoݼxq{TU§GMôŨÛ]Þo*üñ¿PËB¼ÌÏ\ðí‘ß½s8Ž–mû?ú£ÉN5(ÑÕͺëă‹{O?ý$Y“I7±†Šžè„5u9u)ƒzó Î=«,=²Šs¦Œ¬À"’2DÛlÉ{ï7VMbe8ËèŒ%ëÇ‚$Hj2ˆ£MJÂè—´ÖgÈYfd眱B"b½ëóY­!fŽ)©ª7AÕ ²PR+dɈ ²ŠÈù,RúIq/D޼/‚:Ž’òg«)=ŸŸég:a–Ì€fÏìøé>Ò×xê2©:lÚ³ÈAœ`3›oΦ¥ E¨§Ø}òFÏn–]—ëùr#ËqÀöå&×̵o¼øü‹ÏÔ''‡Þ¸¹„Ql 'Û%oaH´vðŠjd*2¥UëÐvP«aH>9â:ÖÒ5ª&„b:„¡½uçD9KÎ`%ÛË;YÀtžýù…PÏÖÌ“:oAÆCЖú)a¨F8$ˆšÜ È B¤ª‰Œ a8­kmל•[ÄXµ®ƒ œ<'Ï%&ŽY¡m×.Vkç\ݵRB.:pÛzc=S¡4òΔ.x_v:“–@ ÞlVœcÓ4’ATrN$µ)Æ®Så~d¡æ± ÎÃã·äˆú¿EÎŽ¥*2.»VsÍ ÍôSgb:•ÇßÜy#ß×°DOGdÔ{»X­Ú¶69gÁ”¾˜nmeV°YÚõÙYKŽ<¬¡òÊâl`É zõ+_nÖ›wÞy‡EŠ¢´Š|õêÅѸmWë(Â9ç¶k³縵µ%"+¬9Iì46Íéɺ٨0T C|!"*íßîTæÏÐá`úY@ú`ClI=to2=½ÿðƇáÙç/.Òrv¼89•­½AQ»®Í1õ]x"!²8·v«R?ðüür›Î_©?\Ö‘+ŠbyvVc5åfÓ5ŠétçäѼ¼¼5÷îâ•mSç»·çWv¸£aùÄb¶~ûŸ¬d†‚_yí û—¯|ôã›Ã½ë×oܽûà«_{ak{zÿðÆ¥k—žâI¾wïæáÙxê Ür¹žníí^Ø?^-Å:„ÖåÈÁµÈÐ^4ndV’,0Öz%¨5ê ° ʬ f±êÈP°¶WÿX§9'c,‘+³%"¦Ì$çó†pnPAœÎ^ŒZ"ƒ¬Æ˜þŽ@DrNªJI»¬9kR¨±PX…í2Ø2X*ˆŒa2Ò3 ¬uÁÛàŒ ɧ&ýL=¥zžm@ÎÐØ» rL8¥â²ÿâë/M^ª.òÑ΄pöðäöÑ6Ú«“Ðlc5ǺÅý[éðö]ÿÕ½òÊUúð­£Þ,î™VŒvC‚ O\9òC“žá©Ý—÷ÇÏ^h¶°ê6³“Ó”PU˜Œ¶/n]œI³¸¹yôÀµ'ªØ ¨÷ì’ º,›(ÑæÕf¡N;¤œEúŠl¬SwñâÁr-–ro;rD輸ëçŸJEaœS2¢Nú´q†Óf¨¶ÌÈÀ°äLQ˜àpß™)‹¨ª„ÊQiJ—;Z¡‰È±6c QªsÜ ch`ÑÖq)¥:7±„cpÛ4Ö9fÎà,¥@³ªÀÔÄ-eãlbZ4« 0ûܵŽ4w`Erð*̪š¢Uµ R¡lαl,O°”I|á[nº¶EnKãʲ•!£¸—–¬Ò£.ÝŸÊñçóÜ?ÍÑþ ûNDÙ$¦¿`ìBQŒ‘Y­7DÚ'áJÂÁåéÎî´i6m¬ŽnÖiê,A•꺕G³j8 !xk·F"")a>Ÿ[ï}›GóÓk¯<í¼¿u÷Cr†˜.fÔÍ<ñ’iË;=µMsùòn5(ÖëuU†ãÃcïBYT›õº©eFËû÷Nîßf(œëë‰U1’3Dõ?^NÔ£«ä±rÒ˜Ï~±ç¹÷ñ‡ÌÜCG81yGú8ðCûô-bRhÛNv¶7›³¦É¶  çpñÂTë³Ã;÷åÿÕãúQóÓOâöÎöæè4æ<xŸe±âœxT˜˜šþ«´Æc{X˜rRÍ0EpƘSJ™„É %ë`PÉÂÑ\ØÅOîþûïü‡ ÓñoþÛ7.ál±–ÃÙÃúÁ­›¯==˜bz0RWÿøÝ[—¯m·&?|ç]¸2;7º°÷ÂöTBññíÛÓíçžûâó¯½4[ýæýÃõ¿÷#"wºÙtÅÎÎþÞxÓµ¹‹ŽŒ›šœ³ ‚ŠæˆÜB©k k²1lÁ˜Ê²ÉœÁ²)Õ€…cÃÙ:‡%s›7BŠ¡Èš'ΑªP–%Cc—¡o\YŽ`c“8Âz¡œØ9{¶\xï3*š5“ëmF¹n×’µz” F€ÔÇðÞÙ’@JÎBœP”H-¹Ê:ç | ”œE4†ÕªAå¶ÏJÒçç¼ü^|~²ŒËí'ÆÃÑÚœ FÅoç¯la´…õ&>ýL•¨ùø.‚â?üÞ'¯¿ºí ûn°õýï/ªG? Sg|«£°qÚz}âòþÐðéý{ûOMªÉôú÷î?: IÏføÖ?~ò•¾vzóìÍßùAw—+p»É]nuñd3oÛ1¤(Ù+–å¦Þ½´ÝJÍÑ8›“ðf³Npb«.RÎä\¨*ßlÚ”xG «ôGاfšþ`5YºåfàÂØ»£ ¯35ÎÈŠD4eQÑ,äí`0¨¶Æ'«YÎÌš5)+3’‰±hb0a%]e˜wõ2³h÷qº8¶KßY‚-‹©‰¤`\féÐ:X·A—; ãÜ(fÎÍYÛ3¤CNH Ó3 6À¨$iÕZ74pP†œ¿S‡àaÜð:²·¡¤ÒÎV+%1$…÷Ä# Ù¤_{ólŽù ÞüÁÛ»ãpáZ~¸lØÙLÎbÚä3††W³GŽº3ûÖ7/nãn϶Ëñ?ù¥×üdëÑõ“¾{ãîÛ‹*ãå"¼¼}q×;ÓÖ<Ýí\Þ´ñÑüäÔ…êânr8UŽM¬»Üs„fñm¦æ-Á:,bUêU¢êê*jAÁØ@Ö*™ÇO^œË’[ÎY$ŦéLt‰:a$IY£Ñ\0›MÝu]B(#«ô¦Íȶ½Yã¼÷ÎZr>o64…q®l}'¹SMš2X¡©óÚ¬R ëѧWŸGÃ8µ0€ZX„ŒŠh¿_AoJVo d#pL5 En•¤_19 3/ÐöP IDAT® ëjJ¸ôWZ¨~N$÷'mKÞ€ø/5Ñ·*$,Ÿ·ì¨ë\‚+JŠÁd4\­Jb‘&çÈ=ï$gIu+JÖZXC‰{,`FNŠÊRQ„ãÓ“Y½dNMÄ`ˆœ1˜T›v…yC&FÞXÙÞš<ùÔU Ü»wÏZk §Ùíí\\œ&Méì¤Ií9«Š¤`(À½Lç/û~ÿ ö®þ¡þ/™¨—Á•£a×µu½–Õc)y`a']Y¸Ý龸ØPSáÅW¾ñÕ¯¼ùÞõ®YUKÈ jŠjrl=ØPêŹĢÒïñŒíU¸]CÜÃ!U½ªöy¤¢qUYMŸ~ö‹×?~ÿÒO\ݼ>¿yã~Q*RZë«OX›îܽþßü·ÿå׿¿ûÝ?ü?~åß•ã2å°t!¤9Ç(¾MóÓåÙéÉñÍ/¼ðÜÎ`ûÊþ•d«õÙ:ÛkŒ:Õé `Bn!€t $N48d½+LU1°Á„W'$FzªÕ¬)R—)ªaùÒQäN²æ”ÔÙÊUL0‚²CY•(+³Š*+³’5äØª˜ûü6Uµê{@1 Î:çÙ†D8+zކW%Ñ^o ¬2'Ñì\(ËÒ{î¡—Ÿñ Æô]¬ré\—y8ñÞ¦ËWí?ø¥×‡¯>&ïë¿ÇßúçÛÝFêÃö«/½~|—¿øÔÅwoþ¨º™ñ֛󫯬_úæë—^Ë2¾ÛÞ\Î’®A@Ëùl´5úâ¥í‹£oÿæw$wéä…é¿ùµyÛ}û·~ï_»ŸâÙOïlíW¾ä8:Î69øMG;S»NœK^äè^p B$»àÉÕ©È1ýÔéÜ#ÇPcÈ@ŒŒhŸ¤#˜n ·&CVÍÆÂP?-#c|é ¼ª6±µÞU£qY†œójµZ¯×u][‹0p›X'HêrYø½=Wv{‡vggÒlVÛ;£íqY†íédooïìäääÑÙÖpà‹*©ŽÇÓ"œªW˳®•~s¯üù†ýÏÍÀûë7ïç;©ªýƒ"Ò¶mVI. ª ª£õÈϽüÜ{Ÿ\ÿ¸¥ºzŽU0M]¯ÃN°1³ JIÈÀXbã;Ø,l!}ß`2!%#I) ‘Þè:xÊeácÄáÃå¯üêo>º·^ñµg^<[†Ál#~ÖÙüêëÓ¯þÒ«‹“ûO_ÿ¹¯Ü»uý_ÿòöîÅÿûÿýν[·îÎRæý Û9•«ù£;7>®Bñì•éö¯¼òZ7{xâÜÖ•KÇ's7(K빋í¦á6……â3̺c.À•3…6©aµ™ÆTž²÷Γ Îc ”#'êš²Ò Pˆ 1G²Áª-,"ÈdJjE•%ãÜ5©æ, µúh 1äƒñ>øÒZKÆ`q67ªJdƒ)‚g¦cîÙ@¥Ÿœë¹• ØÞ,£ªÞز,‹«Ré'{/*ËЭ»³Ó4ã+_þâÓ_ù¸Õf3…$˜î^ÀS» óñÍööôé§Ž|ú´)=ÌçøÁ÷Þ=– 9á$]“%f£ä,ãOÇ‚  †@Hš#±jV‰"È ×$ÑvÂ5RSŠ~Óµ9Áœ{†!Dj*`À9ëˆØ¼sÁÙÂï½'ELmJE£bÈ2’¶É‘K.L !Q¹ã,=¥‚L KD.ØLÆg-+Õ(2F,%VaãŒñÖ‘5j3“ÂŒ³ÉÏɲfhQô‹1R²jµv²b‰ ?…1{" AÉYˆjOL¹|eüÄSWùèÑú^õzIB¼·!…ó¾ëºœÙ8ç½ßÝÝmºF±®p]³pÓ±…aÍ—.î×›ÅîþN1ðeë¶&»‹Åéb‘«j¿ëº›7o´›z<ä$…óÂ9v;ÙlºÅ<¶Íyꎂú³çÓ`ýÛëÙé/<;Ú¥už†…Z EÀc¹®¿ñêsÿâ¿øOüëÿóßÜ;>½ññÇg«_>œ­î›_ûþ~üh¶2JÞú:ƒ•3p‰Lnlɮٻ4OV§§Øl°ž«æèÈ(œ&ãÀ™} fp‡áÀL·¶ÕŽæŸÜûÐylO';M³¨›dHCXuùîÙü“ÃËG÷¿öÅ—¹Ë—ö¯^ÿøö÷¾ûƒëïtí…/}ëõgNf§÷îÞд~é¹KÏ_{º™7ǧËùi5ÚŽ÷¶¶ëæìãë~g‡‚¨änSwó6" ÊÀA¹¿ØHA¹"íêM‚µÑ³/'Ì9„ÒY ¦¬-#ȨB$‹ô™¼²åHÚ² I Œ·ÆYb%v̪Ù8Ê”ÁHc6ç:Q+V``ÁA)9²ÎV£*ç FéËÂ"¤:¬­‹ !¶$lÎÓ±00ÖZbgˆ4Ç”b„h¿ùB"Øó”)CèWÉF!ͦl6('xù™ç°¿zºÁ'ï¼ÿô3—Á»÷?¼=oÛíÑáâþýt4y!ìL‚sëGðþ›‹F~íÚµKO|íÅg¿üå—¿:8½÷è··ïܸ½Úh»‘·w>øàƒë·]±u¥¨bÍ~Už¼úƒ?øþæ#þàÎÑ­S­Í]‡Ô¼ôÌ•¯}í•矽d’|øæu'Áª®NO–'³Íbn‡“ÁhTw 6‘‹u‹¶…¨s…³s¥»¡$ y@¸O²„%öˆ&ÕÄDÆxU$t™ŒÂ²&CÖP¦ó8'X¢ âsf"rE¨罈Ƙ9‰Š5À”[ Ef`¼ð« ÉÒ5mÛtìZžîâkÿâr)ƒ¤f9ʦ¼Œ½‚éé<\áý[Ÿ¬êO.nãàÂÎ|¾¬Eþûolmáч(NñÅöv±5˜L£Ò¸j¤.Ã6í\¼°–U·Yù÷æxö¥êòÎíÅÑ õÞ¥ñÞ…íÝŒ||g)5B!YcŒ'ã}!sæ³õéQ\,¡ XgÙÄs@ ìO ìÁPkméŠQ¨HØ)E— qP5޼wƒ`*Gγ±’¤«ªN£B С …K<-…J¥) ‚wÙ96ÚµÖZ"µFˆ4©H΄ÎJL’»¦^ ¥³Uäu`¶Âd0ò¾(êZº âaZV) œlQù`-ÁY v¾´LHš³j‚€D˜†ATÀZ¨ªJVíúÜ–¬èíuœ F¥fµìÕV`‹0;Å” ©§°–Úx>˜>"^,‰VU2ÔËÛ33>+êB€í£UþD±×ÇŒÛs¿’žOÌ,DpÎÔ©SÂp„Ä0{Çe²K×o}xv¶È«e#‘R佡=¾³ôÆÃ3Ýïæë«Nw¦.„ããõZ`Vel°,˜îÛ´Q]o6íµgŸ2VŒ«NN\Øž:GE郷³“ãa(ÈɃ‡U15¹LMägǧî,aäÓ”%}ŒØ},ï¡ÿèbÝ«œâPP…*˜™ˆúZ¯¶PU…u RM}ÞºB-‰!ký`uº$£¡€(¾ù•§®=°Z­n=üµÿëßÑÄ®œüËÿúŸüêïþáíeÜ{q\ gΆUñÄöøìø,w€ˆÛ].C èÖ­ê.LFûïýñëùñ^$!®1ßì?qm³|e=˜ Zà´]•f|94«×ó½jk½¨CáBðÇË¥#ìqtãÑÁd<l"còþé7÷/VϾ|í×ûÛïÝž &[Éìü›ßx£úCyþù'¸Û —ÞüÑÿnpi:¹B#¿ŒA€œR»1ýÀ4hšõš¦Uï_8¸ºÏN:mÂÐVÃbr¥Š1¶ëÔn’ɥћõ®^ÝϤ·¢ §Ü «Ÿlíµ§kµÞ‚œslÔ¨ ^ ²ÕUh©[äòÆh([¿Þí£°ki6À:”cN¹K î\h–9·ì†Ãv]ïøbwâ6K±­eƒ•ÝÞçÀ&3¢Èl‰ÂÚÑNYTÊ4 Ãn¶,…V›ÅiÑs"3A4…ë¹kBÉ5ç4ÀÞ9û§?3¹û`¹»¾T?8ÛÞ™Tš®Å믆? t¦Û×vÖwåŠ]WºýŸ½óÎ"V“®KKL€ö±Å»ïÎÖ Ä"¬ÏŒð½@nêÝ(?loÏg~gȆˋ[Ãç.2oñéƒÛ'c°,_¾òäÓ¯î|rôãc<¼¸ua²»7D?YßB¹™mÛw$,iÙ;™¼)šf*’`#‡¶·‡Ç!$ $›¼GÃuç+­¸kM6q®®Œ1ÕÀŽ+wÑkE9›X{ÌK­:-zr {R8?r’Šcë‡4(8( ŠÒ'ÄU\/še²j B1GJŽ¤ÞœÝ_Í-Ô"’…,8N¸ªØ³f)R%Á‚ÖË…uV2[HåÝÞÖ–÷v±Y/f VD¡¨Fœ=Ò¢‡Yž‚®EnºÚZçŒ,DDÔh‚²ÖëùÆÁX;Î%þ‚Ff%cHZKDB° wY`-DUX-aP…¢(ººÑÇ?ŸF`ÙÇ8«O÷øzÞ³ÃZÛ+íYÏ—¦ÀRUšºÕ¨Ø=Ø2̼š¯}ᘵë¢_úÒÛº 1˜„.Å“Ó5 Â[“Ñx:^¯×“­A[´]Ží2:GEYƒñÄîLÊaÂììÑrs–²¥£AðÆß?\·|°¿°“ÎN;Nåâ´^-ë³Ù&Fˆ@åO4èò×@×ÿÿÏÜÿöË´ÇøxÄ6U£à56KlØŽQoNnÞ㨻;ï7‡+@†î¹¯½úû¿ü{¾p¤˜‹ÂTN ®Ÿ¿´;-.<8\=œ'WÙɬ>¹ÿæ÷ïß>zñ•ãçžúÒÍ7ßúäí?Âì†Å*pËŽö°m0ÙudS„ ÝÔ³q¶]lž¼òdaÍr³Z¥õ¼Ye9•ZBŠÈEeMhÙGµ‹¦ù½?üýûÇÛ¤·?¾3žmF»ƒÅƒã·®ß÷Ï|mâ£Í# C+iR¶hcl±ÜØ{ì:M ÁMƒß0wÍfS·í‚WÛ»;0¥³°š6,]Tç]eÑë8CB H.!‡aå42œ#‹Š˜ÌʨcJžŒqep\dq=Œ,SjµmEa¥CéP[y€)%·Ð®«Á@pÖu eca‡^ÈcjA]oæÕoZ°³n8¡¦ÝÄH­úl…¬ÀûÙåYû+uUƒŒæ”•ÿ?âÞì×Òô:ï{Öz‡oÚãkèªØM6'‘e‰-É’bGN` 6 ‚$’» ×ù ò¹ËE€ @@Ø‘I”jp“Eqè‰ÝÕ]ÕUuªÎ°§o~§•‹}ªÙMRI „ð¹ØØ87çÝë[ï³Öó{26ý±­‡ÿú¿ø'¿÷oã7”Å6Ý”°¤w»÷|0ÜÀoü“/Ηƒk›ˆn‚vItZ}¾:J+yÞú¾Ím.ã0ËZÇ…Í£ËÜœêØ÷» å¸óÕ 3Ùtƒ?,w“ñÑzó½›c1Ï‹Ë!WÑÀM…$d©¥Þê¿tn½û«U—÷ ‘b½s"Š£"2IF—T`›RJì "è'´IE1ƒ½L ˆŠ“ÖI9”8”“Ê‘YÒFKîÇ’%“È¢ ”Õ¥¢R8ŽÞS¢Åœ'3ZäbMRij ±ENœü°‹]Œ¢™b‚0”4®ë‰b —‚(òQ%è=ÚOP̬„ˆ$¢YYm¤‰B÷Š'N²_ØŠ¢A=‘82À":X„@’„‰­è2iÚí5úp=lø*­ëØËp`†o??ÿì‚û¡X»ª(–YŸéºäz”1B"(Í S•/”ª”oânèb¡’X;©2c32±óµo’fŠËãR)p;ô†ËlVp•º„‘˜$ŠIŠ$ˆrÞ9%î#Ý ÁeË‚TÚ)5ŽIiSìIú0FeyQ•:7y•‰N’ŒÙ׉'¶T–Ð&I€¡‘¶†õ¬0U žÌ)vcØ„Áëj²˜-³|Ú6cìà =ë¤D@V…ÿhª¾×Tå“ ‡b&fI> 6C9¿õ¥/??öáìûJ|1ƒVØn݈r›G‹MêÖÛËfAtz÷ä–ŸR~p#ƒ¢IÏ!ÓånÝîV±|¡` “/N“‹ÍÓ6aMã—ŽddG.”㬘䲻x×-&~¢tÛ¢u$ìv.STØjZÐ8qzÖ†ÃÃZÆ-œnY±óeo‘µJŸ4€Ó³ÄQÈGŽÉl ¼ EÜ×TÕsZ[vqÁ!# uEs•¢NÆp¦U%GmÜ8rÈÊ8›©ÃÊV&i¨ˆ"ËŠbî ÝÅ'QÁd¢“Þ?±¯7+cBHi¤&DòJDA[-JD$Þ!‚ÎùMÓ*Fïû> ûN˜ 1EùˆÁ0Aﱬ$$,¢ŒÈQŠ{V Ö ™bËlµQŠ4(€âÅqù¤,Žƒ‡$ØýEàzH™…É(8ñþ:ÏPØs¨IKŒ®m¦×@Á IŠØ‡!ʾ`ú(‚O˜.èö[¶Èšn;ºÞ¹‘™»¡'‹‚"†ÁVg‹ÃÅÁátµ¹¼›Í&‘ÓÕªói;;œwC?“iLNiL¦89YžŸ‹HµÍdt"±¹)+= \š’¿¼<§@ÌEêÚPÚÊêiSo®®šõJRÄž×NDV›äç]Ð?<\ÿ_é™…‰ýT‚!³öNdÀÑ´Bj¿ùg?*£þ_þê¯|íÆ¦Ý~þoñÃ?ú_ÿüÛßüÇ¿ðËŸûÜg¿ýí73k$Ç´ Ï|æV)êüþyÓ]-'ŧ_|nbÒz:{ IDATãƒ:ìÈOê•5ÅKϽ°*ÌÒ]~zÉSUZióÀ ¯A9Ø‚ˆ$I ÄH­wÞ;FrF­´…ÍDRD"ŠYƒ¢øa$RR{€8ùLd!$ÅHH#Âu&/³ùŸ ·§Þ©”"$‘Áì0[LòÒT¶ÜíšõÕz·óÎA´‚VØÃOJ)¥%%ï£ÕGU(}l6«X#ú$²7x’‚±09/'&7“ù”5 Ž]@HQQËÁòH³^_®ë®ËT¦mŽ·ï<)îú~ôŽ +føàêfÓ¹:¥$% â  OÊêàpâCg,6Ûó]Þy.†U’”:Aí6ã¨ÕÙ“õꪭwÉ;(1b@ŠMü¹rÛÖ(uÿó7©5J)‚‰Á5å¨Þ}k]Äî,_YE=öâh}Ù¼÷ÖÅýëÞoW'Kuú©£’ÂÍç—¯¾ðÊ¿ýæý¾Iîõ×ÿ(·úp¡yýÊ7a>©$íâêì¹)•*n¯V‡ËåLÙÉs¯|ûìƒäåÖÁѽ‡÷Â0˜j²Úa~B èý0;,¾ök_ ?ûË?ÙŽ°F,Oc¯†Ý¸·‰Rÿt§ò\(3Yg3–¨©w-)*'e¹ØÝ~~ñÜs‡‘0¸5htÞû-¦Ç'¹±j ®ééŤj’¬wg<f¢dšzÛwj€ €@V\–RÁ¡0=ôÐ0¹.µ-ˆ³Üç©ÔVGˆƒ‡.¤˜bd°ÒDJ )Ñ<›Ø!ŽÛ«UæŠ|9Ëó©V“ƒJ6ŽADYKE©…Ç~Ü^Ü0¦r’k«*G©c;z—’&ØÜ[ųÌLDccNE¡`µ.skŒfJ‘ C@êb–¹  O³gû>2]>Ù™ dÈeÓ|ðøò‡ÝÁröʯ~ BU–—JÙÀ!ŽÞ{KŽ'8\ŸŸ=ìGoJ çáq,–MÞ.—e žbš~Š›·Œºin¾|"<ñ§ÑE_”³~h>{óíÅîpqXVå÷îoýîô.ÞÄ®’iGJNÅí Ƕ[¿Pæl§GMG×CŠÜF’üìj}ßŒÒ H´/o ÉC_×ù$P/ùÀB%g S™I– 3=…n¼äc F]ÅnÂå—p˜²cYÈ e™Ê¬Ê¼’DBJ $%-õñLfœQ´dD‡±F¿Ïf" U ˜„èhd›²\r«¬&…Î7=¶†0PDЊ…d?ªŒ ¢ @lIå¢E"IÀ¼ó#ÆgŽxŽ*€…g+ˆ»æ(²HHA@¢‚DÞgª}i½?{³3ƒxt&S}zcqóÖA9ͬɉnºÁŸ_>üðñåå˜ý~Ý4þxƒ&îÿpü؉‹½SD†±È2Wù|:™ÌªbR¬6«Õæ ,1zm˜HœóeYÞyþ9£l×uuÝ–óʘlµZ½ÿဪɤwý|¹¸uÇataÌÊ̹އ¨ l†»í.6]:äIÓÆahŠŠ‰S™ëÍXo×—VgUQŽ!Æ@’´wìÚððÁÕfÇ´'|Åë ʵ½åc3ÕŸ_Mÿ¨y'"†Š"$Ìé£Ù4íå(+Œt*x(]è‡÷6_ÿ½×s G'ŘƷ¾óöî¿û?½~¾Ã—~ñ¸ëºW>ûÇF/xþÜâ`}Ü¿ýÞ£ó‡§å¬ =‡Tå3eÝéiלe¬Ôtf,ÎßyT·O2U”ÙÂæ~y¨ŽnÝyáùò‡éÁ‡âàH0-çgÃÍtVÖínÛm³_xåx2?êk~ðÁÚ´¾ë꼆ߴòé[7Žª¼Ê6»ÝÙÅå<´TÙ4ºþïýê¯þÊk_¾yðÂ7þìûÃU#M(&3…*§Ò²õ¾mwÞL“ÃIE3Óòc®@S¢’M´ÞTˆqÄRa!!sâ"fûÕg‚‘àëÚp ‘Û¤§Ô$F–Ù<Œ#dL@ «se™µ:ımw~ì뺜$Ì,QNÐ1Pß}7–¥´Œ¡«»óz$Ä,t¡¨•aÓøÍ|Ba9ÇÐyY”œµÈ¹Æ; QI´è1lÇ•µ&Úž&^B‡Ê*1†K;-¢Þç²ý Ç/yf½ÿe¼ý¾üâ«wÿùïýËß|üðP§öl›Æãà _œNû\>.g‡øâW^=ºó›çg*£’³Q‡ª4l¢mÀ“Øm; ßy{úT»‰£&)nü®knL†N.l]fE ì& QS~‡ªÂÐ:j±6_TËéÄú¦wo÷Ý»wïÜXÞY5}§6Vsûõªï{ ƒÔƒ Ò^&®Ã?ªîû,6xAâ‰Ê£)mU’.§ÕX,ž_EñÇPçP•73“EšVã¬@aH›È&qÜ 1¡ò ?8ÈsžÆ>ºÅô¤u›ºo‡ÑázP© [Î2À›¥lªf…Êö޲í€"†I éÙ~DˆûŽØÃj¬âQ’%DRBŠ$…k,«0H±0QŠ!"EaI |2PÄPû ‰±7µ~høqXê#ù5l†¢TY6îrsi‹¼ÌÊã[Ór~ç¹vNzøá“¾C‹À |M:BŠÃÙc19ªÊÎçÓÉ´´E6)ò¬,š®mû¦;â¨å“b >ÆHIÖëµµ–éB ¡kúfӌݻ?:>>6¹™fyx•&n/×ÍjúDØï}O¦Ùb1ˬNÉmƒÔ·Ýöˆ¦‹eup0qcÓÔ¾˜s^L|ÛkSÊÍfØ­‡‹ËÑ @1 ,B{ŸÈjöoư·,LIP”ެR Ž9/‹¹ß­Þûáƒ×>ó™þñîŸýÿû£~mÄáx‚*+ª*¿ýÒ­é„3ËïnþõÓ{ÓnÃþjsõÂíò—^ûÅ/|õóŸ>ú—þ§å±Ü™Þ89ÕƒåôIÿøÃ®Žæjv4[w—!o^yåx±”/Ès–åþONçßÛ8bìµÝ|ý·:¹Qþö¿ûËÊTßzý½îwÅ,y×îý‚ë]“OÌWåËYÎßüÖ·Ê&hIâáñÁ®ž/oô‹ôXš{íäöÔl³ ÕtvœúblBw寕 òÌO3;Óø¼%ì¹ÉýB #0׺L‰†=Ž4òN0ŸÆqp;¯‚.1w!išæsßG]t!@A,›‰.˼Ým½ëÑ÷H©±µPe–Ä©mGiÛ1Ï„lR}ÂÒƒ¹‡XÎTQI.>tiè4T‹M¤“ &gŒ<º1 ±²P¹$ c³}ºÛM+›ØótŒ±§“eF¦âª,&b~rð"ô¬©•+¥‰•¡¼Ô3ï~º¨¦üÅwÕL£ ´'7õá ·»œÖÉ–ñª›÷ïIeUñðƒ«®Ãç¿ò©˜Ü—$:ÄVbì‘MÐp¯2¹ ›Á¯_˜¯†ÑûMì÷Þ¸úü+KÑâûZÛj~²œ_ïoª±ƒú¤£´898¬N¹×›‹'ÝÙ01…OËã‹ôt½Þ\\ºà<¼ ^RXí±×{ .ýX>f 2ÔUæ¨RzÉ“À>Qp$c#†ꈋ½\ÒÉL•LuTÂðÉw}/»U¢(”)µU¢è“dÚ\6}Û6šiŽR’ë1²$ ¬edff27³‚s•àÅÁÄà‡û"D‘V@Š”Èàe DÄ0Jk%*Á_ãI)m,)¨àBˆD’¤$å“+‰I“¶JK˜ý)˜bÒ?=šƒðu>òuÆ0DRˆc×oÄ…b^ÖÝj½;ÓÚΦ‹çnœe%©“ÛG›Ínu¾®ë6J ~tÎ}¼qÿ±Ÿ¹ábRγÜx?zïš~¸Zïú¾/«œã3&?~ú¸Ê«åᢚNžœ=Â8_f~L½ø¼Ìê®>_·WÛ‹ÑËlÎÆÐÓÁœŒ…ÒÉõC–©ƒÃÅ|™Ï¦9±Î)áæÉ­±“m Óéa²·~øÖ“‡»Ý–÷F‰Q¬üc¾1¥™þœšwù˜,³RÐOìçPÁ‡&¡cEJÑ)f{þøâö­ƒ—n¿òÅç—ÿÇëÒ]Tà»ùàwþñk‡Çw^:„oüé_|ã{ß_5(—læÒVØfA––}VžV_ù­/½øâ‹ßzýõ«‹Ë§7ù¸züÎUY²¹9»xûžóC^4Ûu·˜ݾ±|òáÓ²Xž=¾˜O§³ªsëw~ô(*üƒôå¿õÕ_zøèénó«ËM®ÒP90 °6¯wíÕªþá¾OG's[N¿ô _ÿé7þÕ›ßú½×wWþr^û•¿ŒóËUôY˜eEÛnû. )Dlºã˜›/æIIйÂdn£¢Þ¹ÉTe&qH ¢“û=™(vnÛuïÚ>GÁYÒœÚÓCì ØLådKÓv¢­ {äŽK}ë“ Ì†Éá|J :2"r="DH¨¥TÊDò)ŽˆÎšB8#°gJðCjúýlq§=R ï“º"Ï+bßÓh«-¬1†Lý?@û¤,‹nÛîàb¶ÔÿË?ûÃÿüïþ†B•Ú¡²8½‘oÆkL_÷”á;/¾Tœ÷›ûçgõÚ¡ëðk÷3ÓÓ¼wõ4N}¯±ã”ã”lZ´Éo‡îåɤŠfoÞ´’õW]ôuwPè1RßG&sã¸8ÜQŔյ»¼¸»xtëI}êöÝ¿üËï¬î}öE*ùf[§]uV¶}……Òõ}_%d­ìÑŸHÛšˆLbåDă9Ÿ@ku3Ÿâ„'ÞsÁ樸y’Ý:Twʸ´.‡„N¨u±Ct"£€ ž’—䉽6”)v¡Æm”v:·y6 u3t[çG×gÌ$†9'“Á$‰Ä’6Ä j_#öìxf.µv>yÕ0 "$ÒPŠJl„b®Á¬PŠ´V@JŸÑ2Ć4X,Í&Q$h$–k9FËÇrýNöJcmú$‰H”¢ç_¾{ôÜáÙù£³GOvÛúj×캫åì`6=¨æ*ÂäÅQQÜ5ºhÛ¾išàc»k£J)ïýÑÑÉv»5Êjk‚ó2¥ÞÕ‰Ì06«ÕjèCˆ ÅuÛ:ŸîÞ>ÚÕ[cÔ|2]¯¯¼÷Ëåò¥W^Ž1¶Cµ|+›çEqquî×r÷ÅÓÞõ]'ËC ›yNEa'U¤,3·n¿ðÞ;o÷­¾uûtRe£k†nG‰6W¸x²Éõt69~úxýèÁöꢫk¤ˆØ+WüÌ¥÷ˆó¿i­åg~Ýä_“:#"Ƙ½¤­1ÅkÙWú}¯ñ,93 l‰ íâ ÃÐÙ‚Ú”ZPi‹CŸxytÚÅppt;¯ï­jäÞ}çÞÝ—n¾¬o>xröî½÷Nn-.×› Õ`qèªÕ~û«Õùcšfôë¿ó›ÿôŸþw_ÿÝ×Wi,ðîåz~ðç·3s!©³šÞ/úüh^Ѝ"·/¿üÒìp~vþaó¨ >|ó_ýðêr¿ÿ£GÀDH ÁúÏÝä¿þË7ÚÍnpkCƒø~¼uã–‰æäèæº§wÞo´«Üf»~ܤÁ8;I0J$Â2r¤ÛR??:ŒÙh8õÞKç˃rv˜†9ÄM4ÊäfšçÚ²Û‰¥rVTŒ~v4©«ÍöÁêòòB¶Q§*7M^Ì‹Y9l×hd ƒ¤#˜Üho‚÷×Jp¼¦.{ÐlnDÅÀ!&@š«¼Èw—-HS·¹P‡SÍñ`ž©\·ç«GOpÙR1ÙA¼&*Äø”¡m½4FU¤p0ÏÔéÉÑrX¨-êíf_áH®§‹éc{f½Ý®  €œ­€þ}ó×3mÇôK¿ðâò…ƒxÿ‡/†í‡ï÷6›½tûæW`ÚÿíÿðþÔÕ·ŽO½Ù\\]ºD‰ò!t/¾òJž­¾ÿ½«ãSóæëOÃ/Ž>øÑe¡î?º´ðõ—w™ z9{ûÇEʺm\VÇ;>×:{ôdÛ{pq‡2Ù=hçFAÇoÿù{íæ=òeŒæòª8H £(0R;ÁÞ\ÿ¬\íC¨ [àÉj’URÎu;è$ÍÓõ¤œš&L&Eç÷Ð(缘ë[óìno$Ÿ§d³B 6õ¸iânLuÄ`1¼;§Æˆ½kÞÉ* V¤IyPt q£XSey–ç…fE",ÐZuÎûÒÆFEnô)&ÅL‰UÜGÆ2#\;ÍJkí¼!#2Œ.aDD(³cÉ{Oˆ”‘UàªÈ‹LY‰ƒÏ%%BD‰D¤VË)ÏB9RŒ Ì`f¥6õ¥ÎR>å§W®Ùa:ñE²àÇ8:R”BHЉ²¦$¬ÖÚ97]IF"VŠëBDJA§¦©wõ˜"ú>–“ÜZÛ¶Ã8z£-3m6›ž©í ©íò±þÎû3Dƒ4Q؇*¬‚æý}®ÓJÛÓY‰‰~á˯ÞùÜÝ7ÏÞkÞ~£ $Dˆi}Yð£šæÌÅ^š˜òtwÝèT”O·ë‹o~{½Þ‚ñö{ïÖn÷î½{ßyãýz$ ¶Ì™¹\]}ásG«§¦‡¦ÎX}ñsŸ 1óct2­ûîéÕeÓ†®Çfã?¼ÿ~ß!0!›re xñÙÐ× >lfîèäèÆ!µMW_<Ù$÷ávÑô›«~ð³êPeþäÖm›;ÆÓÍêÖs $F–0vÈ,¦Ö—CKí0¸Q¤÷#0úÐ…”eÓ¤yd!Ä€¤ua•É(ä=Åq’k=±É@¢C!ª¶ïËé-r,0Efs –1¹@ÑíÝCÖp^N²ÉDÇÉù=‚»‡,&*Èf…KÉCåù²H.öa@ò‹¨[!ihÜàP7hÇ([f‘’'¢,ª…‘¢*(Ø^*Iª8Øq×n­ !Úk–ÿÇ*ûÅh¹^¢ýý™›P¥ö¹ãù{O£<=û{_¹}:yéâo¬×)¹~ýàéÓo½q!—/– 7;àîC·ë·ýzZN·ýèEŠ¿¸¯ ¶…9ºQ)Ýz‡ms5ú’b;øfè\×J©i9QÍ)ŸF‡” BÞ»]J‰XÒwcô°b„Ym§•ËŒízBšú~|òäÜZíÜP–ŠÉ®×½Ã˜WF ‹D›iÒ®0_À‡¡"qÖuÉù&9ajn:_æ My»6+dóêFÛ¤ÍÕöòén·Að`&­s‡Ÿ™î¹ ­œÿôAûù¸™D„!1%&glë}qg kPf”IŠ#ª Ïç&sz~\ÈÔÆ›¥Ü¨|_tV5I|äzú°{˾1}?žœ.ò1¹zXÂÎæÓ+™OKˆ~ôè* (J¼ýÆÛo¼ù½óÕjWÃ(œžœä((¦y™7Wõ›ß­ KgÞ[ÿýçKÏßýÔ}ý‚ÕƒG?XÕýÅjkóÜXÞ®:×ZކXTÕ°õŠE2UŽ]Tb¶k±–ŠÂÓ­ çe¨ù©kõiaô¬ § ¯RÝiÄLÆÂq£L#–À¼¯eÚ>z‡Á!ö±/UIYUeCòlÄKt>0”ÉÔHqh;I]>›IMH1!„q£$ÙÅñ¡_Ìr­(ñ.¤(¹¡`‘ªÌóœAapCD€$HíØ ÅôXWÓ+3p¨òùÒ,ÝYXŠÀ9LB ¥S?ÔöC×bˆBâ¼U‚Îó2+ôÜĆA´ ™Zš™`öeÈ\ǧO+\»À壛fbŠQpéëÐú«¿ÿ›/=˜nÿàƒ7ûkŸ/<ú??°Àr¢Î¿ó£ mËç¦ ÁK/[»hí^>\5«ó.·ž¿ñ|ÆóRh;éw—=9´WÐaXXžéƒblã…6ceºõöÒ=Ø¢)ûâÆÖ\]Àµ(ò¼´©`cܸëzø„Ñ˶óWØmÐl}ÒšlYµmŸžÍ¶®EP°‡kýÄóŒDh ÚTÕ”&ÓiÈd]× }kPfbcBFÓm1Õ¼dLÁ™ŒY%öÞû‘ÇѸƒMz¯qz´½[“ŽÌìâÐôç[ s~ô!±¸*@"¢? }C­Òl¢w.»P#‹¦Ô‰)F„$Š´¢¬ˆ¹ „„¤€ ff¦K3¥ÀIˆ’¢"Œ bËSJ>ù„®3$ÙTi› ls6 §ˆ öN?£0%€“@˜9¦èšº/+ãÆ¨”]³˜<ÿüóëõö¾}uǬ™Í¦JÅCtÁµC#Ã0h² Š1v]oŒÙµMò)FqèµffkµbÄ&”y1)óÕºVJ-fËXj3­·a^ªtVšjb[ $õSñ†¹­†!)” .ŸïVݦƶH–æF ޼µÆZ¥­éZçW‘œ[ïܶF[CR€óS‘Û¦M”èºÓ|–ÿÓ{t]°œˆ)&0ód2;´“«± r7ʘ$E;µ“"Ÿk.š¶/9³…S”º 0˜T¡¬Ž*EƒÈ SSr±—Ô$äY9A1¤´ó}Bê¤S%çÒ1c›¸ÕšM0BiG/Q‰QA©PÂ×9è9™JÊÜ—:ФDÌ „d Â8~@¿Fc0Ã…äd2p“%­H_{»4<ŘRŠHú }ÌFš@ᚯw~°^5ÚÐñ¶Ÿß^6NXey19¤ìèhÝÔg> k¥¢ÑPÊdY6©&Î…}*аæ$Þ{ï$$/ÞÇ®Ež‹fH…!`´©(uô)i‰ÆÞI@–[F„²Š™Cã8†Ò¾;eù¤4Ç€¶ÇñäôèôÖ¡Ñ`å3Ãy¦†¾ÎŠÅlj´JbŒn ‰µ­ IDATpë‹MUÌÊì@Íg–'oýàÁ£GWì¶;Њ?¹“~êU>™óõs74‰ˆŒHH%×WT&"¢X•ÂPh,f3£ô¶î”EüÙÙ•ù°˜ÝòHå¤önÈsbÈË/L¯Öõ¦NËØL3‚D7öƒ¦¼´;¡b¢>õêÍùQù­ï}o»éÆâPT9SOC?¶ãÉí»MÓüáïkõÿñø\¡ËwÞúQ×^o7¸€a×ÄÁ겘‡J Î!ŠÊ"““) ªiu|£ºyw–áêÃ'ÏŸºÕA‘K½“Íæ+ë·ì<Ïf9¶ç±Í›-Šùñér .ÉJ‹áÜÕ®n°Ðxô¬1d4ØöÊ7™sìÌsE~sïR³N¼EfÀm“f1ŠÍÞ§—4%´‚@¢këη½­²ÃÅB¥1…&¹MGµ@°v°¦„RÓ$×s› £Ð³1~ëÆ®'.ò˜`”9²!¶À ‰‚'=Ï«Båv14Î £ÀÉÔD²AØ UÊù$W9üG¨&ÚKB =åÙ Q„e’Wqµ ÿíÿ»ÿÍõëÿÙ¿÷oc|T_üG¿›ßwWhÖî;öÖåˆçŸ_Üy÷ÝÇ÷¾ùÞ¢ZÔïõK_éMöàìÃ1òg?³ßµ–L™càZ¬žìR§š]ÓwI%“Wéh OŒ&×ѶlÝD¥H@Z«¶áÝ&%HÝû: !^[m­ ιÅÇ$‚Q¼ŸÄ ûÿžÏC­Z 0+ƒÛ¡£OȔъ@¥É—Y¦rqÚ‰24nÛ=¡Ü'RŒà|Ý…‹Za˜Ùj¶ ŬµfÅ)‰'qŸiacbÖÆ&ðBð)„8  Á©€ï1èy†78V0ÊÛ©ž:¢(I"4qîuÁZB4‹„ȹ¢à´ß¹K#J 8 )ÀkQ”2{“¨„"X “0ƒ#Dã#WÀÇëûGt˜=ìÑ£®Áª¾¼ØQ »mþt]deYÌîÞ1Ûm}ñd¢:­ŒQF„¼Îy•”âè)Ö;§¸zO‰¼“<˪rBï½HJ‘ƒO}í™\žçUYÖ›­YΗóù|µº¬Š‰®o{hRJ%NÛ¶6Õ$¿ýÜM0î?|¿®wO/žN¦yßÕY¦¦ÕÔ…Á9wrz8«Ê§gOºMÓ7Ã$+Ù¡ a ¡Å‡O?zX†LH>Eά ¡ý±Ø'ÿï™ÝÀñÿÏmûÞŒyï€C!JJ¡Rò# ‚nêv»ÝM ­Ç<6^¤×0³i•|Þîx»î^{íÖôŸüÃ7ßù«ñ¯×ãPMÔËG/Ü~®ú“Éݪš^ÔMjG°:<½qrzþèñ½8b³©soôÐÅú*%ÿôñÅùź°ÅÍãþÿà[ïŸzN üæ×^{xµùö_¿ùèÉÖÅ@¤Æ¡k6«ÃÓ"¡¯æ0ë+\Ög³âHk}±}¤§Õðþ½ÁmëÙ ‡§K.Íä ¼vÿâ¡|í·Ê€P¶ ÃånœTÄvRåJH\ÄjDݨAÉH ‹2ÊФÚu’:ر£ò¬µ†”GɘÈ‹dT$±Ès°AÅ(¤BŒ1tͰ٢EsBT„$ã8võ0ÖŽ{ÖÉ:Se^Î ¿˜à QnG¯•‚Ft>ù`­%Ñ^q¬¦4',³ #太<ö€Ð Ve…Õ™cj×M\Õjhˆâ\Jå†+/«¢EÚÃ…hÏkºÆ$"‘ˆQHûe !‘i‰||óæùùÙwßxïý¯ÝÁ¤[ꘚÇ÷üó§Åƒ³>¯»ô'¿÷ú+_zéö+/ýù7¾}¾ÚÙÊ~ïñ/‡Ãçæë£õ{o_}æÕ»n”u¨Ý˜êÍÐnžºnt-ÁE–.¯Ltv¾˜Œ½ªÃøðñ&xå’ Þ³ MÝ®V£4"“KІÀ )†°k›=…š)"$$ ÉO‰Ÿòì¹fò ÄÎïÆ&òNt×€ÊgË[‹ã¹×õz}5º:9çT§à\SMT¢˜TðI+R¬™4ƒ‰$)$F$KI”á”…D"®TU ‚Ð;øàb$¡à÷^%[Pž#_¨å„gltHÑ… „t„ ’) ’Ò>•7ZC©ˆ\§!KÔ Î@¥X˜Z˜J÷NPM)D`‰ !_ëÈëDð)Ågd˜Pïpy±Ý¸^•{‚pªÊòðสæÖT}íºÖ5ÁköZS âTŠÌ`HÛ ×cE‘F¢,¯ ;‹Þ.ˆ°ÑÄ!EQ¬s« ›7TK”¢,&ùdà %ŸBŠšë}<•(m¨¬òÅb^Tywqy¶Ù¬b*XÉX׊sj›Òã°ÝnûïjÝÍ–GOoÖWõæª÷­.8ÄV°FGR.Dff­ö›2ŸHŠ%ü,ºËG“­øÿ/ÉýUà}NÕ~b’’JP¼Ýu¹%Ð:‹ÆÆgzòê§^Y¾¢>X½UVLo<|:6›³]težmw­²éñâo¿øoÝ»zòç¯ß¿óòÍúììÝï=~²~ùvÜ6­KblÖ8÷ÁãG»aèªÈ==ßÅõ*£vU–Ù$³¯|êåóS4“ie°ˆ£äUyñd|zÙœ_Ô]0™”&±‚§~¾Äk¿öÙ,3õíï}pÈëHêôöì•ÏêâêÑÙöäEzík¿±\¼ôàìéëÝØblçÓEyÜ9¨9z…Ñí°É®FšW³åcH—ukŠR'ÎÕ¤2Ë4ÛM'‡ auÍÁªhN‹2Ÿ™æ ô, ¦LÌÎ{¥L‘W.Sä5Å8Æ Þ³„R7  ¤›¾ë!©ÃjÀz@-Ég¢ª23:›ær$ýlìÑ»aÑ‹ñ™hí‚„ÈPAàÎŽ¦öÄDíÐvš]õ4 ƃ“™…¢(ÀÔw.Ö=š!Ž ¡˜<ÚÑ×íà}ÜGP躉•òÒ^§æ=ç]’Z?º<)ðÝ?;ûäþ/ÿÓ_]~æy´þþÎkÍðzBéV½1`•ùzüüË_༨ßo‡ƒu® %ŒÞ¾Ã?r=Ð )„Q¶ÛÁµð­(7»ºše>,úü¢IÀÅ•(ÝØw­‡˜qôuŒ¡ÎÁ‰$!ù8öµop^$)ˆ$0ö©›?¶ ~ÄûÝãjAH¥nºËÆ…Ñ l¢Ü‰i|ò£wAœ¨õÐ}ÉЀ– Tdc}bç4‹¢” ˆ(°@ö;sýS÷f?–¥ÙußÚûÎp‡˜sªÊª®ê®ê.²ÙM6ÅI´LRa¶DÖƒmþ' ÿ+~´~0!È H”IKM‰MŠdÏÕÝÕÙ5æsÜé ß´·ndU5ÙФ-8"7È8çµ÷ú-açkkëT E$ ±•zk‰sÎcz Š H ak¬¥’@…¬g[£nÍ|fvÉÚT²“!Gʲí³3AM1•±0ðÞj­cXzk©T¹Óp³¤E–‹e£ÌrC2Üþ~ˆ «XÐÇ4÷ag§œ5¥…µ E –iw^#Fï}5©¼¾îKàù|÷öí»ËÅ:ëåfÕÀTµo\«Ú­;³¥C:gvÖ›¬›~ã‹)­úµ1¦m®œ–T·õbyåŠqµ%ÕÕ°¶£Išc ²© {%¥"®æÙ¼mgu)é|y<-WÓîÁ´iªÃÃý½Ù÷|/¥t¸¿‡ñâdYöò¤žûÒjãí^í÷‡n±¼Ž)˜"ðý€$pJÖZ%¤”‡>š¿dùåÿ}'ÓÍŽïÍÞmu~®°ŠÂ¨S$,K;ñ-Ú O¸4ÈýÞÞÞ_xãõ_ºÅßFˆtçÎëÍ»Ëï}çѰ¹lwf÷îÓÛßÿõßüçÿõûk/¿þé¯ïá¿øy?©—Ãéûï]?;~´º4³oæÇO.ß|ë­ÝÃ#:8¼}ñärLÃdßÍ÷vï¼:„¼X-³>~VØW?½àz7uyffnžÆqìV1`ŸýJý_þ¿¶xÐþ³ß¼üõ+6—xùÿ¥/|úà…×þä[ÿ®P¹uÿ–3~ñàtvؾ|tøc÷~ü³/z·šÅ«`l]:A[£Ë—vÃÖßžJñtV¡¯Ã”¯êɼ¡Ô-z\¡q8Ͳ“gÓ¶i¢í £J¹qÙhmqÖ¶ì¬zn«éåbpÙbUE$ˆ…qU½c¤Eó†°F‡ÂP¯d‹BHLeLëŠÕ~쉨2´F^•Ô—›…¾{²N«¦-^<|!HNõõꜗ§Ï~ð½ã‹óD@!l˜ÁªZÒ‚³òaòÑRKþ¼Ô.‰üòŒè#±eû}ˆ˜·DPèvqêœÇÑZ ’\еFQŠB¶M™²3µ#%Vr%˜Om-¦Î“/½ò³e½2<ð»go?zðî·Ï„ ¼Ú›¸ò‡{³§îÙ/ÿÊ—t’ßzøæoý›èì7?ýògnííþáïü_wï¼pq½>l°¼ê)£­y~8­§ic¯Þ]Ü;üÔ|º[ÝAè×ÍÝùÞüèƒG¾ÿÞwnß}ñµ_üÂw¿ù´Ä£õ“»‡÷„ƒï|;DÕ¤$bKnÈB5ÈcÿÕ]ÍO¡o/–çÕ>ww+·“î´·Îä§ïüàýЭ}ÿk“zúú—>“–ëýj/ÆÙìPëùf¥ä¬µv=òúxJJe ±z»ù¤‰SëlXvãå†ú–‹Æt®ó°sð™½Ý{û¥h\æÖ{£œ6/IG7ogl|Üú!.7°ÎTš)v¦ÓÙlowÿü|EÙ·2ò¨ë‚b:wµ_¥qÓ¯»ë±iÃTµ~YÙ*Ol6eí‘k+0PU<”x>21•FUµ©o¿°?Ûé/ÏÏãZ’q³éÌLN$ 8v\Ï^¾ó©“φwŽïµ÷`×íýJY¶jEÑ-Õ7£5&dù(B]¥@Š(Øùõ[`õ¿ûœ¾5;½Ýb¯ÆÔm÷ÚÏÿÊ´þàûòµo"ãͯü›³«èiþÎÃëW^»ýêýúýãó;ûØÝß›V;gï<=yv¶Zt‹µÝݬ֫%jF—´Ñ'ÍWïä°Zæ*ÍÊCHcÆö.™a[ìM'Ëu×÷PEËM¾’¢ ”HÛA•çé J7”2€‰9ç‹õõ8\â’’¡QCW²Oát,cw¶ yt†jg†[õÞ¾kb²¥Xg§SßΚ‹÷uɆ  ºöÖi”Õ¦;Z"0Õ†wšÊk*’—N‚/bÙl’Œ&³D-(_{vy•ŠHÖÀŠf)<ï g&ã§À¸ãeÄÁXS“s …IÑXÞµÓ}•õy7Fœ ¬CƒŠq\R4j*ß䄬Rk}èoW~&"ë~mÿ›‚þŒ›ô£]žÀ›5ïjg\eŠÉ’J–!e2Î̦M; 9åSq‡wšiUUM–ÂÍ“Í<6{f6›5Ãh %wü¤i›ª]®®_m½¹ÍÜ‹Xª•-íÜš…\UM&¶ÆUn¶;­lÕ¶žk1¶Þlr.XÚvb,wëÆ¬EºE—S»â­ßñfZµõ¥¤ÅùÐ÷ñâ< =êÊYÔ<ÅÈsï/*âÛ½—õ þ+^¡¦+[€ÀR3yCb$9Fm–yÒðÔµ:¨%Ÿ‰bŽ<}ÿÞú`þvÍÑw¼®mU×÷_:Êeøü}^›ôðä¿ü¯¿ÿíÉ®ŸÉ‹Ë'“Ûó;»‡S/ÎWqLë«U¿ W—ëu7Æþ,ìÄeÌãÇOžœáøüòb‰{ëõÉÙq6·^½[6Ñmóâ ‰Q1…DMeakk&ÑyÜ:8ìcþæw|ã[ßÏ=îxÔûâîÕóŸùÅ_xåø•ÿùû_~çñ¿ll{qüäéC|ö³B6EW—ËZ}éL^½&CÎ#Bɱ8“s!‹~@e?j ‹O¤™4çPp6¼BÒÉ2ÙON%ºÎYkÉÄ¡Ä^u•‘ï'UÓ6“bÙyo¤åU—Ç’’èÆ"60u[Í]EÅ:õ#JI›!q5æJªœ%Æœ7 B¢²JŽ'}C·„÷Û±aÓº ‰S™Íy÷h¦w9Pwȼçf¹]-¯†“Ò•«õÔÊ­¼M¬x~CÉŸùè‡ßÕ7ŸíShÖ®ûRBWý`÷xïð.*7{ýµû§|ðÞ"o“@RJÄÙñéîÁt×ÒÔNŽì¾‰õÃ'ÏÇëá™ÌÔUÙP*‹©ËµG]OÏ/6åjìéª ;!òí¬©ì²[õcÙÝ­_þÔýÚÕ||Î.³Œ-ÒX.I>¢¡èM2LJۿ„-wEe›Òä,ÃpR8G.àdHŠ\©Àײ‰šF<¡¼)B;˜£AÕf5yL’ð†Ûª™4³ÊÁ +«ɦ€˜le[[r Ý2”, I¢3`&ÕÌjm-uûpÚ‚·Xú866Z)¤l è0œ³ÎZ%(“²jÚy ¤2rA ¢P&RQI Âa`šÊÏ÷&/:Û–œ)7ö“Êc‡g˰¹˜ïNêIåj&OdØ-TЦ”ã 9ÀTUÞžYç­µuíËuŒq¾;Ë9Îv¦Zd躺qí¤I‚|ûÞý~RJ7-0«1f:oEdÕmNNOö÷w÷ïÜýôÙÉùõå¹›èÑ­Ýùtgw¾cÈM›i·Þ,.N¹c`w.mUOê™)Ñ\ŸoÆÅòñ£ãËËn0ôÛƒ©<¥TðÜõöç´ýÛH?üú[ø­õ¯åøXL¶ªÝ ̈” ¤fXB5Eã+=>{¼ÓT)Êų cðË?ý«o|ê'¾öï¿óoÿq ²éÇñÁÛÍÞôìl¡Î.Qæ²?©jª‰øÞWŽîÞ^.ÖßøÆ·?]øI¨‘I—„“Ðõc˜æýÉîþµ®›˜iùìzùx…óxÑ…£ÃIÅ-9»µãÿuß¾ÄQɹ*¥p±¦]b26cÕ—ý{ëýo?xñï½ñÚgÞÈã×JˆÃAVÎc\£9”ÝÝC†©|ñÞŽé­õf´¡çå4ûÞLr‰\á³o|îàðÞ7¿õÝ««‰÷ÕÝP ¹ 8ïM´:cÌlº#©HÑR@ë<ŒÆ˜>Â{|ÔÙðGxT(«`;:’ìHɨ5¢&gJ¢#r*„G™Æ†’Í6f× ZƬ(ÎÓÄøN{ÕT±7…sNLÎS’TÒ˜2+CYdKýÊdrÃ5ÕmJûcˆqÁFs•a ¬³h"[± Y¤ŒÍȱÏWã ç±V¨„„ €·Uãꆸ5*¶Í%±Aºa\!• ð xÇÔ•ÓšmJ!äÑÀŒÃÄÚÖ·2µÆÄMúÄÙ ä—Aºõºj;Wó|¯íOsJ~Ri‘q ⼇a)i±è«ºNyp•ŸÎgJX.—UU•¬·oßvÖvëM£–’RºÝî7So*ê6›1fP$[ Äñ`oæ-ÚétìWumÑÛG·|+¾²§Ç§ÃjûÀ‡®±“n¿øà{O& M뽃ÝÃÖö×××—Çë'ÝŸH§Ç9†›2n VÕÑ;ÿ]ï2ncó¶ÿ)¹©GŸ°Ç—@D8³Šª3vv“PJZËùA C_ôôj³÷©É®¹}¸óÂÑÞWöêú²†Ëë¼õþÓgÇÜã ÂŒߥžUßûÎû/ ©ïÆë«MN B]ãà`â\5ÄÀÀ8†œsßÇaÐPüŽuuÞÝÝŸÏwŸ}p<†2ï^œ,Ç\Æœ’B‰µØD|óž=xð{›.µÀŽÂtܺö_ÿÁÜÚ¯þéWN‡³»Õ޶{-Üdº×¼ü’qÕ“ãgýûÝkoì Ã@n ‰¡+qkïx^¬A)()G &³*H gàkP†*†˜.j…-ÙdƒA0šTÁ` $ƒ¨B gBÉ"d’§\Œ$`ÌЂ:ߨ—Pr ‘ƒÚ¬–ƒhé €õvâêImÄA,¹ —ë„ËŒ’Ç8ô]'"X–}ÚÔýÐWj?w}ŒÃùæüÑåòƒsÒÛ%B!‰ÐÊàœM*4d !BYŒFN(B†XئÔb(‚Âhsσæ\LÍ~6©æ¡Oi“Œi#}¤„qì@bˆ YG†,HPr<™Ðñ9;.棰áP’%%h„lʸǛbWF5¥A‹BJDTP!&Cd¤"ª\Èð¹êÎ.»«·hw|sÐÎk¢šm(c¿˜¨É‚!àºëa‹ä2JùdÅÕ8ׄ%åØI„*aΓ–Ç.îííÙvz½¹rÆÖUÕ‡þò|1Ƽ»wRÓíÛ·«¶öqQÛzPRHÓZqè6hi›æzyî›fŒÝårá½óÞk.ãØ{ïS }¿„AÞÛåõ5ŒÜyñ(õyy±²ÆåXVØh=›¸Yu6kæ­Ýcmc?,.ÂåùbyO‚-ƒ¾@)Æœ³6?$J}œþÛ›•Da™Œ1ÖZ9gU•¢ÌõSôQÏ¢ @ „HÕ2y¯MË¥$Uñ6µm==ª¹ Ý¦Gÿxø½þï¾ñ•·N¯Î®»åÎÑ|¾³rr±Za)+$]-3YuÎù‰Ï)]žwÃ00ùÙŒBHªpžüÇ?—Rºº¼>¿º” Kue34$Bî³$t‹îòb1Žq³é/®®CAÉ a.D¢šr’‘gÞ_žÅM×WÞïÙ]Cé‚™9MæêdlwÝ]5{õÞÎîý^h§o->øÊþñåõiþ?þO?—Rjk»îzS5ºa·JéÖ‚d„ „Bˆ%i1 €I¬ª@j¡)c8B•PFIT£1É"3¢‘‚—¤ˆ”rw½H0 &s…8o}Ä>kÉÙ­„}ä¤9¨…ñ¦dP0°ÄŽ8½/ öàþjUú„5¡ ôqu¹&¢ýEÖÚ_–«p‘ü¤êÇpqzÕ_txºÄZ¬´U{##ë ϨÍó#£®cѨÔÀvÈO#BÁA‹ÿóËrg×PºÔnœüÂOÕð÷îßš|ê…û%Kûͳ³Í(f1–ËåêÙuwüt=ŒØÙ·Ë««”ÇØK`]åòý÷ÞzvõÞãÇ×›a5¢‹‹A”µ‚51§q³&"fŒ£|ððL†o†|ÌfoïÀÕMß±„çÒçVn ¬¤z\X€$*i@E‡Ìaä˜x¤2”À‘#²€ü«Õxô6±lúBÙ´Ö;ËN=k yDL1#—‚ällmÉ[ÇpR ©—†ëI{è«Ôs_À¥æ«î|™.YT¨¤”“Àùª(墊¯’¯H9ç‘È&$ÕQRÅ%#å"¹“ƒP’¾Ë—‹þ¬Ãª À£žûÝ=¿ÏYœPÉl” *5&H£Y^¯aƒä/Ù–ù * K$ƒÆ;%£¢£¦”º²Z ³½y½_( ]aL!múÍr%\¡¯úb–âœsµçäÐ IDAT†NUCà“ã'Z¤iªÊØœ³ä²^_¹]ϱ¤”PU`¦$…™ŽŽOONžÇY|ùå;Žy³^œä’ât:ÍcÙÙ߯&uå'JŒ:mö©¸ÅÅpq¼yv|¾¼ZŽ#BÂ0ᦲ‹ Ãæÿ3>û‡ˆö¿uàÏÈ2Ü͉-Á2jïv&vo§6šq IlßÅ+7åÙÎÁgfÍ{Ï?8~øðéeÈÒàs¯Ì~úK?õþ;O¿õ‡ßi«9“ís5íß:zñVøõ7¿öììÜ93ß™Ü:¸e¬–RŒ!h¨*ÇFã0–BÆV•µLΙaV7÷^º%y|û­·ÇÍÐwÃÕu?igÊ 1“!¥œ²h*ÔTŽ];ô!–ä “©L3Ù¿óÂÓ˳Ÿø¹ÏÎeçÝgïœ]©-Ãy|ëâÉwë¨mÛƒ£Û[à‹"º™>P¹É!$•A-›­yGT• bXh*(#`–á <Ãgp!+†³£l(Ɇ`ULÑL@„3p•e“×kí5ÄIÅÈ%t»ŒR ÖZ “‚•D0LVJŸ’ÅfeCD1E$EªP,ëdˆR•1hŒ×ñzs²ñµ‹Yº«%zÁUÁh Gï´ò¦;”ò Šû¶.ª™],sA¡Oï­«—*ã ÷ö^üÌ7çÇçWëù¯¼~°¾ÞÝ{øèbÝ1Îrwy½ §Àü°²GG{w_Œu«×WW—½”R»·ß{¤J‹ežÏÚ©ËÖÖi3t!Zï,£ƒ¨Zðói;ÕRŠt›0™ö%¥­ZNƒ‘óó&‹H ÊLV”éf‘ÛZ $ú´á¢v‘à Q ¢T$@pà $vÕàécŸÆJU5Ûe?4Ü6í¤š4ZXB.¡H2ä¶–72ÖfÉsŒQ¨¡™«¼eš8RpOãÕõ²hAfuUõ1Cäº,æâk¶j²ñ­aŸÇ²TíÄM&jý0†¡1oRˆ]YrÓ¼’’báUûÙõå.6kžÞïz—G³ö{fç¨)”æÓ°„ij2#{WO'ÏžœZW…1¨ªˆ0ò|: ±;=}Öm®Úé|¹ècUŠÃØcL‰åÕ×^þïþ›úG_ùÊÿý»¿'{»»G»}¯*¤Ùº¯ˆ@$ Å:MêiŸÃ˜°„2iºÊœvïýì_üÌÑ“ëGßþÞ׿û½ooÒp5_¡nf;»‡ÌÌd%źš¥\TIPžÏo0x%cD-2ä J¶²‡T'£4ª2Ôoc}•ɲ0‰E±FmÉ b›o¦zjX‰FÖ’%1„˜äqˆaLeí2$ eeç ÉŠVÂ(°U†l' 80¤Ì ËLÆ¥Âed$ŠyŒ—C¨,³E¯ØÄ ’ʼnqÆ3Y_5±?É](ˆ=˜“K!0ÁõÈ9iXèÅzüàé¸cqïþ|´‡·^¹süþ[_ý_£×qíÜ_øéöS¯~å;þío}{Ý——?×&­Þ]œ,Ÿ¥Ò'fbðÎtz‘S.I‰ØÃ·­™Íöf‡¸º\„œrÈÄ AQÀ*jŠbk!œ‹ˆd¥çaÖr•l‹»!5 l5I"´ƒ5äaV!•­$»M’CVD‘¬P°…ze§$±KÉGiÉŽI»’›ÒÌ]Þñfâ­—UJÎ(ZW6ç<”RjãÀRLÑ’ƒŒ1 .-¥!‡¾Ä) Gœ\•4dí³ˆ×U«‰q,P5ÐIX‡~ÞÚÊÖTq/i“û a#›.8 ì9'YEU, %Éz=óÓi;3õŒ’FË…(ë³çQDDŸ°¸Ó F¹ä’¶þ&¶”J{ùA÷x÷`rp¸sxûÎdÖn6«!ôÕ¬Ú„Õ{SYßÔãØ¯ûž šYu~ë/Ü»c­½:?wÆoR MU“2€iÓΚÙb±H!û½ª$é×½ˆBÔWR1J*dQíM÷&Ë“QŸzy÷ñŠÿà_½óuÙ€ºg—OÂt2%÷2¶w&—›ë>„à¼:oööw~â Ÿ«j~ï½wÞ{ï½yÓøj2™q©®.×—ãºruãk3ÊŒZsÚà…ö½›>xüh2ÙAA)ZT%!²•o$iÉ¡µÕ^;±%i>é./Ãúáê‚zwë³/Oû'åÔýÃð+»;·¿ýæûú§oLjÅbe­íV$V;‡F… ª1‘&&¨R3ä$ìb²† 4磖‚VÁ†0˜ÌäKDe,dˆ‰™ ; ¡R$afæ!¦¢E‰°œb–²Áx¤aÇЦm²«¥,j]H¢ª¤j˜ÈBb)))qÉYi{´a¾É/#9 B%d§g] h\­¹¨$†ˆH7vqÜ|ÂÖL ®2 ÒI!²¾-’W©jô#:Æ·>¸î~û>wÿî;ßøæ½pø­7¿xþ…ùÞüîáOþÒ½ÏýÄOÝ=xéé;O¿üÿúƒÇÊ óÆõ›´ÓNÏ/×Z™ÉtÖ‡Åùõ¢3ÙjgÿèÞãããa˜É{c.²·%fÓ霈úÍZT¼·æ‡Úö›€ L`RKpÛí(*oa)jîRHyÈÈjX½M%Õ¢¹¨H l³¨KáX<0g;j¾Ww›&  i˜2UäHJ‘@Z¼¯EŠŽƒ%4•óÖªM’rÒºŒpµ ’Îú‹óÍÕ‰1uESÂ*•A¡iZ†b ’8Wd1®–Ø<¾^NÓ~»;(Ñå©×qÝ ½œ´¶j|+‰0™œóˆ1 Ei2åY­H]‰ƒÆ~{?Mæc(9Ä,òI;wQD€ù†ŸQQRó¡»:é¿ÚÎÚé|~p¸×ðäàîQ=w¾ªº±¿¸¥âªV¤Ö”ä†)´l¡°… RŠlYY’2¡ñ[Ê”BE8ã• ¨ ‰pQ‚’j’µNÁC¨Ä²T˜C\¶~a H”ÀÞ"ôaP(Lñ9'R&˜¬²ˆHÈCê@¤Û !¨BHUDo^.Ø;æäB*l=2bˆ’E#Æ0ºÂ†"j”ÁýÆ@ Z‚a2b»8’P)•ã1WÀøÃï¯Þy¼úÚwŸÜÜÅú°jχþÁ×qe~ÿÞO¿þêý£Íå#Õ‹nµ =* ®8Z<~|ABÕæ*dd€gg§ç××ÓÝ$…I©”?ô YË1Š÷¾®ëÍj O¦ÄlÃ0D ÝüTÁŠÊîÞ¬cڤƣºNÊ0Š(9‰dgEܘ$ÉI‡• `¨[¨Iê#x”8Ä´e’«¢ | ©&S—R½7 Š¹öŒ´žOµ¾;ñ6ÚÔ­Wݸ™^CK^H‡~×½ôb(”\†U/Æ'æd'A¨”È(>¦ÆOëZ-{ÖÇeE6ÙPbÉÉ ®k{„å*^—®¬®,ª[;w«YGÚ¤nd#iQÕíŒϺ«Dq¤Ô®¯EmÁJô‰‹;¨BAÛã’lPHåL öÆþúr¸8^ú)»Išîµ“ù¤6ÓùÏ9f-1LàìYÃ:ÓNë]€XÜáîUO÷~ÁåXš¦ÙŸòf³É±TUÅÌš\ql´<}x–Bîûq³îC_bx.B*T‰”†•Tù9Ó‘žÙõ9-àùHêf—\ˆÏþWÒdþŽ2Ñ÷!"QÑØa[£S I4𕱕÷­7AµÛÙ±}Œ“Ê]­/§~?È`®÷“?ñùÿùÏ~ðôÉúOþã£w¾õä÷ç|kÑ´ãþ­Ãyµ{W«MW74©›¡ïÇQ‹«³³‘ÒNj"òÞY㤔ÈÙC¢Ä°ã'—W›Çï¼ïk§óÖTÍr9ŠèvÌ©EA†2—£Ù¾¬ÃKóûwn±¤“óãÓëÓ”Ì&mî|ê@,ý‹ßùmšæ×¾ô™É­Mß|ðàÙ{Ë‹óÌ,›nH!9K–Ês/ {ù#zçÖÇ«ѲåLm×,@EåC¯sQacbÂDFoŠ;é,«*¤@y®ÿ2TDÊ袲½a $B3Œ|˜ñÜpxs¡ (¢JBº I$ÕŠ;)‘ ‘U2D¢9©‚!ÊoH‰EUU¥ͪEI@Ÿ˜uÁX¶Ž¥(¡°#0$ª‚"„©pÍìgW›”+×ÎÒùez÷ËßíÖâݽ7ÏÂ$¼þi\ž5$RH:F$QÃh*Ê¢¡ åÅâÊ×Õþþ¾HîVë1d•7ÌÌ–˜Ñ­W)KÔx7„â¶o;Q&‚aQ†6m3i*£™Lòõ¤6l›)Úœï³nB¦ÂndKÉì”X·¬èÍû¿5>²3Æ‹X“ÀJ¶‚YI®«‚ÔÖÐÔ¹ÝìkesZ¦1…8$ŒÄèe R,º l qQa2Ù`F%‚eÒ²0wõ¤ª"§5´G ã !#JV»±6"ÊZI²ÀjìG¿6 ‘Bœ¯æaåê:ä´’±G Ysê-öv;ýÿ„Åýc :ý¸éI­á-–F’¨Êºë±ªqq6œÔ—“YÝN§õ¤bÇD¨*Ïi€c #úÆìÑñ»'DdŒ»–ÆUÄQÖ—×ã‡a(I˜¹”ÒuCè£ ARDJ|C:%3Aùã9Ï+ºüh>ûŸ³à?XNêöÉN_?ìÅD`„H”UjžÙ³­­¹µ¿g|׈À—TÖ!›¼ûý—î½~|uüþÑ/¶{® ¡?_ë*K,Õ!N¦Ÿ{íÕÒ¿{r¶Ü ‹I»¿;ŸåœcL{;»Î ›Byë­·îÞ9<=;6dœRCˆCÖ¢¤ªE6«Mm°?ßU«–¯rΰÅxWb+ëÍ( Áè†#W¿qûögîÞ‡o.6Ë‚2ܽsØ6ÍþþôªÏìÂ~üógÃ3ïšåjS!cVD5¥ŒÌF?º:t³N´Í RyÎÞZ¶”’/nÁMH¡dHž»~”E V%|íx~MH!tC^ÚšŠŸÛ#dûc””`º9Ò–\²Šˆ*é6@ ȸ)îÛ'‹À(ToRxž÷BD^•D3DQ4m&ŸhšJúñâ¾]¬-ÛׄˆØ*›œCI=%@œ©›½4.ÝtzôÙƒæ¾ëéúɳ÷¿Ë+¼þ"Ê.žÂÎqçµ—wP½(ÍWÿ[Ã2 $J Ch&õlo¾»Û¶mÛNJÉ—ççg'§i ìÜ: Þ[C4Þ’·jËšECð–Œe'Rªœ17žëMÕÔõdjL3ÙÛCÝŒB]ø¤2J"ã·‰¢©”çî§Â`kDªE¡L` r°ÖÁTÐ ±ÒØ"7ÐJyŒÒ—bHײ.i‹&kT(Œ„˜ã€œÕ°aÏÆäB±è6¸/(‚¼5 Ù°Æ¥–¹öÈDÓlÒfÒZÇA·¨´˜ ¬¢Ä‹.$™h3bªFp£6ÉSfé$±kP(Óßh úC›@T&e)ªP2Ƙmd­’Œ¡Ãf‰ÍÙ7ÚÆAmëŒ!km‘䘚¦Ùå««¥s–`¶‹áçû>•‚œ  c Šoú4Ú¢3䣔;C fÙbÏU?Ö¡+°]-/?Ägß ÿdþ;÷®ìuîDÆpö³µqDYÞyðÖKŸžýÌÏ¿Ñî×/¾|ç÷ÿð›<>}¶Ø™ì7¿·³wu}öݯ¼õÕ?þ“Ýùίþêþ«·_æÏúÐkÈïhÕÜÿô§Wýðìá©·Õ|>W$6eµ¾zïÝ“¦úÓ÷?øà¥—^ˆ!®¯ûÅuÔÛ ¡rx8{ñŃ„óë«.Ž9ux;»blg³Ì0†…Ãz}ç¥;¯Þ½5³ª)ì·ÕάY–tµ\œvg·¸’ÝÃùéÓó7·ªW5³‰÷ʼò ÈªÒ ã |ƒãxþ‹m§BÛ«LaÜLt!7]<©†žC“Ÿ ŽÙŽ:Ÿ§ð6|ùîfË„U‚ÂXI¡æ¦Ï)Û\OÝU©@U´@ËtDÊÏï4Ý>dNÐöè!E&"€”¶ áF¤[„´ˆdÜDu|bÕý‡ïé-·€!Y‰3ˆÈªæ ƒä”û°ãªòî¥õô'¦wþþßûY“—ßÿæ¿¿¿·÷•ßû: þ«ü oŸ®m†öh÷­ï>šÍfØHΉ˜ H›ÊïíÌ›¶N’ÖëDrL9ç®3Fe°ÍÄÆ` š¢*"1°DUí½u"’R*"%Å‘q$A‚µÆ4-W-üD]+ܨrÞ>MS’¤¼u1®jyzvqvýlå/› Ííñx7?zòèôÉñj±²‰ÖC¸<ÆëŸÛcr1HÊ}Á««,·¾»UˆA ·L†DæÅ—n£ä1'×V/¾ú©Mž_,Ö1v+<Ä$Y ¨0$“Î&µ©Y5AMÛ¸=šMúöº_¤,;GG)ÒɳãjvÿøÑ©3íÓ'§ZÑÆX«d˜™Œ±ÖrYx0HÁl‡¶¼UÉ•¡ •*rc\"RUˆŠnÛòƒªP…<ÿ[¶ xÛ¦s•M¹YÌ{®ï‰)àA™Pˆh›ë¬"J$ÛY­~<àe½@Ï)Ûµ?V´ômÖªÛ,åùCC‰ ¬0ú‰—úù3Û›BÊv ¸l5.2l¡U.Òxž†€àºñÑÛÃÃr¥S÷~î ÿÅö*®rŽñ_ï_ïþñúŸãñ“§!~þüéåŶ֘"‚ºK)µ°‚B+]ztzòíãáãû÷–‡³>Œè¢ ï£opo»:›0.ß:=_÷·Cu ‚h´ª Ü@!¸qi…‡"€ì@q¡NVH"X[¶ùk"ú+}‘ZxJµï0ÜwÕA¨ê-MÕ|ß ä×É'@CDU„„îSáÜé `…*تMu¯ÎC ŠBÛIšPÕ^ù´ìz­À}4·E Áõ¿w@ µ}ÔŒ¿r¡H“+›8¥!¨¨ÁŒ%¥E)–ݧ±®¿~YvÜ=»øÍ'Ëó³g_Ÿ×ñ§ßýõóÏ¿¹ùá>ýÕé·ÿ쫊F¸×)O%O†ZQ_žÀ‰”pÇ7—wïßyqñr³Y_žO^u¤„[7olWW º~Ñ Î:9Å\!u.À W»Í®–®ÄÕ.‡tóÐY.†ìžHwÛ±Yµöo" xe1(¥šÔ¨}/ñÀ}é&b“×2"÷Øöðß²NpŽ^Õk*id LX¡SQuš•‚Bww¡š‰©…ZÀs#mj£gµlÈY/ÇË:^¢ŒPGô”(´JjŽ0uQWX’š"7y¥D„:¡VxðaÖI#GeÔë;¯7›Ø €À+d§ÀÌÜ+Q5Ѐ¦— 6Ð4—bû{7tÉœî ·ƒˆTº›lÇ+·Ò¶Nª ¸ þ£ÆZñÉìø©|öÿÏ\ߌðÿŽï¢*Š@Ò½éçý°H)USÚÅÙ鬨^…¤ó4»sû8Oþõ³Ó‹õøè«“~ÝÝâ­O¼__LtûäÎϧ«¼z¾>?÷á¸,º¥MyÚÈz³‘eZm7]k‘>õCwtvz N†ƒ£ƒãå;^e}ñ’¦‹ùòr³žÏR¸X¾}¼-»«6WÓ.̃#„.‰Zrˆ* XIb¸àôt}z>êeÞ—Ýeå5îÆq*7ïܯ~8ùnûòjq´8>z›ãÌóllÎ.ÒÌŒI{›ª(ˆˆ Ò:a¤7©P!¥ENµL8§Bº ]áTRšþ"¯ý¯&„Òµ­I©Õ {ÑÜEÚ—šó’Feë0m:¥2’ È=á„7c·@TD¡h d#æJHšHKzl‰BaTh‹°„M`ò†¯ÐPº;ªÀƒÒÔˆ@ܪˆÒCX¶=lÜÁ¥Ç·_nÿýŸÝþûgïÿŒ§ú‹wŽ6›+¹Ò/~ûå_þðå[Gºªƒuê.óëGhƒªH)pZ½qcyp0Ÿ­ÏkTô3 !ö)ÔZÝ„Õ\JÉã¤Å¬³®+^$ (L°+¾*c‡Ý®Øh( Î脃¥hqÏæ® Vh4"N*yÄ$H‚½Òk¢ ÌMÄÙ¹F"¼Â+ŠÂŠˆÑRTÜ-3w6#:Õž¨Å ñ(-ÌDY«6ÝÚ«K)2§Q|Tƒ” /¬E0•ÊÑÆ <#UôŒsê ’´zµ­£xSDB%k¤%x`QÔ HV@µìU«M‘¢ŒÊ7wÊuka¾=²Ë¾IB\("è„YÓ§€ Q’­ÂRò¶Ô†>õ›r•B'Dö<ï&ìXë,F©µBŸ"$˜Y®æ{äg)Ĩp'lÎäýüq-íùúµ˜ù†3ùOaÿÿtrJÓ>žˆˆ¨(é-Y)ER§RUY²+äÉ£‡ó[avhÇ7—»]|òdüþÉó»·ß 1n®®f›0²ïÒÍ»7ÏyþÙ¯?ûe§—_}ó9aV ¹–MÞÆ¸ÜíjSJ]—7n¼Ø½„.͇þ`“7»Ýä†ùáA·¦¼>½8ïN¯ËöÉÏV»qX,Œ]H;´äP£¨…ÀCêï?xpÿÞ{OOΞŒÁÎêtÙ›ÍRC7_,Ž‚ùæí»wŸlüνû¼Pñ®XPªûE]̪âJqJ€8$‚ª®dP8BŠD$I…ŠJ­°&Ƕêt2¤Ý¸8_=èÏ- ‚YIDATBÕ=ì{ ¡ŠŠ«ˆªDAP*ຟ,Ú±Z{)"AÑnÜIûÝH@€@÷ò½sÙg8ÒymöÖ¶Ée@Ø–Æ.ÞtrÒ>M{‹þzQ¨‚õõŸ$ÖãÅáÚóÙ8 ¦ žŸ\~ñäoýÕôéÇ=½ÊeeïÍñh…}w±E7[ÌæC˪Œ›±n }1à ]çóÙ<¥j¥žžžß{ëàð(O»²;¢Ì»>kžbŒ4ƒyrž&ËEcf³5ÛzˆH%¨Bsdc.–+ÌÅ¡2Y5н!RSfÌia`%2‘ ¥M¬&t˜YK&vT¶u·„ëÕ‹U–ŠJqÕ.ÄäŽ,…P¨D(]p/ÌÙÃ(Å„•æž rA‰­Ô1ÅRª‡(’$…kössN#Xé•ePÀÝ€êCÍÈ^\ ¢®âò/>5Ì4MepIEND®B`‚GoFigure2-v0.9.0/Resources/fig/DorsalView.png0000755000175000017500000000643411667757442020712 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA± üa AiCCPICC Profilex–wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû¥ò&" pHYs  šœqIDAT8µ”ßK“QÇ¿çÝ»¹ß'8°æÂ …RÙ…Ô‚^˜ t§—B]åM`ø„P ]ÝT]Hx%^)!MXmvS°˜®m~{ζ×ܘ¦Í8œ÷9缟óœçðŸDUryEô •k€ÇD£@w7’++XM&ï甚ÉWŸ;F瀬5ìvÒå" ƒ_[Zø¶£ƒóót«¶xANÈ„Ãx–Ï#£t:ÌåÐÃT çvwá1 ÀçÃZ{;îml¨×G]P^§€É¶6¾'‡}b»M†QžM™ÕÈ/67ó¶×ËoúlCvuñú‰À­­|ô3õ==ì4M~Ôð@€ñÑQŽ—,þØô÷ó¦ÓI*EF"¼c­ëY<õï27‡—.VåÈd0¶¸øç•uc1•“ན€"Æå©)ø-3ëkÈæ&^h‹%S ‰öÏ ,iXLY› Ž¡!4ŸØ‰; ©PŸ¥×í K»P@v}ŸÏ ÜÛ‹K:x"*•*]¢•º,Ö…²½a¼`ß§§ñKCkÈé d|œ~?èijâC}‘­ËâåeÜ•ü HFd",ˆKÄöšr`ñ:9ã¬uD¬2’ÖùHúD^Ú(Ãa>¨>{`ziCƒ1 áËØne³HKžBZ¤gç¥ÉÛ¼^\•ïk²×bšEß>íëÃÄÒ’ÊVÃé|¬»•¶B7=ÜnÒã)5½ïp\‹Fyƒ|n;8ø”;+$!Ú‡})̽½b Š/²Û!Át0|ÚÚ«X ©ÙY¼TùrªU@N¥hßêqÒŸ~ñ»©Ù¦IEND®B`‚GoFigure2-v0.9.0/Resources/fig/camera-photo.png0000755000175000017500000000235011667757442021203 0ustar mathieumathieu‰PNG  IHDRÄ´l;bKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEÕ #-ƒ6*uIDAT8Ë•MlEÇ»Þ]¯×Ž›8ޏùì¡MÔ P´*R/­DE¯€Ê¡•8@”rè‰ =#¸Ð'T$T D•*$* _*ˆ&D¥rKSÒ¤AqÓ&©õGìõîzm‡ØÅ V*ýK£™÷æé7£7of$þ‡NŸ>­Ѧ}ôèÑÕ§ÅJÏ Çcãû@ àkú …‚U­zûÒéL’ç•,Ë·¦¦§D«ÎŸÿ®\R¼ò¬`EQŒ+W.³¼|Ó!àÒå‹AI’!Äóƒ}>Ÿ111±ÒÓÓýRÃVWVVçE zž÷làX¬«ˆ»ÓéÌ;;Gw¶ Æ]×µúoù|²ð) º¨/Ìßëò<ïº,Ëj4Úùa:9ûøðZ@ûL3ûžB:xðÕÎýû´õôô˜‘öàôÌtÛ/W¯‰t¢ë~‚¡ ¥R‰‘‘ÑZq£øs___ø‡ÉÉøÌÌÌÛét梋u0Íìç¡P(qø­ÃÊž=»éííÅï×p‡kצ¨¸•šKoo/’,ã“edßfq4E&³pï7n$Ù»÷Ã0Œ|¹\F‘e¹í·é)FF†Y][ehhDb+“““kR,äHô°t?EÀR¶,„ ËM@k~Zå×üµ”"½¶†¦* ÆÆÆèïï§^«A­JµZÃh 7ö'$@‘7w%(—ËOtjµŠkÛø5ññqvíÚÅ‘#Gèêê" "IžWÍ«-Ú&X€ã8Oxx$Êe ]×I¥R$“I666‡Ã$ :ÚÛ7“*ÉØŽM­V—Å'„øèС×|%«ô8®[!ѳ•XWÜp:"Q-—ÏáÚ6B’É$¹\ŽãÇ3{ç±x75¯RË™Y)—ËÞq÷ )í<’ÏNž8ñA¤V¯Ö%I–2™uùæÍ›ÞÔµ©, ûýþðŽ^Ô ²™4º®‰Dؾc˜»‹‹$¿.lË2ÙP(øq©dý*Jggä ifO~@¼P(øY©d-A ¨Ÿ¼þÆ›Z¾P V«â󩨚ʥŸ~$ÜÞñÕƒÔÒEà6° ä¥F²å0Ð5ÆZc1PUýFÓ´ªªj½^^Ås¼ï:ö"°d€"àJ-_Tëͦ5 Jc®'¶Ü–æP—žòJÿÉ-sõF_k‹†¿Þ¼n)ö OΜRIEND®B`‚GoFigure2-v0.9.0/Resources/fig/synchronize.png0000644000175000017500000000212011667757442021167 0ustar mathieumathieu‰PNG  IHDRÄ´l;sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÛ :rµçÐIDAT8˵•Ëo[UÆçúúÚŽ}§c'Nó,hm¡iUH! ‰ +T$$6°bź©HH $þTAEÕ”ÐfJ»HˆòHÓ8Á(1qN“8¹¶¯}_,z’º&-+FšÝœof¾9ߌð<ÿÃäÞÞò€X€÷ï8@Ð | ÞÔóÈP*’RW­iG4žùè!%\>,@ùƒ³t7nºÍK±¿Þ®~îl\nSâë}V€ùE_’³ÚuÔŽTg%fyŽ’ÅQ&<[Í`©[ÃcæÉöez§zZÓæ±`9÷XJ=47çOe²À)¨{ô± ¬-@wåúñjpôªeÏ÷–ª7·ít¡÷ÚÅÒ↙ї\wÔ3ËýUu©3yóËY „öQ)*Ðôk:e9‹ÉsüÙsüTКNí¬¹¾6/ØCÕŠ7p”X Çgûl6•bM×µ¾Ü„Ü­¨ã¬µÅì…®CÎJ{—»©¬ZÉζô­Qð«~…&­(BÑ-0¢à݇*]„ð<ÑÑQ4Mã÷o.Þ.?+ ‚דÀU`®Ƙ:Eð«7HýöÏXÑ©.ÎJÉ?!c¯¨BˆÉ>$;: $´ å[hÇ®“4tz‹:!ày)Œ> „T€ÉÉIFFFØo5TiÀ€âb7(Yã9F?ð”êkT€B¡ÀÌÌL-à®+mœ –¹ì ,Oà:üü4‘‹§IÝ<̰åGÎHn}Òó{Ê›¥ûî B@Ðä)IÁìš”deE@ðYbž)ˆÄxç…ïøxq‡ú]¡È+Ñ#wnBJ´>&,—~àÖ¥u (T#k¦³·<ê÷s‡TTBVäÔñ.$ßq Øøú[›Ìzžñ¿V¹wøµÇ´ñ(ð °.A«÷¹>Yu]À{»~òÿ…Sd‘ gIEND®B`‚GoFigure2-v0.9.0/Resources/fig/BlankIcon.png0000755000175000017500000000103111667757442020457 0ustar mathieumathieu‰PNG  IHDRÄ´l;sRGB®ÎébKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÛ)]éUp™IDAT8ËÍ”?HBQÆWž<‡¤?.ÏE qhk‰†ˆ œ£©å…ˆƒ®­{(B-MAc[KcB‘AD-A«Qô5¼,òõä ]¸Ü{¹¿ósþË詇%‹-„½×=3š!¡Ç:º£"ŠPU5Ü<ê‘”RtÔù“>òWðœ™cši¢DÃu|¥+RJ…l©EArÊBtZP#éNqé*ØÛñ¸xxðà77Þê8cÓòòP*‘Lz3“““"‘Öí-J§}uKKâðPÚ-‡×W_ðÊ \_-E,æ«ÉçÅþþ°cë¨Ýö6Ñ(ìîÂÓj61åò®\óóprççðüìçpj Ù6ÊçÑÅ…wþ ö967ˆímqtàá”N£ËË_ï“ÉqÚ«ÛEÙìH1žcÇ««"[[~]ñò¶=\¯ÎΠVƒõuè÷ammD&ÚØ@–…&&g»¸(J% ;–ë"càýóö† ƒggáàà»Ó»;亡ý/ZsŸÅ¥±ÍIEND®B`‚GoFigure2-v0.9.0/Resources/fig/xy.png0000644000175000017500000000070711667757442017265 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA± üatIMEØ "rnkIDATHKµ”½JÃPÇOT¤âWu0D]ÄÙ½KüK tè–½K t1k:Õ¡vpÈ 8"œò nÏ9zÓXIbÈí…“\îÇïüó¿'·qu x||4@O3wˆs¸ ˜$‰Ö0v¡¹>C»*‘7¡3`<›É˜;J” 9= ðvø%Š$ÃýñXúÁdR ¬Ô.ªV@«Ó‘ejyþ—â<0/´{=Q«,)ƒƒ×èñãmœ•f½ÿ¸ÀcX¸Láâ|iUŸƒïßÂP”ûý¾ôkpcYxkÛú>vÒ$µÁ¯Ó©9\7-E­à'ÏÓVV°ZmVdaïqœú­åðòª¦¶Ç ¾>û{í xc%smB¢Ê¡ª"»GÀÔÄÀl¨ UßÌjµ–>fðÝnê3”âºV˜û¾ ºÙéiìQÿœ|b¯ò‚ç Vf®Í×Ð8ƒ¿ïf!ÍS—>´IEND®B`‚GoFigure2-v0.9.0/Resources/fig/navigation.png0000755000175000017500000001661511667757442020774 0ustar mathieumathieu‰PNG  IHDR@@ªiqÞbKGDùC» pHYsHHFÉk> vpAg@@êóø`¾IDATxÚí›y”]Uï?{Ÿéž;Ö<¥R•¡¨Tˆ DAXýœž.]OÀ¶µE]ÏåЮÕ.mmmiµCƒÐ*DI"2…TÌD†J*5OwÎ9{ï÷ǽPÚÅó=kuï=gŸ}öïûûíßt~WˆQ<YFC¤‰MJ|© «ŠRIE!ž~‡ËÅø ü+mt¬ ,„¦1JúÉ;€Æ5ÓjÀ`„mêwJÚ4‹ú½KTçŽðç’ü³ïü„þÀ‹½€›þÀ‹½€›ž¦aÅͳ €O~þ•ýl•}‘äõ‘`ƒ6´ƒ ¼˜ ÷ÂË«Ï(‚¿<½°g<#¦Á¼Q¼tY›üöò´>™H0•4ÅÐÄ¥\@€´0V\‰ÿUñÛ^<_– õøà¿ Íé'.‘[ÖµlSyÁ¼ªÅ­K]‚´ÁöÁ“ø— L¬ ay/óÇ@xÚ€øïրŨ¬3%~Ùê* Õ°~DZW‘€´ÀŽa\\ð/˜X3Øñú5ó'¯å¹øm„O=eY/ÌÞØâtÈÀƸc<£ëÕ@¤@)ƒFL ,Œ‡˜©@¸:Ö V¬Îü3­ôxy.æ9f1`IûyÌô,<(Á ÝÐpaêj¯ „F`Œ=æøq„oaE`üL} HûO2|æy|rüœ1`{Ö_Y70‹I‡Ö¥@û©C$ÀÿgŽ5=©òâ±sŒ6<ñU „9&¡iÜ{¬ÈEc°yJÊtÌl# ¾{a8Çl!óä1èXÔc@Ad'a|÷NïºãQñ8FØ 5ÂhÌ1òŒ4F„³¸Ÿ0¨†ü…VSƒêÓR HS¿ÏX ‘õx¤aú%c$Ó“£ŒŽŽbÛ¶-Ÿ©TúùPÒ¨ž4ÇYdm Ò‚š ;¦R‘¦ZOJEF€Ñ!Ͳ+Цîv„Bz®=73WÎ$Üç@ˆË̱¼ƒ¤cæOéæî„!aò%ÍØ¼fׄÅÊæIVõ b^’Éh ] A¶ 5e°…¡-ãEÐZÑ· 4jm –¦l&JšÀ@kÜBHÃ\ ”,k™W(cHJAÂ…ñ úÒ07TH­XÒ$™Õh£èL j¡f¾¨q,MoO;ÜõŸ›Ç®}çyÏ©ÏtÒ‘4[b1È0 t$"Z=!k´ÙuY¥c´KZd]H-2 ¢ ±†AÍ(‹jaŒ S5XÒ "ƒÔ‚¦¼!,”QØž ÙDZ’¤*€ÖT´AhCK$(7lFÆ€2Ï2 ZHп¤çôÙ™ÚÚÛÿD ®U·k²¡ÚÔÝ 1šR­Â|ÑF鈹²F ÉtI)ð,ˆ</„1ˆPP¬ò‘ÆhÂXV(M»ocɈɜA ƒßî°o6Dƒ+!lr™Á2ˆÀa¡‘«jŒXÆb|.Ba(WŽ%Ïil¾“£èv¦Ú;:ÒÆ˜ü³p¬0€¬´  ¨ïíHiBeÐ(‚HQ¨Ô¥¸PÖØ¤lÍBY„ÏÒD¡$W08Dq‹ª2T0ÂjI%”he¨ÅÀVE¥1 Šª¡D CŒ”k,Aà”TˆdÝ#ÊF‚²€d ‚HS1P«†à¦AXÀŸ À WÖ™—Œªk@ ÀBÓ›‚ÞVßu)†‰l•¤cX’´èÌ8tg\ Ž×THÂå‚g×`Q# IÏГØÒPëÚ‘4†ž„Á±êè·HEÊS„Æs,|ÏÂ"£iŽ:’£ ž iÏPMH ߪÒÓÔÎãÍ=ƒÀãR0äȆP€" …*t$Ÿ:¯‹†'Cª¡a]¯®…”" ÏH#Hzš¹Šá+wŒQ®V‰¨ÏгVf8eÈçÑC9‚jH Öt%hZ{g‹Ä,0Hö–Êœ¸²‰ñyÅî±,n\âI£5¥š`¡ Œ “dbÊhT$©E¤@4õ¬~ö¬ØÇ #8ήkR‚ªÛj šbЉ¼"_¾sƒá¸Ÿ·ŸØDKÚeºá PÂfx<äÞ=YÖöúÌ5µÈP é$;fn{4Ksʦ¿ÙaóãYš“.ÇŸÕD9ʳcÇ2¬[Ÿ"\þñuÝtÆ ÿëÚa~¿}<én›—¶±íñÆJ ,õ80b„F› ¬ôÀKžÓ Dú Ø6CÖ1Q 6†È@5Ôôv€-!Œ4ÿŠv~7Rææ‡¦pMÈ{Îì%“$Ét6àºßŽ£…Æ“³ê€ás·í&T>g¯É0³På±}9‚‘^ÿ¾ üü‘1šýÿúѵ,ïJpzOŒ@¦ Џ+¹ý#k™)»ŒÎ¸oç o8¹‹7ÒÁÏš "ÚÓqúZb̪äTXßÚÕÏ ÀSX‚¥‹p”ÈtC’žŒÅÝ»r(ióîÓZÈ—*š©àEh¾þË öOT8e ͆îNLæHù’0ÐDÄ5ïäÌÁvl[†ŠŸí˜¡·Ë¥=–¢9ÞŒkŘ*T±¥ÍÎà "P‘…ë†$]‡˜£XÝírjïRŒ0lXç/iFhmK Ŧ'Ø9/™êê_1rø0ËúûŸÔhYôPO„¢@`Lħ2I9´øàÙKyäHBÍpd!âó·!,ÁÈdǵØ1R 4AU3‘WŒÏW¸äü>Îjç•WìæC¯éeU»Íª%i\ßg¡27­È™*D ¨EácÅ$¡T(#-ƒ,C§g(©lµÌ\. eG<öú¥Ü¿;Ç­Îñ’n—LÂfe›O¹R C¼Aiðm‰r=Œkc%!& – ž2HŽø¦^ŸÈxðåÏóÓëöÒzr+zuW\·¯Ý¦=áa£°ýf²xnñ2çˆ1h®Gû­Éˆ6ßæk›–Œ;\`¨Ëa<ëÔæj´ø6(CÂ…û‡§ùÀYKzk 8cE†™b•@Uð¤ÀñRO’ŽkÒ¶Á«U ò¢ù#ÌÍÍ2Ÿ¦V,Q ÛÆõâ„­).=±x̆’É Ç¯êeßtH%‰ ŲÎަÚ€ýÏW,ë©Y`dê@“/ÈU,„mQá[›Ç˜ÊÖ¨†Š@ËzÖ#ùš¡´2¤ˆ•Í̇‚ÏÞz„þ›3VwÒšIÒ⥘ ­ M¦Vda×cüjë½ìxl˜v<†çz9:ÍÒž¥?ÂñkVs`ÿ®ë’iJ¡+†V.¡­9ɆuëøøÀ á ËøõDЇ§,š•D±þg5‚‹Ù°© |uݘz¬ë Øž¡3㊻Fó•Íܹ#ËñÝ.–% ‚º«¸¡*AE†JUóš“d‹†R ¸öÞi¾vûͽ]|ííÝœæOsïÞÎüû÷9<›¥T XwÂ:[ÇÊUC(¡hÉ4qttœWžuÛ¶m%Š‚Z€ÒšÉ±IfÆKlÝy;–e1ÐÝÎËO^Ë6žÃƒ¢ƒÏü׊A-ÀõÜ?À±à¸Å-`³X‚JdèLI=4ɽû'8yy†ÃS%V¶ÚtÆ-jÚ`!ÐÆ´¡æ@̔ʚž”ËšÞ—W ôq(»”½YI?“Dþw\ñ öâœW¿†þœtòK929ILÀÜüJ)/䘙f|ìÅ|žB¡ˆeK¤„T&Eg¼–æ2™&x`seÍ÷6ÝÁ;ÞúFîøú?|ô’ðáoç»×?S Ê6Çh€ .ÆÈ†Vh¨‚Í¥ - —mç8kUŠí£% ¥$rÑŠÈúdZ­øðyKYÒæ360[ñèi…Uò7]óo\}óíœ}æk9ëüNüX‚©ùiF‡EðhÑ"4hCP«bÅ<üd !¥r‘˜ï£¢¥ù|ärYúû—¡µ&ÙÒÆ÷>Ä}ïââ‹>ðÃ}ï;gð¸Á÷>„'êAÆ€”,·¡F¨Hé°{rá±2¯^ÛFsÚcÓ£ó”B›HK›,sh!`²¨(‡‚ÙŠf¦¨™/+<Û¦‚¶ã8¶ÄìßÎg?ó®ºñç\ôþ1ø’ã$Õ’¡V 9R xu&à$±³QÊå 1Ïáüs_ëÎyÙÜ,µZ• ¨o…(Šj5‚ DkÍêÕ«Y»îRé4ù|‘~ìclÙºå=;†wüäÜ~ìüzKòÕf2Ž!fC 5ÍtÞFD dóq~?=§“ÓV¦1F°óh‘l!¤'#¨DC ÁÃÐß‘¡$ +ªøÖ•—±}×>þá#bll‚££GÙ÷ø>¬F¹k&—ç²æ‹K‰¢â†lHZjöïÜEOï¶lÝÊäè$–ë ¢ˆ(ŠðBÐÒÒÌü|–;v°{×nv ï •J±eËý¬Y³fHJéuttÜó„áOÓ4ü=ß&Û›„^_“r åªf|A±}Ô¦ß9̉³DøDÆâÛïäè\€å(z3>¿Ø“ãÞÝ +&ràØõª QŠ#‡¿Â'±ÿv®¸ú:Þýž÷qèàAjÕZ½ì®5ÕJm4–Œ…Õ¸s¨ÄÝ{b\TuÉ?ðK~sçϹêêk¹÷¾_ÓÕÕÖŠ Œ°¥¨oa)QJ177Ç¡C‡¨V«8ŽÃŠ+hiiá²Ë.Ã÷ýÕëׯß Å“aoŸÕ‚ÏEQýP‚j‘Çç 5ÉEÕHtÌc¦¨xèh•Ý)¾ôæ^~|;;§*Œæ3%M)DZóÊž27ÝòsÎ|Å™LLNP,Qª.µ 1´1Q@ST%Z|¸2ȹÉ}\9¹™ì h5§žv:©d’‘‘CÔª5–öö`LV*öìÙÃîÝ» Ãx<Žïû”J%fff¸çž{H&“W=aD#÷’AÇ«ám@h(°­¤‹CSÞ÷ï{Á@ʵ4TÌšÛ~7ƒ…1õjp±*8sÀGͦ(2é Sã“DQD¡X"—[ ›[ R.ÔjTk5t¨pgF¹w¤@å_îælùY*ÀäŠô°–Ó6¾œë~ð¼ë½ïbvv–j­Êþýûyì±ÇÈçód2R©ºÁt‡x !M_:t\lp)Õ ì90EajšHG¤m—)©(ƒ ª¡b¢à'$ëû’ØÂðÉ›GØ´m‚¥1"ÅÐà4¢,¥%ãctŸÐCPª095ɾýû°°ˆTÄå—]NFÌÏÏ2>9ÉîÝ»p,|!G(5·ßòV­^Ë'¾|)·Þô#N¾àuœrê)¼õ-oᤗ¾”ñ±£lß¾/æu—hŒ!‘Hpë­·’Ï癘˜À²,úúúX¾|9‰D‚NXkÊå*6Rbt„\²tåÜÞYf¶~'È“in£­³‹?EkÚAºMÇ!íkZ\XÒ•¤=.øØ {¸õÁ,Ç/õɸ‚” ]I¤ Æã.{î¢ç hjj¦T*Õ_²šºÏ>Òé47Þôc>ôáqÃõ?¤³£‹x"ŽeYضeY$“I<ˆã8$“I\×EÁÙgÅÑ£G)—« u#˜ê7•#{:œŸ}–DeŠXº 7ÝNÌÏPqŒL €˜ÔmB°¡?I%ÐüþH‰¡®8)Gâ8õØÊucjY×ÌÍL³w÷nÞùîw±g÷Ú[Û(•J}ëáºR,ÛÂu]bžÇŠËY»~_üâùüg?G{['¥Búü¸øâÐÔ”áß¼’¡Õ«q\‡T2I2™$‘Hàû>ñxœ––‰žçÑÑÑAkk+ç¿îulÙºíÉPØMµ¢ÜX_zÿÝhËD ŠQ%V–ÖÌU¸6-JQ ó5Ŧ‡(Õ4¶ë0šU8eA“oH:†ñ¼FCsRR«jl)¸áúrÙw®çî»ïaóæÍ¬Y³†©É),ÛaáXŽã`».µZ»6ßÉäÄ ÊD¨ZÄùç¿–}öó‹»îfÛ¶-<øàÃܼiçž{A,CëzÏu]Œ1!ð}Ÿ¹¹9.½ôRvþþ÷LÏÎ’njjÉg³óÒKØaY¹Ž…vâvm9øn½ÿÂu®-ð- ;ƒCį?ƒ”t±FdKƒck Ž”H4 ;añ¥/}‰¯ýë¼ímocxx'–- à Y¿~=½½½”+&Æ'8tèaÒÓÓMïRÚÚ[)•  «Ž[E6›gõšÕaÀw¯¹†0 `hhc ®ë¢”Âu]®¾újÒ©?ºáGôõõÖ‚f»2;‚Vj¯±üŠå%|°B’ŽK2žE ¾/–¤))‰"ƒLi¤tˆIƒcƒEýeFÜiêQÚòE%Â*étñxœ+®¸œÿýéOÓÞÞÎm·Ý†%mN:ù$FŒ²c犅"¶]ßÃŽm#ohSéÝ=t÷t3=3M{GåJ•·ÿÏwðÉO~Š~ðƒÜpà ÌḬ̀lù26lØÀáÇY¿~=¸øb¼˜Çç¿ðEN~é©ÔjªÕJ¥þ;B+tT[h9ñ ¯SAiÇ(‹8Žã0S–,Ô$ÙªƒeYÌ• S%˜+´Éh.b®j0Z “ÍBµ^VÊ‚£S ˜¼lã+p½8›nÞÄûß!¯9÷\æ¹úê«™œœ¢P(ày¾ï#„Àõ‘(!B`{R‰ŒO×»?„©÷×)£h´¬:ïböÞùo`Lº­µåŸ?rÉ%^w‰ضMss\uÕ·9p`„OcÆ ,_¾‚îîn<ÏmÄ ¹\cêIM&“Æó<\×Åq²Ù,cccìÛ·l6ËÒ¥KÙ¸q#ÍÍÍaÈÄÄ££GùÁ÷¾Ïw¯½æMÀÏ1UxÊ{£ÒBHi¹õ¶4šZ4ÏŸ „ÄŽ%ʳsó_»üò+‚ /¼ðãçž{ñFÜÞÓÛËÂÂmmm¬ZµŠk¯½–ƒÒÞÞNWW'MMÍ$“)b±¶-)—+”J%òùår=žèî^ªUƒ,[ÖOSSžçÕÝ¡ã099É—_6Ë-·ü=po#ø¯×@Ž]t²o¥£;‰µ/ÇI·S8ø»?åg†afÏ–ÅÕjuxË–-LMM®]Ò»¤ehhˆùÙY*å*ýýýœrÊ)ÌÌÌpøðafffyì±ÜsÏ/ÙôãMìÛ·Ÿ‘‘Ž£X,â¸.ôöö±lY?ÍÍÇ!N#šzÍ5×pÉ%—ütÛ¶mrƘ'øÃ ñ„ü^ óÏH¹Æç¯6oÞ¼ç¾ûî»à‚ .xç‰'žØ×³¤—îžZ[[éîî&™LáyŽS÷@­­-47·’L&ÈdÒÄãÉFrãàyMMÍÄãqFFŽp×]wrÍ5×Üÿè£~ø-õ—#ycLíØ=S‡È_’t„FŸUåû7Þxãm7ÝtÓ)kÖ¬9çe/{ÙécG¶[–Å’ÞrÙ¶m†!¥R‰xå>°ùʇ :Ës€Lg-½:‰æ 0³_SÀôl×@ÀÀR#á9ið™}þÝ¿V¦§µzÝ#òd‡í+43OåÓÜýïù¸!‘ù•ÓûSŒoæ^¥4÷¢KÇÿsnøÓK ½EDó•³Þ;žSRRRRRRž¦"šk¤ÒÂp½Ÿô¯°zÕcCrí³ Úûh_ÀVøU[0éø=³ÅP±¶Ø yÔY=ÓÙzCsþèz£ˆžÎ¨{¥¤vî£x¢{1%%%%%%åYPD y´ð£·;KÍÀD´ZHufÞ•Eó¦1»³àÌš¨vãûyð³f)¿· g¾OfÁžîí¸bØ@j?cx¾ó‘N ÎóÃô쿞7›Ð{4WçìãqåfÎõCþT©yüÜø êdër4ÑÂ1ÌôkN¤¤¤¤¤¤¤ìOuƦk‰ i¯K‡7íó46ûµ¨'¶Gc¿6®5c@fÚ&5i? §vÀsÛ0¤¶É÷šGÏSO±fæ¿ÎfÌÓÈ#Ò4'®÷ï3Ô~Æœ™·ÛÝÏò…†®±—WÏηýVÔöMÑ>nÐ!Eé¸ÿÃ)00dÚÞEc c´ðÿJ){wuŸÌþÙgÍJ©ÞÏÖëõV« Žc¥Ô>+|ëÆ£•VF³v˜$†‚1—q—q® %Š+Ã3œa"¦b®• %(溅¤¦Â)å0å0éPÄuÈT‹TÒ <“€5vA¹îO ÓR22ZRI­È´w…÷ü0F ¤»YJp ¥Hk’Êĉ0$¸W`†1pâJ&àd8)F’(!J@ŒK`bhEÌSŒhp0¥’J­ÂÀ±V‚³X&mùEPÙ9´ââsE½×3Œ6V“[%¨D:Œ7ë ;Œà‹Â–VR0G-Áˆs‚1Dû¨$(Žå¯¾ŸÕËyþ­cþ-NJÙ{žÓë¾b¶÷Øî5%%%%%å·iÚ6iÇ`UPƇHk)ãÄŽId‡n#iÀ‡£5 [¡1†ˆ˜Úh溳ÕÙB±Ø~VÛ ø$ë$aè¾6šë5‘ d cH80 Ib´"áj2ÊÇõ´ÑD½ý4»¿az§KÃ0ô}€”RaÿÕZ· Eì_±ØBö]šb¥µVJ9ŽóŒm…}´“Ýç¼»~"ênÔ.cßUJ1Æzßêý{GÑK½^ÏårJ)»ÂjµZ(poŸzÍ¿>Zk•H­5ßßûj c`NŠÏ©Ž @Ck£‰îøQFàÄ $fÄ H©„ˆ3€I áZ?$ëéù:ÇɃ9òÏ~#½µ=ÀZÍÀóç¼Þ[?±üi uû( á:à FkãíòÚÚh¥8Ž(mCþê­–ëûŒ1ÒFW«ÕR±d/™ÞV­Ý´;'u <§ÐRAk)%眻.ŒÑZ3ÎÃFÃÏf´šÍ “iÿ‘õe ‡‰bŒ…a˜ñ)¥p}¥U&™lƨ$áŽÛÊ¿ º÷ù7 ¥Ù;pïß))))))¿OŠH™^•¡` i#i%›ÕZ.—q8†çC@%IDžëÁ‰ïDß Îf§§JýýRIÆy3‰4A! fj3¥|)ұǼ‰@[c$P Š¸Æø- ÎÁˆÁh-c͸ðüN=›“ø4[ÍL&Ójµ‚ °vEžçYE V«åóy«zÅ‚Oôßµn"Çq´ÖQqÎ]×/Q毰W]ôÖyÅ9_Pêôþk'JŸ– ±Ë««»º›æœW*•b±ø;p2ND¯¶Ô¦LfÚ*ˆz²mjƘ-³aÏF;‰¢í[ÔVR2b¼ciëqÌû­¥iF¤e¢c ßSöT¬#‘æ7²b0986ÂMG±‘Šˆ˜RŠ»`Cܨ}\JÁ£a4”Ž­À8k+©FЮ‹lȤÞläÊ%{nê­fdôBUëREôc^ß!ÇB8è\àq³éÄ1\wz|¬P ’$ ŠÅúôl&—cŽâo"%aìø> T,¹'léîùw¤§¸M=ëŠhþ]ÔÞ‘º74;Å3ˆÒš)))))¿CE¤õÞÌomƒš H+ÇžçÃhh]Ë @J8N»8—ÒÐÄ‘H´Q’´ >Fí‚*ïȰ)‚Ìk@kØØ-×éM7Wõ&'†6¡\ù¬;ÇÞÀ¦½æ`÷QÚ cBØùW)¥ã8F#ÆX’$Dd5ÒþžèòHÞG8íó\_ÐDxŠÕö:¯ì!t÷°×†ènâ@vÒú º3²öTØ•sέ§«Ñhd³ÙglñÌ@lÇc¨·À°uŒØ¨!¤„TÐŒC0­a$\¬£P¤„Ö` œ£Vƒp]t¿Së–aΕ´«¶‡JÀŒ‚!0€;í¼5Ä^”é&µwf$”lG5sÀMÂfëYTƒ¢8ž­Lï™Ü31199Y™žI 4#nt¢”2‚sGh­“$±gƒ¥b… ;80ë+-Z½º¼r)Šh WÔ«³~!GB¨ÎŽQ_‹ææ5=[íÝ8Rûõa²y•öì)e”&!Ú‰„1JÙQý­K¿2=¹«o°ïõ¯½[(,ªUá5ÃÖÄÄž­âŽΠ •b.7`ÏŽ"zV"ÖžBðX™Ô½ûÙP^ÆØ>·Ít˜¥¤¤¤¤üvfnïTt|1žïC­èÆküWïx·Ë™Ž‘hWê¼8`Ü€Dª)g85Ô8xY£a¬i¯…LÁ¸Ñ2ïd’$60¾ã·’ГdB-À‡`ÓµÙ|6¯UõáeK^ó†7|àþA°·N]Ï®³ÎƒÓÚ÷q»®k]CVÅqœÍfí³Vkíy^7xìW*"ÝADöõ$I”RAØešÍf&“Yð1o?2ÿYÞMìáœ÷:|¬GËZRJë²QsVõ.Ü« æ¯ßZ¯BãœÛÓbÏI7ƒ(›ÍîIØö½üÆì¶çÊX‹H$ˆÀxû‹4@­7[ÍZ½Uo4ëf­^¯×e«)Z’i%“¤†a«•HɈç®ãp!|Ïs=Opn­T-úòNÖÏd²®ëd2Ù|>.8Ê}`Æa4tƒÃáÞ­ºM€RZ+e´ø¤!º2É.ÂÛŽ£‘¨Úleû“OŽíØùÄÖmJ%R'RIIÚÐÚmIãÜqÏu\ǰ¤V© ÆÈÄÆ$Q«%Á¹ï‘¡ƒ–vôº¾%ÃÊÙ0Œœœ@Ï>²nÑð4þ¹#‡:Ѝ]9DűRÊõ„•ÊÌôôÈʃ  ¡"—«MïÚýîw½ýÆ[~öÈý÷}Üq²^ÝôÀÆë~z}±TÎfò‹–.“Qd41GØëy7Ÿ^§ñ>¯ÿ¦%GïMfÁ›Uwë5ÂBþ¥T§¤¤¤¤ü6°Òhÿ©â˜+×9xÉò‘¡Á#VJÚ ŒòÂó âVldR ò.cº•-¡©”ÏÍÌT-^ôð#›V¼bj¶bjÁ,Z¼hëc[— Mïšì/âVÜ_*ÎÖêÊH/—ŒÏÎz… W*W› &¸ŸÉŽîÞÕ‚ò™€ã ¾×ïN]ªŽu˜Ífï¼óÎã?ÞÆÎÙÌ™îÓ”s~ûí·¿à/ÀSfw%:±jv ³Õje³Y×u“$i4B!„ ³ÏrcŒ‚ë*¨Ÿëœó®`Ý>Ý­´c6Ϧ-íS_Á~¶7 iC¡ky´CÈ“R6›Í|>?33c¡FhaŸãµÑ,û;?ÏŠ”$Õé™Ý»wOÏV*S3Ó{&•ªç¸L¦ q#"m¸RýÜ60N)®ˆˆ1Wš±1!ï !ïÞMgàQÊXÒ \C…Í(ÈúÅ|)›Ïä³…l>SÌ—Ü\¦8<áÀuá{ð=¸cœ0Ó$‡sÇg @k™ÄR+Êå5Øém—åŽ(•V®\¹xxZCj(Ísw…ã2Z´d ¸×àpœ9Ý^«µúÖmOnÞ²g×x«Þ0­XJéFɶ_>0ºy몣?ö%/¢%‹|B«Õr‚@w&¸­6ÖýÿÙ°SÑoAÙ µ=[áº\ìÙ±óúŸü$n…oç»àyÐ\ Jƶm_{ðÁ™EC¥¾ÚLˆbH¹æ¨#=Ï»þg78‚Xïw¡”&ŽýU8èõºtSæöŽû댇ÞÏÚû•½Ã!zÓ5­ïÚó<ÆXWÍ߇߂rKIIIIIšæiíÇ›s\˜†QJ‚ÒÕÉ©Â`ÿ§¾¸Õ÷ŒMè$^VÊdƞعcÛÖÑc .›tšT¦œò¼\¥¶gjÂ}üóú׬LÌÈÀý¿üe9[4ª±«>9²lñ!Ç Ÿ;;¶Ÿ/Z¶ŒkÜóŽ1\f´Ž“v&σÙÛƒ¥ š­f6Èüã?þã7¾ñ Çql6€8Ž=Ï›ššêïïï{ßûÀÌÎΖJ¥}*u‰ãØc5I÷ÌËf³Qi­]×õ<¯›S$¥ì>Åmq$Ƙã8½Î+`ºu“\×µ"[ÂÎ.éyž1&Žã(Šìþ3Æ8ç]«ÂnÝó<ûY«Üz·2ߌ°¢«ÙlV*•W½êU7ÝtÓé§Ÿþáxݺu###ù|Þ¯­îÐ]s£Vž][°}JydãC2Œâ0bÚäƒlfÈíÏ’0r‰3mL,e%­(‰"•HªÚjr€1Æ=Θ`kQeú ÝÝV€4F)¥¥jÍVßu„ç“f†qWx‡„§¡©Ò¨ÏÌÖäh¢Ò¤ Lx$¸ã¹nàg²Ù s3㹫Ž]‡Ãqà»pÌ‚ÁÀL3j‘2žã0!²åò'ßÎ’ªãQb`&†+À´‚IÚypR5jµlÎÏwØÇŽj}bëÞ}ïøƒ›V‹‚€7b¹gËöŸÕ®9åõ¯A_!ðÕqŠî•Cúwé úmVàøÐB]ã>‘IEÙ CŒ%a¨9::úÄO ÷>úÀk>ÂqHå¹nÆ ´ÆÆwà `Ç2mÚ¼nݺ¾¡!;ãC\H©âXƒ´C¼·ô¥½‰Ù{To:bw™g½ÈÁü’›6LÔúíƒ °{eŒ©×ëQe³Ù\.×½aFQD=ôÖ•IIIIIIù *"Ñé¤ÛÑAÌ&V¨$掋D6ã¤QmT*• Txå›_ÊÛßÐh5¦vívÀGV¬„Tw^ýãéÿiN=úh±U×ywF¨çùÒ—ýÍûÁÝí÷ß?>¹çø—¼‘¼ãÇ×䙸ïŸü¨X,ŽÍL/:üÐãN:ñÏþâ/P.þÉÖÇ"f­^ îtð=ùÈæÇ·ï¬6ê ƒÔ6ZHÚtº¼Ø ÉF8Zëk¯½öë_ÿúßýÝßíÙ³gpp0I×ugggûûû¿ùÍo>øàƒ÷Þ{ïúõë“$ÙŸ`߲¦-·:Ü{ï½£££kÖ¬9òÈ#…QEQÔ›’dëq !ö116N)µqãÆE‹-^¼8“ÉtŸ÷vÒ´ÑhìÞ½ÛV€é Ö˜°õ²…¶Ãþ,Q«Û€\.'¥<ñÄï¾ûî#Ž8â´ÓNC'H¯Z­Ú…±PÅíߨ¥{Ø‘‡vn›wŠ ÄÂã6î§PD ‚`4Hƒ8˜&ÄMÔëhµÚ)oŒH­Ã0l4²ÑÊs×!.¥¬ÕjÕj5Š".811¡”†ÑÄHdžÖJeÜŒ”2iÆZ}ÓÜaŽðÈ¡;n¸•1×ËdüB©¯¯¿T.õóB&»rIÐ_bù|†Ð‘SíT7€S'?JžPš¤Ò$'GdÆ$­)Ãû C}GŸtð²úŸLÜû?ÿ—„ÕzÜŒ÷Dð}p¦¤lgèu»²ööIÞŸ†}ÊŽ5f? v›)ííC6kÎocö}`†Ú+cÝ ¾…v©w^ƒÛc2Ý)Ý–~ó¦?zçAhþ!õl¢·ñé>‡ùô Í~OéÞM˜½+5=o‹¬;Çd` ˆóöâZs£\ö˜ãŸ?\*íÙ=q÷w¼|¹;8•Àq–,YrÇ/n1Å\ÁHQ Ï…Òãcëׯãh5 ùBh­¤æ¾ £ÑF+­µ³Š‚ˆi Æ:ìv9Dc´¦…‚ˆ -ð ÀT uʈ÷ž¥tÅq¥]áp!8±V³Õ¨ÕÃ0$"Ïq¹#ŒÒDT¯Öì‘;Â9iaº”””””ߊ"‚ì¨ °MŠ\§‡"pëŒ/ëzÙSþ⬤¿ð®s?ðª×¼ööŸÝüŠÓ_þÿþÛWÎ|Å+¬ìËöÿËßýãW.þ’ÓŸ?ùŒÓ[¥Ü×þó;¦.ï½÷¾×¾é/Þü—gæÿG–ÇÆÆ?wáŸýË¿}Ï_³xà ïÛòø5?úÉ/îüåÚãÖyýÅí·Þ´gÏÄ)Ïo.^÷üçýâî_îT­X07—Ú=X:6!sJ Nصk—ã8çwÞÛÞö¶E‹YïÖºT*5›Í /¼0«ˆZ­V¡PÃð–[nyãß8;;»~ýzÇq-ZtÝu×=þøã‹/¶Z¨Ñh|þóŸÿÏÿüÏC9dÆ J©¯}ík÷ßÿØØØ~ðƒ×¾öµV„¸®[­V}ß?æ˜c®¾úêÕ«Wwë:X·Ò¶mÛÎ<óÌ#>>þÞ÷¾÷ãÿx±X´ùQ…B1v÷ÝwÛýÏd2O<ñÄÊ•+ï»ï¾Ï|æ3ßýîwo¼ñÆ¡¡¡µk×vgg»Â¦X,ú¾_¯×¬Ø³N¡|>OD»wï^´h‘58–.]zà 7uÔQÕjµ\.Û)ä7~ö³Ÿ½âŠ+–/_~衇nÙ²eåÊ•çŸþ‘G†a&“9ÀAÖã§Á´–m‹‰ž ! 8ÂJN?òH_¹|Ï/ï,•JË–.vú¸²mïŠOÈáØ¤ Àp@È  "€; ä“d1Žc†ðüv³àj-®ÖšFØh†Í°6]…TµJ}vj2A¡ «õb?Ó ±Ö•¸9=nÛ5IŽl"ª3ßõ³™R©Tîï+õõåËE/xËà:ð=Þ–vmã]CDÜ6ù2ÆØzÀü 'fv •ËýV,ŸØ9:6±ÛÍøKW®@Ñ3Zk‚êÔ{€¦vY;fUˆYHÙÌS¶„ ÞU0¦3XÈ¥”Ãg0ÊÖŠ ÁIˆƒ:¢Zè$‰}Ï £Ð÷\ÚhN¬Ò¬»™¼ @(#öéuÆÚýÏ’N3%Ãa`ô^%a:½¡ˆlÏ¥žðÀ½S!b¾\Ñ{Ï€îœ{Ìs)ëžÚ,RIÆ#FXV!„Ô‰`¶øuP›žÉ—ËÐ œk¥çQ ÇÕ0q£™õò•*%˜I †äàÄ2Ê·E(jÁH×ÐI29åô÷C'µ'v¯:x¸¯|ÿ]wnݼim±•Àw¾Ññ±ÆöÑÛv½î˜dl·32‚ٙݓSË—©©i^.³f%‘ȱG6íܵspÙÈŠÕ« #/“±Z­áû¸p2N8#0Á£jŽ×ën6 )5 s­¤&Äq¬´ö}_8N£Ù2Ùj­R,“Xº®k€8‰…vʆó}ÐqÐ#<8²h¸4ÐÀqŸœœ\~ÐÊb±£M’¨$’q8<4°gzJ†­%+–mHpWˆZ­A¡P Æ”” "£51–fÍ¥üaðŒg{}°¿ ïÓ}¦àq=ÝõüÞžÿ}>žz°ÿà‘- G€lÏz2fL .Úùý±4QrÛm·{ÊIçžûÁ«®úŸÓO9£Th&¸óÞÇ´jÉ’e}á‚þBv¦Õºñg7ÿú×.vïœZº¢4¼tõë—-«LMn{àÁ‹¾téaÃËþý«—®Ó‘#;㌳fZrñŠ•w?úÀÒ5MLMVãèλïÙþó»CçË}”lEçÛ,|ÓcÿØÉMæ8›6mJ’$“É|ùË_þØÇ>æû¾ÕÓÓÓ÷ßÿ<`]ÓÓÓårÙE8æ˜cFFF¤”\pÁ±Çëûþ¿ÿû¿÷õõRNLL¼ýío¿ãŽ;®¿þúãŽ;ŽsÞl6?ðÑ»Þõ®+VØ`<"šõ}ÿ»ßýîæÍ›?÷¹Ï]xá…®ëÚ"Ý®ë>þøã‡vØ¿øÅsÏ=×óÑ~ôûßÿ>€Z­–Ífô£yæ™ßÿþ÷_ýêWÛ4˜™™™o~ó›üà/ºè¢+¯¼ò¥/}©UwÅbñu¯{Ý\ðÊW¾rfffåÊ•RÊcŽ9æo|ã5×\óâ¿x~´ÛSx“º ´Z-!ÄW\155uÙe—ýë¿þk>Ÿ·þ.­õºuëÞþö·ßvÛmårùª«®Ú¾}ûÚµk_ö²—ŽŽú¾ßl6c¶ûÓ¢ Œ Hƒ¬mÏÛ]u´¹ïg×oÞ¸qfb2nÔÇ­Uf]FRJßÏcn6^´bÕÁ­YY± ®€”px[&)©•T0Ì0N¤ÁXû]N ‚›QQĹãè/ºýEwo™8R!ŠƈbÝh%­°>SiTª³“Õ©™°ÕÒQÒÒZkYÎ猉âÊøî™Ý»ÁÈpF­$v<7SÌ—úúúúËý}¹\Nøž³l)í­ g¯6"ÖÎPJ”@œ —£¿8Ô—’‡ÄI¬”ŠÂ¦ã{¦›7Ôkè3ŸÈyÈ’åŽãœñ²Ó^¾¬¶sôÎ{î. ZÆÅŒ/¸ßŸœ–qÜjE‰Ù½sl|Ûv?1^¤EŽjáÚõÊå]ÛwsòŸÞþ‹_Á}wÞõ“ë¯=û¯ß_y|DzN~0”¢ÚìËú#™|DäÀ0Ñ)ù¥:?iLNî¹ùæ›GFFvíÚõõ¯ýœsÎ!"[b®X,þó?ÿóÉ'ŸüãÿøÑGõ<ˆló¢C=tãÆI’´Z-ÇqÞñŽwØ3Eч>ô¡ë¯¿þÊ+¯<þøãí;“É$I2;;û¹Ï}îÉ'Ÿ,•JSSSÅb±T*¸øâ‹}ßÿÞ÷¾÷¥/}©^¯A`k[_tÑEëÖ­ëÖExá _h}PO<ñÄ;ßùγÎ:ëE/zç|ÇŽƒƒƒårùì³ÏÞºuëW¿úÕ¯|å+'Ÿ|²­0;;[­Vßýîwÿ÷ÿ÷ ^ð›E‘•p»wï.•J]eÒ[Ýá)DÑÄÄÄÐÐÐûâ¿(„¸è¢‹>ò‘,]ºÔ–¦°Î®B¡066ÖßßÏ[³f͆ yä‘™™™r¹|à>¢.’AdÛÌ5À•aóà¦G¶oyœšñ²þþÆÔìâ ï2ªG5WòHé¸VÙ¹»2úðÖ;~r“áLs:ôð#²ÅÂÀÐ`¡¯œ+äÝ|Ž š ˜µPÑŠ!C0‚ëpá"’ ÇR#OŒ!pø0>¦µGä…Q?°œ±vuïV«6=Ó¬ÔfFÇM”´Z­z½Þ¨Öêõz«Õ”­$“ÉDq«9^Ÿßá8œshc¤Ìñ<¯P*–úûú‹}A1ßC_ ®°Î68`LkzÖ÷} —»mWO"UœpÏc i@÷ö›ÿv¯…aNì“0.PÜÖ€ŽHÈa ¤ð âÕjujº:3Û¬7d’ä3Y­5i­…ëh­Ëårî¨u^ÍuG¥˜¶®™Ç&AöZ¦,x¯T2Œ[UÔí eÐ+,Aè:‘€vý‹Ž#joW)¢nª9Î2ëíáŒs¶×¤ÖR1AŒ1'@é(Š‚|~¯ÛÈzH´ÖÒ(!ãDDœX[¹)倬5ŸÄ1 Ç‘œ)Ϊ$û\úñ'o¾ñ¦£Ž<ò_>ýéµkõ[Þ‚¸…þ>vÈÚî¹æš_þ?Ÿ9äÐC_÷ŽwäJ…c²™ÕkׄQÓ]4|?ß×?>>^©Tn¿û—'¾èÅ„Íë|uÜ _þ†7 Ž7>þP \HÝhÔ„ëC šú¦ô}?Èxk;33µG–ƒ'·<~ò™¯ú»¸5ÛÜ1>f2¥\}Ö/-¼ëÖ[×tPdTs¶êÇ›ßIzèÑMNyë[ßZ­ØzÄåryÓÖÇë̬<åø_Þï[Î|Sqh ^¯sü1ýå¿þ«sZ³3K††[CÃ;&wOŒíJâȉ4‚ï8´·u šÀÁÁAcÌ›ßüæ;ï¼óæ›oþú׿þ¾÷½/ŽãL&sÏ=÷lݺõâ‹/þñüðÃÛ ÝÆ+¦¦¦ìªÊår’$œó$IÂ0ŒãøÊ+¯\²dÉŸÿùŸÛˆ8ë1Æ J)s¹缿¿_JY¯×oºé¦©©©O}êSùÈG>õ©OwÞy¦¦¦2™Ìë_ÿú/|á ó7sÉ%—wÜq9äÕjõüóÏŸ=õÔS‡††Æðð°í$„xç;ßyÁ\sÍ5<ðÀñÇ_­V‹ÅâË_þòë®»îŒ3θîºëžÿüç[3b`` \.ŒŒØ´iôÔ„ø•š†††šÍf½^¿í¶Û„çŸþ‡>ô¡þð‡ÖÀu]ÆX½^—R.[¶ÌfMOOŸqƶ¼D½^gŒ .jï ‘4övÙœ8À4^uÖ™÷Üò‹‡ï¼k¶Z×Qd\$HêPE"ðÊ…"ˆ¢D†­XéØ0zôö{…Lp©%q’$ †ƒléªl!_êï rYæ:Ùb>W*J£%3™ÌÀÀ@6›µÚ¢×IÄàI‚(„àÈdqÚU™çðü|~(÷-:òн£0‘ÊvIjŒí ›­F­^©TêÕju¶R­Vã8Ì%¡œÚÝœÜ3nÊÍ aÈ^6“+³…|&ŸËd³™|Î ‚U‡ÀâD%±ã¢ h»G÷I‚i×1f¡/™æ*"¶ÿoÅ.6\¸šáìÄž‰ññÚÔÔÔèxT­Vgf[Õ:Ó&nÖó=Ç [-žïÇqÌ]'I’\.wz.CV2‚!‚$†¨[uÝìõh Ìv¡²)‚œ4¡Sß=ý¡ö&‘U<Ý—UÛ×ÔB혺½axfÁP+F4߅ňŒÖ•ÙÙ¾¾þf­–ñƒÒÀ ’°åx>kÕëA>§´r¸#µ$bLÅq‰“×1»OŽ„€RŠ‘Q‰’{öì)är6l8ùä“o¸ñæo]tÑ[>øÔªZã¦[n†`¯þó×­=îy²V•Rú…|±\,2 5;”Ë/Úpr†S““‚×A£~ï]w+£_~ækáy·^û£¥‹F¶l~, U3lpÒŸB+UoV§f8ˆ]Ù3…Vh’˜iS™žY²d‰õ5šÍ‰‰‰±±±µk×r×aÂÙòè¦F£aŒYºtiÿð"“HaÝ{Zƒ4¤ |à2 +SÓ“ãe+Šý¢ÐŽãðra9­Ø±c‡ ✋l–ÆÆ¸•š@&“ Ã0C[‰› Á]Š/Bô4ÐZ3[³O¯]uJÊ3³_ŸnTØo_™ünµÐ³užîz~Ó×þSìO*„þ(KÎàbÛŸ(±†F”@:ž‡À- õ-Y}ÒqIÞÓƒ‹=Ù|âðçuxÖUôè–GÝEÅ×¾ûÝqÝOúúú^ýg>![Œó‘‘%cõJ¥.^¹¢48°iãý3qóuo{ó¾öíëŽXó‚cܵs`õ²L}  Û¼©\È.ê¸åúk3ý…Á#Ó¦Å3¾ãzĘ5|ˆA‚u¬i M«Ù¼á†^ùÊWþÃ?üÃi§öùÏþoÿöo(¥Î9çœ}ìc+W®ôùÆoܰaÃ>ð÷¿ÿýK—.žž¹êª«c‡~8ÇqlZ‘뺭V먣Ž:üðÃ~øáë®»îøã/ •JåÛßþößøÆ+®¸âÕ¯~õu×]·dÉ’¾¾¾G}tõêÕÝjãî ²F†ïû™LæÊ+¯<ûì³O;í´sÎ9çóŸÿü{Þóž|>ßh4Çé¶N¿öÚkíäô—¾ô%ß÷ÇÇLJ‡‡Ÿîhã>‘×í@'n`4Ó¬¸bùK–.}É)/¹÷¦[·=øÐÖ‡Î0¶dÉ’±É•´tÔ0Æpžp\×s¸hÕ[&N´I\æÜnF0fˆÍZ"㸙LÏÔ)ëQKÃ8ž—+äaËêa)e£Ñ ¢\.'- A©¯œËå¼ (–K¥þ¾H&nàÙLÍær9?ŸC!ÇAµ]Dàgð\ÀdW/Ï ÑÏçÞ¯50Û@Çõzm¶2==]™™­ÕjqU*•¨RiNNÙq(ˆqÎÁU¹°bíšuëÖ•GF8)¡äÞ.´ó=A´pe¢}½"í‰;*l —±¿?›•Q´åñÍ[6?6º}GufVKåЊ‘Ä\#ã¹9á9a£Y©O–óHã(h GÀ±n×ZÃ1Ä 'ø`ŽíÇcö©OÐýŸ)+UF Ó£ LÏQt•ê$#éµ(¬£¦«–º¡t T“`JÇ s ¤’B8ÜÄq__? 2Ù<¤´±|Ž Ià8A62Š=ß¶á0ˆ7Z)£ÚySFƒ14[È´­)¥pÆ´ÖkŽ{Þ]7Þ|Óÿ½ùäW½êÔSOý+¾óók®=ñôÓ˜#^úŠ—ç‹EâFiÁüRŒ®ÎT ý}"W&<i¹dÂ&„h†7Þ캣ÁéG—ÿ{’$¯zÕ«¶ïÜ)šÜµ®©™6S»ÆV­XžÉdÙø´q¼ààe+¶Ä2ëgU«É³™ÁáEà,Š"0Q\™ž±SHµÙJÿ€Ž“¸Þœ¨ÔZzµVq„»zÍjžÉzÄú ùÁrqrb¼ØW¸(–ò­É=Aÿ Þ©[­V.ðµÖ<ŽkµZT«yA!Ç©×ëÓÓÓÚU^” ÃЖܤöõµ×}†¡1FÃØ’žÝBÞ))Omà>u•ù””¡Û½ å\µ£L:ɬkvxžC˜jµZÓÓ“[6™°Àxâ±êäôÄĤ‰àe2…ÅCÜwŸÜòØž-WÚ¼néòÉí;ÿëëßδ¢/SÚ9[Û]«…RÅG®»uû%!&·íøá¯ëó²o~lêÿå,ºà³ÿRÊ—Ìî±ÑSÿôÅ›õ_Üvó®G·$…ILF£© ¾×6qL»îœ5>ƒ\úØÇ>vòÉ'¯ZµjË–-ÿ÷ÞyçÝvÛm›7o~ë[ßjëªMMMMLLt]1õz½P(ô÷÷ßu×]Q%IòÐCÙ“p×]wc*•ŠI³$D´uëÖË/¿|ñâÅBˆ 6{ì±vìØñ³ŸýìòË/B¬_¿þöÛo¿úê«mÝ…l6[.—ô£mذáþûï?ÿü󝹿š»ï¾»¯¯/Š¢'Ÿ|Ò®¶Z­ÚÐ5»!ιRÊÝÅq\­V …B©Tš™™ùÎw¾S,/½ôÒ“N:éÖ[oíëë;âˆ#šÍ¦ïû½gÄAdWîûþæÍ›øÃ^vÙe¾ïŸzê©wÜqÇÕW_}ÖYgù¾oAvUÛ¶mûÉO~R.—·mÛöþ÷¿ÿßþí߆‡‡'&&ž¢ŸÉü` 2Òu’æI4C53Âç­ñŸ¬ù+Q­Õ|pjr¢o||zfffz:Š"‡9 $[I­Ví/÷ëDÊX)-4J©Ðc ÷„Ã8³)p®ë*ÆXXm”$€C.çÜ7"Q\ÅêIØšh™=R'#Aa”d²~ÉfâX†a3‘Z1½dÅJ×w‚\¾T*”ÊýÅr!“/8žð‡`4à4”†J@œ¡/ d]ô÷kÕ¯ *&( i6M=”IÄ™Ã|nÏEàèÀcBÆ(8„ýõÑ‚ÑÔÓ¥«{ªM¯¿h¯42¦“ÅÔ+ŠˆÂVËó¼Uk׬Z³P  Ón¶l/9 LLÎ>¶e|ÇèÎ'žl4{šÕ0Š‚B._.-Y³K† ””3íîaÊ€:3Žad4Fdl\œ8íõªNJQ7>nn!¼ö Iª‹Ç;Ò¨ëjÿßþˆ™#¥Ð³œ6Ìumƒ Á´†ÒÌqU½ùèìZµÊÏæ»÷d[Ó3?¿ù–b_ùð#ð|ßÏfâFÓõ½8йë9Ĉ‰$I¤ÒŒ12@œ+ ¥1Æй€Ál‘’ÕÊ›ßôæK¾òU÷ºëþ䕯xéK_zñ¥_{ÁI/ân¡oùR[.£Q©d‹E¢P¬¦òsyp¡â˜Ç0&Sî«Õj÷ßÿÌô¤ãð—¿ñ p¼•…2 ÆÇÇ13‹b‘|¿V©®^å»}JƲŠŒï ð­Û”RFJxÙ¬_«ÙºüкQ¯g‚`Í¡k*33ccc:Œ¸ã Q›zÐ(9<<,{ò±-‹F†³ƒƒË:H6÷Ýw8™L°eË–#s9­U­VÉæsZëÚÌL½^/•JÅRɪšDIß÷=σ1QÍÌÌ0pÛÀJÙ$I’ØnÖG„4p.å鋢ߨgéÙª(ð+׳O+Âß•ãâÙÚîÓíø›Žš{ŠãJ«)üQ(¢:×ÔÎv† ƒc#i”i“e|À –—c‹”½éΜ›Y6´tÏ讉û'G|^–™Va˜Fgò³A$Ô“³÷\öƒPxõD†R]û£Ûs|ã¬ÐH^®ptÓh²«6ëZ6»}˶5‡rÉUŸð2^q¨¤vOæ$„ãåŸÁqm#Bc1!B[q†ÚôÔÌÌÌQGå8Î'>ñ‰O|â—]vÙ¹çž{É%—|ô£u]wdd¤¿¿¿V«ŽŽÛ¢ Åbqjjª^¯¿ç=ï9õÔS«Õê¶mÛ”RqŸrÊ)ÿñÿqË-·XGS†ŽãDQ´nݺ5kÖœsÎ9_úÒ—V­Z†!cìSŸú€‹/¾xllÌq×u¿úÕ¯žyæ™¶Ð\’$žçÝ~ûí_þò—?ô¡=ðÀgŸ}öyç7<<|ôÑGoݺuÓ¦M'žxbÇaÚráV†Y+áÈ#´zcvvÖ+ÿôOÿÇñå—_~ 'Ü}÷Ý<ð@6›BØLOËÃkó޾ò•¯är¹ /¼°R©AÐjµÎ?ÿüN8aÙ²eVbåóùr¹¼fÍš/|á 6êøÀæÍ›o¹å–b±ø´&ÞˆÚÔ­iËŒ ú2¤A®ë€qóȨ4ËäŽ]Ÿsø h´Zh4Ðj!Œ“f³^k6›Í£c±Ôqœ4[­z+Œ¢(Ne´RJ¥e¤cí Çu]2ÐIìÂ7‚ƒ ´QšÃ@ɸ©'Wøƒ’óA2Ѳ9]—rz&ŽC(d– rnà67íj@U4Æ 41MÚ0®¹!áßÉä ùr¾Xî/õ‹Å2Ëú‹;D Ƙ‡»p½žlÿ,9*20 L@0㸉1RÆŽãØþKša3ðüa¹×% ¦‡¸vÀÜ`9˜ë”¶ë¦õÁãg<£  ´#Ø%m’R3D,Iúr¥ã)=ï赕j\¯=¹sG-ljÁr¥â¡G†²;C*y€“3FKPB*&hhMŒ“ñ`£]ÅÉÀÓ Ã ƒÆ M[×iÚ[1Ž+2„„Ú%9„7P„„µ\í-aom zÏÂVËÏdD/›g²Ö„‹¾xAŃƒƒ¯}ík³##ÐøáWÎNÏø™ 1={ò/ƒ‚ëeƶnUJe<¿hïÓT1ç9÷ëLZìܹó›ßüæ·¾õ­8Ž—-[vúé§ßsÏ=÷Ýwßc=¶téR"Š¢¨ÑhÌÌÌØÒsË—/?÷Üs/»ì²[o½uóæÍ‡rˆÖú)¬“nÄmrš¨W0ÊöOÑZi æD{&v<ôèÿ÷éϲV”cÎp_©à»ƒ}###å¾¾\±Ô74T^½º<Ø¿$Šàù Ä hÎà( ™èJµZ­2[º*‘­Fs|×.aH%I½ZkUë±í‰…£££‚ (•(ér󡚬EàÂ.ó(Ï ”RI"ÃZKA†„1Ìæ4ç¶»lX‰§&Ç&¶á:ö;M8MË›Ëå …B±XÌò~&#\gÙ²e¹b¡P.!›…`í2kD”hOOp ‘ö Ü ’ÑÛ¹ùsÒBìÍ#ê­š`Œ™ï8êD ™®Ô!Œi'ùØš{ ï¤îh Î(ðáYf  rihõŠ´LH³L05â¶rÓĵ†7Já\JAª]ÚÏ0C€‚fH4‘"Í`º nÉÊgÝíóCHi[ùp%(pСAÞµ’Cë©/×Ò3p}„FµúèÃ8ì°Ã2…‚ðýúα‰í£ÿüÿôÝï~wã/ï9á/ד“õéÙwþ¯·ŽŽÞ{ï½ ÑØ1æûþ¾}clÃÉ/)øÇóa µD Î]ª†¢ŸË=H=½}ç_ñÝ×¼â•ǬB’ ŸG£þæ¿üËSžxòçwÝñŠ×¼:RÒ>çNÞ÷Za+›Ï·¢9B8>sÀ¹ÃЮDÎÇŸØvÓÏ~ZÊåN?õ4þé¯x%2Áµ—_×E¡‡j Æù¦M›Ös´ïÏwÆw•†5£Ð0"%!øt­ÒŒ#Ï-ÁÆåóyp•Äa¸xx­zÃ!ÆÕÔt³Vw@Z°ÚžÉL&“23ÕÊ£÷ÜÛ××7´dq!“™ž6Æ f³¹ry9ÑîÝ» £ ›RSSS333‹—,É÷÷CʤÑprY)eǶr"[(ø¾Œ#ÃPx®½éÙ›[;Žhwdî¤MÚD»ô)žò¬›Ë¿‡Šh‹|~+äß&¿éêÛû[ÏþjKî3)ü¬WÊ‹"Ê&BÖVÙTeB- ™—QpfÝê÷—¿èh³Xù¢òÄ“_úþU­ú¦·0MÕfò…ÏþóöÑ'–-]äyüæ›núŸ-•&7×k‰s™÷>üÑ|àŽ=±ò¤#¿û½ï<²y[¢@@—¬ù³Ó^–-šIË Ü^õƒ»î{D1”]ˆxÛû^ÝòŠUÀm´ ƒ7:C¦ÝÖ†°ñžû|ß/—Ëc—]vÙYgõo|ÃæÃhµZ'œpÂ-·Üòðÿæ5¯é´,l§íJ)4›Mkô+¥^ð‚œxâ‰7ÞxãûÞ÷¾7 !„¶fw&“ ‚À>ÂÆ•W^¹zõêO<Ñn(Š¢~ðƒùÈG.¸à‚‹/¾8ŸÏ_rÉ%ïz×»lKV»äÏþ󱱱ŋŸþùW_}õ¥—^úþ÷¿dddÑ¢EÓÓÓ63gãÆãããùÈGl!;{©k­»¹FŸùÌgŒ1—\rÉ_ÿõ_¿ð…/´/öŠ“^)Bôÿ³÷žarUWÖð>çæ{+WuNên%,DŒ L03`LìaÈöØ`ÆØlìÛƒ fŒÁ6’@BHÊYê Î]]ñVÝxÎyìV[3~Ÿy¾?ßÏÎu«+Ü gŸ½öZ{m2iÒ¤îîî t]Ç›íß¿?“ɬ\¹²©©iÞ¼y555¾ïW*•ûï¿ÿ¾ûîûÍo~³hÑ"l¹ÁV"EQÓu=*Š2<<ÜÚÚªëúÑÏõ?Ôz\"Œ»„(§‚ª ͈†ùr{¢öðÀEÖ%¯P)æ*¾×M%¢È\"L"’eª±hËÔΦ)“§Î­L ÂA&!Õ%D-ø>pªªSšä3Ç ¯ÔŸA¤ñ^ÆÂBÁ)Ùžç…¾ï9n1_àa軞cW*•Šïz2çT@_w縂qÃ0,Ý!\× =Ç2LPdSQI&\øžÏXuÉl IDAT JÒ$5âæ=xÌWŠe}´"IA8¾·…I‘…!gš¦Å“Éx<.骞ŠM1uÝ4M˲LÓÔu]Q2I’ˆeA<ŽNô† QB‘)Œ$¿@Ï#švÄ¥ãã]„€€¦ŽKæ8ŽýyÒ-N‹bãÞ@@95#¸—ðÉLx ª¨Z`j¦ œ‚àÏYÁ!’¬%$ $ ¡3t«.ºN@"2ªK„@ÅuM]GÉ\¥\Ѝº¢É¾ç1ÎtìzH*—89 Qe F _†XT" yU0Lð=Uà¡$+vèšDA€3Æ9—Q$_îÀÀÀ’%Kǹÿž{MÃ*³ª»à óÁ°:[Úª•*ä‹ÌñœbY×ÍΖ¶Uï®V"ªzÍâËßxëÍ)R4€ñˆn:/‚’Â_–àbÓ†ÌóÿðêëS§tžwí×Ç ;Tªëì¸lætV­JQK°¦ë–ã:†nTWÒ$B¤R¾I&CÇ—5oÿÎÝ-õš,¯ûàÃ]ŽBœµðŒÿzö¹¯Ý~Ú¾õ“O>ikkÓ#z67Ú\_‰E¶íØaû®1ˆ¡ Æ7oøÄ Yo_ßPßôéÓöîÝ[µ+™L&78ª«ZÖÐÀ@:Û¿gišöáÑ––R__}]$‘ƒvvvf&OÙ»t‰a5ÉÔžmÛ×-‹õõõP­!…BAR•æt Èr躄]×]×ú>¨ªÌ–~ê …‚mÛí“'ãL(JAVŒ&ŽãT«U"I±X,›Íj𦛯Ähiøÿ¾ÍúØúÿÝ"„¸®‹ DÚhÔA)íêêúñ¼bÅ Ïóp2ám·Ývï½÷â!+IÎ^Åb;wî|ñÅÿô§?õõõ¹®»`Á‚ï|ç;‹/F9†$IýýýÍÍÍ`YV¥RAy…¢(¦iΘ1cÅŠŽãtttà¤ø¬l …l6ûÌ3ϼùæ›}}}uuu†aÜ|óÍ÷Ýw_µZeŒE£Ñb±˜H$!ñx|dd]p|$Ñ4Í0ŒÑÑѶ¶6!D&“Éf³¨æ(—ËÇü5×\sß}÷á»±eË–3Ï<¯ §epÎ5MSUµ\.뺞Íf-ËBã\ô—jkk2 £··7‘H`¾T­VE™4iÒàà ªªÝÝÝ­­­a¦Óé±±1ÜÝB×ueYÃPqèÐ!,.£°ßuÝD"Q(ZZZn¿ýv¼Â0 =Ï3MsÅŠ¿üå/7lØP©T’Éä\ðàƒNš4‰â8N±XlnnfŒ¥R©±±1œ£ÈÛ¿ÿË/¿üÆoìÛ·O’¤ .¸àâ‹/¾ñÆUUBär9‘‚«V­Z¸p!ŒŒŒ@SSS†Éd2—˹®+I’¢(˜ Bº»»o¸á†Í›7'‰D"ñøã_xá…cccÉd’Rнèøí:¶ãþÞprô¤“qý¾jšð«Üf9锿vÃuP•lþpí+¿ûK²Vñ5€¤N¿ñíÂ;^Ëôɯ/ù¨Rb:F[šnºã[JøÀÝÑâàžÞ®rÚê±!§.þ§Ç~Õ2Ä"Ïæ+£ûîΖ!pÃ|TRUÔ/UUÝ À(hŒ^._©T&Ož\.—1(œrÊ) ,عsçSO=Ùl6Oš4 >ÿüsI’p;¡H¬¹¹¹§§gÁ‚¦i.]ºôúë¯/‹¯½öÚ9眳oß¾“O>ùwÞ‰Åbˆy0<ù¾¿~ÿûßüñÇñ„F{ƒ+¯¼ò®»îúýïÿøã—Ëåï~÷»×_ýD¯ðÎ;¯»îºÆÆÆJ¥‰D~ýë_ßzë­—_~ùÒ¥KeY®¯¯çœ÷ôô<þøã]tÑÃ?Léïï?tèPCCC¥R‰F£h…—L&{ì1Y–Ÿ~úé±±1UU'΀£áëºŽãø¾ßÝÝá/ŒŒÏ<óÌSO=uï½÷>öØc555x$$“É›nºéŽ;îøàƒ„AT*•T*Å9Gë¼ zzzvïÞ={öìÓO?òù<¶¿å…þ¯µBˆÁާIޏŽI…*ÑÌégI.¹o çÒ ³Ã´TP8Pu½²ç„…J˜+îêØúáÚ¿¨’0U+“njokŸ6¥¶¹¹åÄSÀ ( I@d <8·v–%P ÇQp\P4e9‘ˆÆbQYB€óq,1áC@)P @ÀõA’€JàP.;e› Еû÷2Ê„çºår9p=àBÉsÜJ¥R­VÇÁd×­–mÊç‚„Âóœ\5(ôz™L:Žc†¦i¿ûÝïî½÷Þ òù< LÖ­[·wïÞ¥K—¾øâ‹¾ï†ÑÓÓƒ` R©455õ÷÷ã‹ÅgŸ}6‰lذÁ¶mY–§L™‚MT\qÅB9窪~ÿûßýõ××®]F…È„ÔÖÖâwsú}ûöáe766Búúúé•J¥‰“WUÕ½{÷~ï{ß«T*wÞyg*• ò†aT«UtaõŽ,Ó4EqDz¬h4ŠQZZZ†††Â0ìííµ,Ë0 Ïó(¥=ôšKÝyç;vì „ %U:Îårº677ŒŒ  †‚@H–el xàòùüc=A†ëÖ­ûÚ×¾†W%„¨V«¿ýíoß{ï½7ÞxcΜ9Œ±|>ÏÓ4­¡¡êêêàý÷ß¿æškÐ1%ûìôéÓ¿üå/Ÿy晫V­úÎw¾sõÕW !0{þè£FFF~ðƒ\{íµhçP*•‰Ä“O>™Éd¶oߎ¡|â<8šþªT*x³×^{mÙ²egœqÆàààÐÐÐé§Ÿ~ûí·ŽŽâ0Y C²,Û¶=þüÏ>û¬¥¥å­·Þjll|ì±Ç’ÉäæÍ›O=õÔX,V(î»ï¾Ûn»Íu]QëÁò¿©lŸ!˜,P€ B„„VÜ@Tiò—}#ÙðÁšƒŸnêîê‰1¢ªª¡é:U5M!„HTfŒ‡÷*l°’ÛÓ_X¹1Tå¢ zÞƒBœŒ·óSòQ…rĨ KÔÀP!ž6D] ¨çS dY`q>>P2äã€jÜfŒ”Ê„¬R­JÛ®Ú•r¡X±KnÕ. ÙìX¥bš¦š•RR.Û@'Œ Ή º¢ÊŠ¥¨F¡ëóPp áúÙ9²¡Z# ¥¤Ü=@)¥’$(&8çœÐUÁ9Œ.(!ˆ 0a=\àcâñ0ªÊù=ݯ<ùÌ”™Ç-<ëÌääNLÀèØHw×®=»{zz4"ÉN˜=Ø›– KVîéÞì¾×qҜӮ¸â:$$jºU,-Õª* '"±Ð«$$Š6PÍŠ×AÁ^ó‡ß¿ÿÁê“ÏXxÑ?Ý’Ò W–t€Ü®=ÊXùOßÿI4Ù•lžÖ~V©Ú½o_LÌ9ë´hcj8?Of8‚§@€ƒÜ­HÄ/ÙS¦NŸÒ2éÝ¥ËV¿»âªë® …úÙÇ{Žöô(ÑèþýûR«¹9—Ëç{÷ïÃáòþ={§Î™:EXõ™lO7 ùÇ«×D óÌÓÏPÒðx¥§ÛjŸ4çÌ…P­€D;gM[¹tÙ“¿|ª¹¥¥ìVoúÖ·@V€‚‹¡²¬êš ‚Š€Bøx¹XZ¿n]KSóŒù'€¦×¥3ý‡û Z}ÚÂÕo½NÊ6XFº®~ý§ŸÕ·4þÅE ,I¡`YÀ98öä¹³@hWA×(‡Lm0Ã2 (3fFáP.C$3#ùìXmCÃh_ÿÀÀ@÷®ÝÀEàù2‡†Ææ‘‘‘];w—K¥iÓ¦šY±––Ö0ðíjÅÒMÔ0,"™Nƒïƒ¤ uY.—‹Å¢eY‘H„@7KUUUU¯AP*‚À÷} D3 ¤h4ê‡!ÒÔ 2IÑÔ±ñ¬ÇÖÿu¡ÇD²ûÎ;ïüã?þ#clÚ´i=ôЕW^944tòÉ'Û¶½oß¾Ÿÿüç=ôa¼ýöÛ+• ¥ôý÷ß?í´Ó–/_~ÓM7ŽŽ¾õÖ[guÖ 7ÜP.—7nÜèû>,^¼øÕW_E –Ëå°€CCC˜©Ïž=;‰ …Ï>û sÎÎΟÿüç'œpB4={öÀÀÀÎ;}ôÑ|в,D>¥0öâ¾k×.<ßÑŸvûöíø§¯~õ«¯¾ú*ô÷÷/_¾ü›ßü&!äÙgŸýÁ~@)}çw°²pñÅ¿ôÒKG›01ÆÆÆÆ2™ žàˆq,û§Ÿ~†á®]»fΜiÛ66<ýôÓØpÇwüá‚À0ŒË.»ìå—_F- ç¼\.Çãq| …‚¢(•JÇÐÀààà’%K¾ùÍoÆb±×^{íž{îI§Ó†a|÷»ß-‹Édòí·ß^¸páºuëî¾ûîÏ?ÿüé§Ÿ~á…$IZ¶l~¦§všçyanذá¼óΣ”¶µµ½üòË'tÒêÕ«¿ýíowuuá Ç«¯¾ºP(ìÝ»—¢išçyÈËe2ؽ{7~=æÎ;ñ‘"£”>üðÃHÐ=ñĨŠÇã?ùÉOÎ?ÿ|Lo0þk(ú;EDGlP.G¨c\ßStM–4#öP¶{ËvÕ”ÍÍL6L™Ϧ"%–G ‰ÚvÉêÛ¾/ž¶6¼ööäꔩm­S|Oôf뛚í„̘Ý?Ô!ŒÉsgA:n¨:ë-T*NÂ´Š¥Rßžþºd2:\¼ç¬3{ûú EW|ø¦›nzâ‰'póc#Ê”)S|ðÁ;î¸#‰PJÇ¡”â×4íسgVq)>šœA†Ý¶í£uHXaÛÒÓO?=22¢iZ¹\N§ÓN§?ýôÓ ½A©Tzì±Ç^yå„L–e¹®;22b!q&ü÷¦ÏÿE<ìä ô!ÉƸÑ àà” ©¿àìKOš»cÙ»Û–.ùR¥XªV]úŠ'Ôó½JE•dSQñåp? ™ç×°,·<–;<:öéöMeB>•КlÄ£‘šT44±h*‘0¢IjEU+‰Zñ¨žL@"±è Hä…0,GG¨ËâT$XaòP¶" ðA€ $„뮀R°PбÆdLR„|Âè…[@©˜ÍfK¥~m<ϳmÛ¶íªã¤rïH@’$*„ð‚@!)R†‚Šqü%J©,Ë‘¨’‡!G|°…àÀ¹8ØL"Q*É"!¬êI„PJ¡Bˆ0`!gà†eVmW•ˆB•î-;÷nüÜŒFêêjëÒ©ƒû÷@{Û¤/Í>©6•îÙð½]×nØÜÙ6)SWMÄûözîÑŸ¸<¼éž»´ŽYI²Ð *5zÔRT)Œ•ìC}ïþáÝ5ÔÖÔ8lßߩËÔÌ^tšÞR+*nÿþýÛßûhÑ©§6vjâƒwÖmÝ´ôoìÙ²]®øk–¿ûÝWw\GÙ« E‘(%B%JTUÀ …€N@ÑOœyüï÷IN¤ —?nö¬-Û¶µ´µ6´6³ü˜‹©†¾{Ã'»öí1m:¸J…ÉÓ§L ¥BŠ|øÎ{}îæO6í=Ô8]–P©€¡‚¦€ãœs奊½eÛÖ‡Ÿúy`ÛÄ­Ê–Éü€*DÕ4We…AÀ¨û÷îv«Îö­ŸÏ˜9t£µ­mÏ®Ý#½½µ3f–•Juv~¾jÕ˜m·O™šÌ¤P)™Æv¬_çyža%»|ò)§X\FTÏB+Ó&—M Ê6pÑh±÷pOOOksK"SbñÚtüÀ²,S7:ÔÑÞÞÝÝ}\]Mˤ6àU«‰d*Q_~ȃh¬Øuphh8ÑÖšNgÊ•òX¾T ¨MÕu½P,:Ž£iš¬(!gŠ¢A€µmIçB€ïû^à‡ahY‘eí¿ÕbÿÚMAŽXtl[¸°öÇ4fð¾ïßÿýBˆ)S¦¬ZµJ×õ|>___ÿÒK/-^¼xÊ”){÷î=tèPGGGccãüùó=Ï«©©Y½zõÌ™3+•Ê%—\òâ‹/ÞvÛm===/½ôÒ׿þu”„ ×4gÎ|.4§E+&˲6n܈çxCCêÏo½õÖh4Ê[¹r%zÞŽ-[¶lÆŒ³fÍúÓŸþô裖ËeDDBˆãŽ;îèoøÁƒQ©5kÖ,”Ö£\%™L‹Åx<ÞÔÔtñÅ#Kã8Ž$IBˆÞÞ^Ó4s¹Ü¬Y³t]A?$Ïó†Â3³dHæÎ‹ûkÇŽ×^{- _|ñÅb±H)ýÆ7¾Q[[»eË–T*•Ëå.\8¡‹£”F"‘R©„ š•+W†aØØØxâ‰'f³Ùh4ÚÐÐpõÕWßvÛm¥R©Z­¦ÓiM|ðÁ²,?óÌ3'œp‚®ë‹-zå•WÎ9çœ-[¶à'xèСx<^,4MÓ4íŽ;îÀJß+¯¼ÒÔÔ¤iÚùçŸÿÄO|ùË_€^xáÒK/F£]]]a꺎 Þo~ó›GyÄuÝîînlF˜7oæZøa)Š‚c'3™L¡P¸òÊ+A•J¥O?ýÔ4M,ÇàÍŽŸ¿OD$‡ãž¶83^íaéFÀ à,¤œEe%jšJÕwº@—7 èN&‘>´³ûœšÉõñálnçÔýV<ºóÐþ\Å4uFÕ Ýû{Ò ©NÐ*)ÍjÄ«¸#n¡ìºmfÙXóÊ»+| N=~nÐ?rÍœ[¶lél¨Q,“4›gDÀ=A EQ(¡œ )`š¬Œ§rê“5 H$)‹±XÌ0Œ „aƒ vÚ ¾«µµÕ÷}Çqâñ8Bä@5M³mµ°¸¥5MÃï}GG‡®ëè‹ÍCƃ`:ÆM‚`ª\.§R)Û¶kkk5{x_TÜV*¼{<G¹Ý”)SfÍš588hF>Ÿ¯««ó<Ï÷}Lb±>…aè•çû~SSÓœ9sàˆg7V8&`ÉÄè$T!#Û‹F®ë¢¢ ¶¶–sŽ/ǶmMÓEA[mˆÅb¨àO§Ó–e!ÕÔÔô¿àŸÿÅ ‡2Ñ 6ŽÂ)Š™€ ™ ²`q¹UÃÔ¡%5릫f]óUûÎõ~¼ó³Ïó½ƒÔñ̨!KÅc'2ç ¸@ª‚ÊñÊ®&É„A¨ ’$)2ÈrUÂ*\›UóÐ;dÉ¥Ê (•¹$¸ !a\–… U?0‘D¦&’Œê‘¨5ã‰T4bú/žˆ¦2µV" ’ x\NFB ¨. €JD¡@%AŒCKÈ‘É8"á T aÂSŽsD™¶šÌ„4ˆù“DÇY]ŸÃàT™]v'|hxØ ƒjµZ²Ë¥rÙqŸ…$ ^ÿ˜D dB‰RJÈ`;UJA•d‰Â9cŒ‡Œ,©™‚‰P‚Q²D¨¬b{®jh”R2•C5¸ôî;Ni›;ÿ ÓO: Š•ŸÿÝ ~DuUNDæ_rvm{‹bÙ¡áBÏ@ƒ?ôÙ¶½üνõνófð…í–’±¸íy¬R!ŠfïÜ÷î˯ö÷&euN]‹ï9…\) ,»e§ö•KÁ ßüý+}¶]ñÅóO=ÓÞ¸þÏËþRÛÚÞé'Ì·ôíÜ´}õ¾yÑ7o0ëÓŒª€…~àû@¨LeÓ¢I(;²tkg}$qhÍÚx2‘ž;ëôsÎzþùçsï.½ôòˤÆzðܳ.<ïÕ7ÿ0gΜÏþ"Æš?ÿeßž=¾ï[Í@¸!«Ý{ö½»déõ_½2Ý1åÐöÝÜ [ñìäË¥ù Né\p2u‡GõT²24<0<|ùUWëʪÂ(€ ’¦‡®'kZè¸Â+R*çKm-`‰xtöqç|úé†ý»vL™: ‰ÙsŽß²}ûiñ„™H<Ü›š:å gŸõÁ+¹¼N%ÐrW×¾}ûF†Ž›9“PÑu`ˆÁAQÁª•Š™ÔdY‚ë–rcŠ¢ªR,äz{ª¥b]Mm©Tš3ïPÕÀwMKÂ=ÏÉær D¡\.•+õu5 Í`Zù¡îB±ÔTU5ËŒ‚ Z"E$š/ÚAÕUŽ eÂ.Íñ髊ª¾¢\.£pŽÈ29RБe9ä k±X¥bŒ¡ð˜iÅGÃìäØ)~lýmöÑ¿®^½zÛ¶m†aÌž=»±±_ÏóÎ<óÌ={öÄÐÏ ÃåË—£îãÔSOÅ6!,nN:µ§§GÓ´]»vqΣÑèÖ­[…ÉdrΜ9’$ù¾Ç‘KG4›ÍbGÍ©§žÊ9ýõ×qÞÆ 7Ü€8„ß÷§M›A.—Ëd2(l;pà"“3fLBˆ®®.¤2¦M›&„8xð úçŸ~<Çdàðáöm§R)¼K.—ËçóŽãÀI'ŽeGÊÉ|ßÇ”Y5!ÄÌ™3±~ŠóHp@È÷¾÷=ìÖþ—ù— ²Ùl.—#„ÔÔÔ0Æ5a5‹a·B†Œ±öööL&3::ZSS³nÝ:ìFnmm-—Ë‘HÄ0ŒÚÚÚ±±±Ç¼¯¯ïî»ïv]wÚ´i;wîDcµZíëëCÖnúôéa¾öÚk½½½Ñhô²Ë.;í´Ó±0ÆN=õT̑֬YƒŸk¶mŸqÆ~øáóÏ?ß}÷™¦¹sçN”ÒÍœ9s‚ð™ ï¾ûî_ÿúט8­^½3ŸŽŽtÕÒ4 ¥éÇ6Úß'":ªîöß–'˜+\Ésã锤×Jš\eP¨6ÒH¯]nikšÎÉ5õ «ÿG'ëpÆRº–.Dœ±è쟽ø23õ§Þ~ó[W]ùêÒ·Ö¾ñæ[<és9™¬ YH ÇÅ IDAT£Š¥{x¸P.5MjŒ7Õ‡G[ukèóíÍ —r¶ÆdáƒV #TQ‘ÁÁçÔñz¡_uhʆ2 ˆ^p³~q1Ìáÿ`º_©T‰DµZE™’¼aâ#‘ˆçy–eaЬT*èG7+|ßG<ª«Õ*V\p/a,€#ÆÖØM8чçº.b°‰Ù¦–eá˜T¤˜\×mhhð®®ᜦiðqò}ŸRŠ÷œ7_©T$I¡ ‰>#rVX.š˜ª4ñhrØ ¨†QÒ÷ýÚÚÚ\.§ªj$©V«ˆŽP?Í9Ÿò'‰\.Çÿ@:š2šhbùksš@£, ‘¯ðx¨* •4&‘Rà†®H¸¤ž8÷ŒysÏp\ÙwàÀæíƒûl[¿ÁÔ¤T¥TÖAM“E–ýjU¡œ™‹0ôYúBžŒ%BΡé„/œ¹@€$ûù‚³´¨•*¿õÊï_{µ¦™+Þ^zù¥‹ÓÓ¦mß90ƒÑ±ÏÖoeù¼³Ï¥ µ‡Ö¯?*ƒëB( …âH.7ÕŒ‚¤€àŸ¬þ€³`JG§Q[×ÚÞQÌå‡+eÛÔt;—‹Lš†!tƒ H¥R"–LEr…²]…¡ÁÒ†!¥òزªÆãq˜[(‰ªV(ŒÀ7MS‘ÏçqÆ¥”».²CúÆÍB¯Vqt¦iTQàÈ„ñiÑ&„+…Ž!¢cëè…e;ÔPà¨ñçž{3[o½U$xJV*$I&øÿøÇaF£Ñ믿>û¾ÇÖäÉ“ñ[744„'éúõë‘kÂÙƒëì³Ï^¹re¥Rù裪Z¸páèèèŠ+0¿æškðÚ ±±/,NŒYG“ÎùôéÓ'J œó}ûöáIÚÙÙéyöBp HSSÓÇ|Ûm·a¥õßþíßЇ`íÚµ¨ »à‚ °HŠîDŒ ©zSɲÜÑуCöîÝ‹Gù²e˰Qêꫯnhh „ôööJ’dšæu×]wÝu×ag _×õ7"Rjoo€ššš+VÜÿýˆÁn½õVEQ2}ó›ßüá¸yóæÁÁÁxàÉ'Ÿ¼ñÆ'ú“5MCJY>ÎùÇŒ5eÑiGV¨ÇÆÆðÚ‚ زe f8·ÜrËÖ­[Þ{ï½Å‹#Ø3MsÒ¤Iè61ÑÄ9Ç{xx¸¦¦æë_ÿz†œók¯½þ{›ôÑC ­¿D$俎1ñ…˜D2ˆ%+ Å2r¾dE«U‰qMµ[j£Ÿºå7—üåÍwßñ‡óùWW&%Å(ù,çϘòÌcO\ôõkwåGnûü–ûïV<Úš ÚœnNòÈpžÉªO‚æÎÖn·TäΗ¯¼è…ûiG}7&–dY3 ÍЛÛZ%Y–eYÑT+Çã²,{œë™T¬¦&ɪB#¨­ÓÀ@¢@q +‡=zñ)èô è`"8ø^…R*%U-ÝÔ<¥¹p†)@± ~Èßc¡©ªkŠa€¢ˆj•Dã %8ÄàùpàÐ~ÿá}{vgýÊŒ…'}í‘»[ž Ï%2S›ê!ˆÆgÏž½Ûg­í|×À¦Ëþãå+ÿõ~ÈDa¸ÉX¾ëðGï,ص¿A5uJ['O®I¦l»”LŇG‡ÂáBá£OlÞrÉ9çžúÅ/=ÿí;vnÚ2ã¤yÿø“ïC:•;ØSÜz@3|»w l\¡!€)Š Tà8 ›ƒ?ëÙwàÀ®=;>ߪJò%]<ÿʯB]œ2HP7¥ˆ ñ„(’ï8”…ÔÒO>cá)gžz>ó|ɧK—¦T£eÖììîÝï¬\þåË/E€)Ûù Ï;¿£½ýÕß¿ÒÿÓŸ}å+_ ¢zãäöxcCvp c6zžW)–Ré40èÙÐPµ¨nú¶«Kš"Óî®®éqS‹,šˆê–ÙÛwXjmŸ4ýäSZ§MU5MŽZår)’LrÁRźõÓÏhÈO¿øBÐÔî?Úúùç'œ<óêdE‰D“U?(9ÕŽI²%UjÒ»T(K5Ù1’JuLj'á_éèˆç©ªŠR·L&S°+‰)„ÖÖ»] ¥T"L¤eIíêê²bQBH¶PÃЈF8ç¶“¯×T4çäœG"‘T*¥G"À˜ªª’$U]GÓ4I–y`n:Ñæ CÔ÷ã# È:¦Z9¶þv!¿'):«W¯N$årù¸ãŽC>ä½÷Þ»øâ‹}ßÇ.šb±†!¢ Û¿øE<+•Šã8ƒƒƒ˜Q è#›Íöõõ%“IÈU*•L&S.—=Ï{ä‘GJ¥V'ѾÌ󼆆†åË—£v«­­MÓ´l6ûÉ'Ÿ\rÉ%Nb±Xccã'Ÿ|‰Dpð†$Ixtâ‰|ðàAˆÇãmmm•J¥¿¿ š§vš®ëè,…÷•W^yÏ=÷`Ê~èÐ!”· ´÷–P]×Å­DA8„ I}}½eY¶m÷÷÷#3ó³Ÿý ÿz×]wa4ؼyóDú5Y\ô‘ŠD"¶mŸsÎ9xy555£££pÑEÝ|ó͘zµ¶¶>ðÀÝÝÝ«V­°,ëî»ï~á…Þ~ûíh4Šê˜mÛ¶!4:þøã}ßGæGQ”+®¸I$Ó4c¶ma¯޶߷oÚ^xá…×_ý¿ÿû¿ÿö·¿=å”S†‡‡ ™LÖÔÔ ü Ft’¨««[¸p!öÌ›7磌®Â êXûÐß9"bGú¾ÿ:‘`Œ«¥!‡tÆ2¢Ñ¨¥”mÉ R¦Åñö5OJí_÷é~÷­ÞÊgxg~ÛTAb›öNûÂÉË?Yß4wÖã?}òׯ¿€L+š”÷í‘RÀ(¥“ÅÐY{`ïñoþá­SÚs¹BT!óª_—ˆQMu\O’•t*@=ÏWTÙP5¼´@ð€0 $Âó\K‹æÆÆÒé4ª/PŠÇ­ëºØñ‚#‚ Gâœg³Y p²,#™ƒ{B9Šç7jÛ"‘ˆã8ª‰Çã¶’†aà‘Oȹ‹EMÓt]·m[Q|„U‡°mÅxèôº8ìÂÎã‰6bì¡®¨î«T*ñx|¢ 6;Öu]¤¿°ÚŠÅ0UU'àÆAüŸã¾™ø®â ’Éd©TÒuƒH,+•JxÆü-‰ã<à4 …\¨ŠB5E–eÁx†„ Y‘´z÷`‚ºœœÊ²jªfe´B)•¨L$ƒRʘ`%Æ åòØ~&xaè+šŠßá¢ï 42 Jä\10‰˜‚HåJ©®¡Q‰T&•IÆ©X<¢›b¨‰Î-5’ °L¤qI¢*ÖÚ9ÁÇ AÅ-@˜äÝÄ) ‘Ëà‡O€€ÒçŸÿù­?m^»žVœ .¼ð¬+.‘fOƒØ¡ãq1-ø*¥P.fÍ_°àÝwWP]?ï¢ó{÷uíÞ¸AØO’³A’ WXóÖŸ‡öì¿õÆÿãgO±Šsóý÷@µú§ÿü/U׌Ht¬w`ÃûLÜ8µ¦éßï}plhäô ÎûÊ·€n Þtã»ý¸Ô7ªXF=‘Ý÷W韫 ¥\>[u<§jèíéÝÛÕ\Wkuû®­wÝõí Ÿ¬ëêíš3¡X‚ÐýÍ/9{ÞܜϪI•ˆæûUÏM$’ (•#™8qÜ´íÛ¶}ð_¯‹åÙ³f  mß¶¥.S×9¹}çΊL¯ùÎ?øú«?ÿ鑚Ôe7ß ÅbA©œ©oð‹e-Õ¼°Z.¿¿b9óü™S§/8iÁù×\•êï,«kkL%Z@PE3&µ·oذAUUŸˆŽNY‹ZD¢vÕŽÄc @ªY&Œ•8d*3²wïö-ŸðšL¦¿û°ãºV,Z›ª1 M“dYÓ@0ðð<;Wéð«ÎqsæX‘h*™¤”vwwŽŒ  MŸ>}i3íí?X=™‡¥‘Ñý{÷P ¦®ùnÕw=ÆØäÎöb±XvªÀ‰‹È2%²"qÙ­:2•Pll†‰¥¡ëª¦ TU•)—Ë©âñø‘.P7ÆUι"I‚ñ~HJ0Ê«Ñ[ÿcaÕ5–a†Q(ð jllD§ÙGyÄ÷ýºº:ÌŒðƒ Nصkž}±X ‡UD£ÑjµÚÓÓ3!´Ãc’ÏççλqãFBö¢`z€ÞÍØÀcYêÒ‹Å"Ê@:::ŠÅb&“A/\×u±!çúë¯O$ÃÃÃpÄknüK’4::*IR*•Êd2Ø™Œ‡,2·årÙ4Íþð‡çž{îÌ™3ñzvïÞ]SS“Ëå8ç¨ÀGFÅ÷}Lu˜âœcÉi]בd³mÛ÷ý>ø`ãÆ±Xì’K.©¯¯÷<¯«« {‡8€˜ ",þ–J%4–ð}{E‰Åb£££?úѾño$“IMÓ…†ašæ/~ñ‹O>ùäW¿úÕ’%K`ÇŽ·ÜrË’%KÊå2ºØAÐÜÜŒ ÿµk×¢G–eDzذaÃBH,K¥R±X¬««ËqƘiš‰DâŽ;îøÕ¯~µlÙ²åË—ã§F1ÿ™È^ƧÿÅbŽã|ík_Û¸q#‚ºçŸ~úôé˜ ¢öMÛn‡ˆHæ Œ‹¸‚…a ”îûÄИD™ívF§µ§b(Æ¡l¿"'n9áÌ5}‡–üëÏú?Ü~ãñ—¼ýËŠ”%ZWÛ¸©ë`{mË“Oþâù?uå×{%qhtð¤Ùµ…±xÔõªïîÚzå·n¿ôû` û»wÞI €2•s©PÊI©×p?Í-j¨ÃÀqž„P €‚bi H$Žòû0ˆà†Ä3uK(ŠR(‰Dmm­çy¨PÇüËØš9A¹`Kºõ#b™`Þ1üaçO2™œ„å%üOTñ"ˆú«mŠF"‘H†h™L&®LÄt×u‘ÀA#ìx<GºEÃ0œéM\* ùLÓDt„8mbßâŸðÕaœF£Q|Ò£Ã%¾‡Åb]¿-Ëš¸`4û¶m;‹aÄ—Œ#°#K–eDz™òù|, þ`õÙ—¥oÛ–=»vÏš:ÝªÉ vÊD·ÌXkëpW7ábzÛ¤žžžAÓL&“:¥©Žö½;w445…a¨65LbÁèXöÐö-™L xPÎPæñ%¢5=ûv×ÕÕéškkrw\ÊË Ó#J¦¾@I)ç²Y"I¥B¾¶¹ Â@Æñ a(|§O%*½½~Ä’1!°ù¾ \躎5`Y–… ^à³+šJ$Ê?jï±ulÁ„nâG\„5Äd2†áš5k!O>ùä<@Y´h!UdxÀa€\‡$I¿úÕ¯c‘Häâ‹/€5kÖ DÕï8ÉP’$¬™*вjÕ*Ä9'œpÂ$<q;ÖRß~ûmÃ0^|ñÅo¼Q–eôpúôÓO19÷Üsñ$ÅnŸ—^zÉ÷ý¦¦¦“O>™Ìg.\¸téÒ|>¿pá¾¾¾§Ÿ~úßøæBŒ±íÛ·£oõÙgŸÅMl.ÀóÛð(ÇŽƒ‰ é¢E‹^zé%I’¶oß~ß}÷µ··wuuýó?ÿ3¾'{öì©V«Éd&T9Š¢Ø¶MÔ±XìÃ?D=Ëgœ±lÙ²‘‘‘Ë.»lllìÅ_¼óÎ;UUE0†É ¶]xá…óæÍ[²dÉ£>ÚÝݽiÓ&ü4wî܉ï Òk˜wáaN‚ H’¤'Ÿ|³;Ôæõôô`JÖÙÙÉ9oll\¼xñÿøÇýèGxv/Z´Ó*”ü!îÂv‰«®ºjÍš5øëºuë°[;‹¡"y§cˆèïÁ+ Û°á]"øµÓ:äLB 8‘UÐB7vnÚ,@D3‰Ó¿p"D" ¼öɇ+Þ[ýO÷ßýÑ3Oÿ¼£! ÅC÷ÿkTÕ-5öáÊ5 H¼XKrÈv>Þ·ëÞ>öÐÓÏ<ûÖ›r!ê´©óN;Óé¶=?žJèš×[Ì: ³T…Ö© ˆà8{óˆÄj¼ ‚&DxÈÛpαʈ¾÷q· nÂ¥:æóyÃ0P†Ø½YdYÆÿÁ:88‹Å0LL V Qè÷‚ R@¨µCaŠÖpËá}‹Å"¢!r»x{ŒJ ¬€ …d2©( +ÈçóU,!Eƒw$Éår‰DbBõ7ñVŒŒŒÔÖÖb‰a’KØý‹Å‰BpˆܶmJ©iš(§ÆÐƒäJé&®u}ƒžPŽ8Ñ섯½5}ß74Ý÷|œ‚3-*„¡ÈZ2î{ž®iˆ!àðáà å²L$CTÓ€0VÓÜR<éÜs@¸~÷ŽœÐ%ï./ T€]*â\²L}çyD@sss,U%YÑ4¨É€]!í“"œG4 ªNK±uõ8[‚„"tdG¸Þ¸²o|t©7>x8A@0€ pÁ€%Â)à´ô°Æå»®[ulÛöõ–¡/ÙÛ•ÐtJi±XìïïÏå³ Õ„œ !„L B0 TIx“¹GyÈX@J(f¨šïV5 1ÓbÏîW$µ!¡ª†²SõÊU[*øÕþlE’])UªBª¨D¡~èq ’¦¼ª‹ÆÓ™D"¡+*a\8>õ¸ÆÉÖM[²¹±šIÍZ&ÑÞ9iÁù_šwýÕ¡ç2SW(Ή  ¥¨ã9–¦S]…Qê›[önÚºë³Msg·cóúÃöCÔ*­[·eíº//:ŸìÅ—^"–±øÖ›ÀR RwëðÞ›oOÕ|¾fÕØP×Îц¶Ö[î½&·®%LRÊ!‹&b`g_¾xå[©äÄ3kgÏ0ëkdKW1H' ™JsÈÀÒ¶¬ùpñù€.íÜ»«ã¸)ÕW>ñ‹iõ-—Üõ_=üäù02úí{ïQ,ãk×\sR" œ”‹Åh¦È@ÀØ@Ozúäs;&AÕÍ„ál}"yÎÂ3W½·ÒQµr6;¶¿K,Vìæ†úÓ¿tÈ /hþøc¬ž8q"j£-[¶lΜ9‡ºÿþûŸzê)¼õg³YìÞôéÓ‘çì}Ü¥ ‰Æãñ+¯ŠªÜÓ§Oå•W\×}ê©§º»»Qp?c@ JÃe2™bj‡1“ɬ_¿÷EMMM>Ÿ¯¶¶öX´hÑ~ö³Ÿ=ýôÓƆžÏçï¾ûîŸÿüç–eÅb1ö_ýêW–eá~à‹/¾Àðbss3²r-ZôöÛo{<ž?ÿùÏ?ùÉOpÿ³cÇŽÍ›7G"‘p8|þùçK’ÔÒÒ"Ër8;v,êà-]ºô7Þ8tè†Wȃ»ÄNXvÖYg;v,›Í–••­\¹²¹¡w^ç IDAT¹¹Xåuªý!¢“'àñx8FeîĦ¦äþƒ^Îû\#¥q-&¤.lmÛ·ÿ®»?yÁ÷¯üþíwŽn}ïÿ^2¢¢KÏBo|è—šK€1#™™=cÖ`¢](T© OßøÇå/–”UÊ®3²~TÔuöÔlàÑ€£ª–aêGöû}F(\^a'œ `}.–„sN8.víÚ588XYYÙÙÙY__?vìX8á—Š¤O f 8Á9fÛ6î¼1U‚zGˆŽq‹`‰s^UU…D[\5 ðmÛï÷#—Õð†ˆW:\&нý§‘1‚™L7áb„‹ºú`<‘H`ò ˱ŸX…^I™L&“ÉàdFãm˲pºF£Qä4çr¹ÖÖÖ®®®éÓ§µ\¼^/¢7 ÆŠT7UU1fƒuDhY€|bLOc¾ V(¡Â)E4A ‡ÃçÂáp>Ÿß°aƒÇãQUuüøñø®­¸î½´±Hɲ¬ššÓ4#‘Ho_(P|š©ëŒPGÏ«*D¡àZ6wÜaÓ›† ˜âr0ÌþövÁùÁ½{¥Ü¾–VBˆLÙª:¦åQT¯×›ÍdlÛ?¶QÏ彪GUÕ‚p|e1P$‰2F¢H²Ï£©ø|ß·!‡VTÀÔFÂ` S` ®à@„á (H®”ûnæó˜Ô"’êÑíB*‘͹f8q\W˜Ü¥8œp›1Y±D•'Jò„çsüx6ï¸àr&€2X(Œ©ž­©í¶rñ± ß[reÉÌ©@‰äñew]—J(Y–m×U8"1Ƶ}³÷È‘#^»¤ñ³µ_nhiùÃÓÇ{º†UÔŸÜôÆòå,üñ]wÀˆ} Çã(õÖýTõ’ÄO¬žEÑ ¢ <~àŽÛt)óªÜ2€09T¯ˆ”ˆö^¿7_¸ôl~ßþ¿-ußί™ÍƒŠ'Ö4µ²ºZìí}Qp娑ã]u%¾¿íà ×ü|AS7•@âe÷þìî?<õDY$®()—ï߸Ñ4Œ‰ÍÓcu5ÜÔ©âÛþ¿¼ø"¬zÿƒ™MÓªf6_»îƒ•oT×Öø‚Ç4»wìöÕVîØ··¡¡! nܸ) ¶¶µ Ÿ:•Hªzp÷SÁÐÖíÛç¨OgÒ½‰þh¼´~äHPdÉçQc 0Y¢2c…‚Žâ¹-[·BŽ;6¡$& zÿáî¾Ä@wWG4‰„ë:´ut´O6Ų,÷.˲ÞvÐŽõöõY–•Ïç4Ÿ·µm]]ÝѶý©LÆÁd)‘Nš¦©F6Ÿ/óy-=çˆ!; YUB¡PWW—¤(‚*1¬VUUíh—cN6‹š–EË4JA‘óƒƒù‚ΓµsyGp-p,ƒ ñeЬpasÎÓ”N8P3ƈ늜$­yŠÙªaÃX$Þã|>ß7ÞxÝu×À‹/¾XYY9räÈC‡­^½ÁÏÒ¥K1WSSsÁ|øá‡²,?ûì³Ó¦M›2eÊêÕ«ñ½–eíØ±…Û·oG;¾±cÇbeº¢bS(Êf³Œ±L&ÇEÑuýÜsÏÝ´i“ã8Ï?ÿüðáÃZ¶mÛ¶cÇŽl6{Í5× ÊëÂ… /^ìñx¾þúë•+W^uÕU|á…vïÞÍ9Ÿ2eÊäÉ“5MkkkCTV__¯iZ&“™={ö„ vïÞýꫯÞxã#GŽTUuíÚµ…BRWW‡¢P¯Ä0e¡PÀ°¬¦ih´Š¨¸qZ½õÖ[Œ1MÓ{ì±ÞÞ^MÓ|>ß¾}ûòù¼×ëÅbÈC4ˆL$ÈÙ¶Ç3™Lii)–ÌŸ?ÿ¬³ÎZ³fÍK/½tíµ×666ʲ\SS³mÛ¶ßüæ7„{ï½~÷»ßýîw¿“$颋.ÂÍÏÀÀF“±[×õiÓ¦½ñÆŒ±Gydâĉ&LøòË/¿ÿýïWTTtvvþíoC"ÌÞ½{)¥ýýý“&MÂòïyóæM:uûöíX:>qâDäÝX–…‰r÷ÝwwvvbÉ÷=÷ÜsöÙgã6æ;‹Ì©Õæ/"*¢ nî@8–„dÆ™g.ÿûšX¨”r—ÈRoŸp©c:óÆNÔÊ*v=þú²åyÇN¸þgwØ^¯–HDCev.ëæô5Ÿ~¢%»F×–HuÝ~ÛÍ¿{âCÓöíkeF¶zÜdǶbB.+K%5œÏ ª±°î8cÇO®ëJ (=až|¨"Ÿ0.|ë­·–,Y¢iÚ† ®¹æ\Î0F‚U•X?W__ßßßÿå—_RJÇu{¸¡GÂnQldõêÕ8“Ï=÷\JéÁƒÛÛÛC¡POOO4EŽouuu&“aŒ!ªAfy½Þõë×»®:::.¾øb×uÛÛÛKJJp bŒ}ðÁh€ÐÓÓÓÞÞ.Ë2Rì¢Ñh @èÒ×ׇ©Ó4÷íÛçõz'OžŒŠØ{öì9xð`mmmkkk}}}4•eypp°¼¼Ü0ŒÇ|„ ñx|Íš5£F’$IQô1øì³Ï"‘ÈäÉ“³Ù,zÔ.\¸p```çΈKJJ(¥Éd2 aóÁƒ«ªªvww£>OqmÅ„Jðíß¿¿µµõŒ3Î@ ‰btÑhtîܹçœsÎwÞùûßÿþá‡nllt§¥¥¥¯¯oΜ9(²‰fy–e3mªËËË;º:¿J$ÊÊÊ&L˜D–€(ÒÎ;b‘h9Ó0"eåà÷”Œ†á8–ÑÙ__U[Ý8çã×^s]·²¬\ÏåÛ>pà@uEå¢áH&™Ô‚~ûøQB)Ø–eš&¸3„®ëº ÀО^b”RW¢6[¸œ Á˜¤(²¢¨LfÁ`aTb2“e…ÊL¦!0bD=cT–I•%E™“†ü¿M‚sàB€kQƒ*EuyÃÜ!¼>%Ü ä%ˇV„ÂÀ x¼CšÝÀ´`0©t!™Ö4¯™Ê;zÔ)˜Ÿ/No;°‰/ôtu'’ƒÌuA"´$èõxtËÂvIR$£œšîrJ9#‚QÂ(SdÊäœDŽ;TÕ8rÉÍ?­X8¼ \Ç%ÏPJÍÅúw.”JŽc9@dÛ€cFù"¡žÁDa[KEIÅ„gÇÆ­ÃÆŒ9mÖ¬¯·nÙôõ®²úa£çŸ –á­ªFrzÞöÙ¶©”ˆ—€¤¦¥:;Ã%åÄë‘ØÅ“ìíh~°íæÓÏølÅkŸ­ûbVEüýµŸuïÐd¥iìøª’²#{÷'Éÿ{Y8¥^õ“¿}Rrø WõÆ#q0ä`V1,{``tÊÆOð0¹º¤ÌMeY˜$¯YùêÖM›=L=~øÐEK®Hô~ݲãО}KpíÈÚa{w|ÅíhÙ^uÖ9µçgú‰ëºõ Û·oïÛºIhj,«7îꫯ–¢Ñÿzì±ôñã¡ÚÚÙgÎimmm=jòô©ëׯ .ˆ†Qc†×——\2éE€i™ªªÊ’lÙ–*+2“˜ ”²šªê²`¨§£3›”U ¶î;|äH@óιòÊîm[Þ_ˑ؞û«««ó]õø*{=[Z¶566&2©ºæ™;vŒŸ8!‹€iÛ#G:xð`ƒžW~ÒG-Ç.˜,EjªúTbšÏÇ’2g„…ÃÐÕá8X(Ôî§~²³M*•’r¹@(888¨iZ,眣ãV˜sJ w\™JàX¶mÛ®Í]Á½œ+ª ŠJ“eÙN)%Œ}GÖåÔN埼!B ‚KW\qÅÛo¿½iÓ¦¿üå/ùË_ŠTsÇqÆ7wî\¨©©€ë®»nݺu+W®Ü»wïôéÓ‘{†|­×^{­´´C‡_ý5®œyæ™È9Çx«¢(©T* µ´´à{Ï8ã d©Ü|óÍ›6múè£Þ{ï½/¿üë—P™M–åx@’$¼>ÿüówÜqGOOÏõ×_¿xñbÜ]˜¦Y__¿qãF¬à- Xß‚ztHý¸ë®»n½õÖB¡°|ùòx€sŽ™1BÈwÜñãÿ¸¸•Gšrü0‹n„·UUµªªªX'£ëzmmí¨Q£ðÎyGG¼ÿüÏÿ|ì±Ç ÃÀ1F+°Dgýúõpî¹çâ Ù¶½dÉ’5kÖ¸®»qãÆ3fX–õûßÿþì³Ï¶,ëᇾï¾û0Ɇ±QÌtÀªU«† vôèÑÉ“'c¤ûî»ïnkk[±bEWW×Â… ‹µÍk×®8q"b˜ƒb¯.¼ðBÌ•!Þ³gañxõÍÝ!¨K$ï¼óR …Â}÷Ýwçwjš¦ëú©ÈË?SŽè¤&N¨"ÛÜÊlà*e§Í™ýûBjý~W€¡“„Q];ÌÖHÖpzŽôu[DT×Ã.Z|éòU¯¿ûÞ7\½äò .zôßþ=äóÏ=g~ÕˆZ­C ù²úú]í}ܽåö;7²ÞéèÒ»;ôlv„ê§ù,fÚ)Ø|šwß‘¶ÅK®æ‚  @¦èì‰Dœe„2„Ê;žvÚi^¯·©©iþüùS¦LÙ³gO,#„üùÏþå/yèС#F!ªªª–.]zÿý÷ÿêW¿ºì²Ë¦L™RQQ±bÅŠt:}ýõ×clÉçó½ôÒKK—.mooÿôÓOï¹çžîîîd2¹gÏž½{÷^rÉ%ù|ã.?úÑÞ|óM\òEyúé§Ç)x]×W¬XqÛm·mÛ¶íâ‹/Ö4íç?ÿùƒ>X]]Z´¶m·¶¶úý~Tƒ¹ÿþû{ì±|>äÈ‘1cÆ À¢ÌgŸ}6 Ž9òøñ㯼òÊUW]5mÚ´áÇßu×]¿øÅ/$IÚ¹sçE]D)-//ÇlRkkë}÷݇šN§;vÉ%—œþùO>ù¤a6lX¼x±ëºÏ>ûì-·ÜFQ€®··÷•W^ùå/©(ʃ>8mÚ´²²²/¾øböìÙ%%%Bˆp8ŒòŒ±‹/¾XUÕU«VÕÕÕù|¾d2¹mÛ¶ B¾øâ‹>øàÒK/5MsÙ²eG}üñÇ Ã7aü¢ïÿ½÷ÞïM „Ãaüã÷ÞÙ°aÃUWþË7‡Úžxî™ /¼p^u˜¹ü¯îû՜ӛGTTçlëêEç}þùçc/8séÒ¥ûèc©´´ÐÞ¾|éßîþÍV6wðàAà¼1í;Þéö§e‹cÖÎTLD‚êQ\4î€Ài";‚fMME%”¹Œº„A²#Eˆ „0A#Tì]½™HÀ¨Leª(Y•˜¬R‰xýMS5_@Ve²¤J^¯_ö©$¨å P.(ç’KJ%Y‰Ç‹¨i(›Ä $€pl(¹d@xUÛ¼qãÆo÷tw9tØÖ·²Ë¾Õb«; {úz_{øáHY‰ë×22 Õ×5-]b¾ûNM,ZV^±sçÎ “ó’Ï„4Žw¬ýøÄÊŠºÆÆöŽŽÕ«WË5™ÍØÙt¤4­ÎM$ªWÜuQñIÓ4"(²b¥lÜÄIN*ÕÛÙµ¯µmzeÕ˜q†Y8vððM5UvA¨Oÿñc–c«oèïî’ñ“§×ïÚ¹sß¶ÖUÍ“}ÛÞ]J8°}ÕÎË¿wî§»[n{àwÓç_¾ì/¯}¸vÍ GŽsC\>ºqÄž®N<ÚWÈ÷çõÓÎ8ƒz}Œ0Ó²½²üj9ñ?F$EQ¼^o*•bŒ•””Ü{ォV­ºþúë}>Ÿ$IóçÏ/zù)Šâ8ιçž;vìØ›nºéƒ>€ŽŽŽ?þø¦›n€,ËÝÝÝ^xa"‘8ÿüóyä‘Ù³gcv¥««kÞ¼yHxs]÷í·ß^·n]SS&ˆ^ýu¿ßÆg á­ªªjúôéõõõ¸ÜTWWï{ß[¶lÙ¬Y³°Ÿ¨îpÉ%—är¹ÊÊJ×Ç¢#\ûúúZZZ§M›VRR¢ëúܹs¯¹æš÷Þ{OQI’Î9çœt:á,BAÌÖÖÖW^yå?ø^ÑÍ7ß|ÓM7]~ùåÁ`°¬¬¬©©éž{îinn^¸paWW—®ë\p–ýBæÌ™C)íêê’e¹¼¼|Μ9(¥€«ê§Ÿ~êõz1Á­(ÊË/¿|àÀdQ¯\¹òÞ{ïEþnIIɱcÇêêêв ™ Š¢$‰ `µhUUbe2™_|qÙ²eHblnn~î¹ç^{íµ¹sçÆâñcíÇuÛˆÅâ–cÙŽ½e{Ë£=F …é0cö¬n¸¡¬¦jd}ýÏïýŃ>D pÛ1—ÿí]ZVùÕSýæ¹'o½õÖ϶~ñû/@yX)76T€«ëåÓ&ƒàp>”uCŽ'`@¸à8À×u\„Ì 8€ Àb¸ UQ.>W |%@)cŒ0š+è`ÚV6›Íd³ŽîHº.ç=ŠáëîëîïîsMÃˉC6™Ê jªG8îkˆ ‡s¨$IAKÎdU @@VÎy<WU•y<`Ø@)0² Ù•…ØP@¦@ ä ×–a1`;ÀáÛJªlRyc×¾¾ö®=Gèñù”±cF›Þ4ld= A’†t½=*Hl(©Lج:¥” Yó³×Å % ÓgÍî(/Û¼jU]}·²|ïÞ½yç]ñ‰Z9aìõ×]iëäs’?¼ªP<šÏjQ"e’ÄÐÙJV<Œ·¬P0@Ø“Æ.øÉŽ8䋯êF5qcAâ@8H\§Œ‚6¦öüŸþèÂ8ÐÕ•Hù†ªØûêí÷V¾õîÏ~ù3LÔås…Ñ£Gƒ$L·¬]G\^súÐÑiäòÍsçn5¿d–{Ée—¿ýו-_|qÆ•W‚žŸX] ]+–½X9¬vì¤ þHˆ÷õ”TTZœ—×Õõ¯^ >/Xd3ÍÍÍ/¾ôÒÄéÓ¹iœqÁ÷¶¬]›ÓõæÙgÈÁP €‚Ìp½¸ë ”MÓ,Ã<|øpEYY(•™Ê¨š&ƒã¦LnÙ´9ßÝë ú'Ÿ3·®®nïîoü>ÍpÜòšÃÐ3º^=¬ÎâÜr«¿O©ª©ÕÀŸoÞ¼yE¡I’NŽkooøá‡ûÛß®^½E*¯¾úêîîn”¡¤”"†ÁI…Jö«V­ºâŠ+–/_ÞÔÔdšfgggSSžñÀ”RôªÜÑhtÓ¦M7Üp.ÊXÔØØxøðᆆ†Œ—躎;`]×q]»víÌ™3·oßþøã#%`éÒ¥O>ùd<¿í¶Û ø뮻Æ÷øã/^¼K(çóùPø®²²ûŒfظg2™Y³f­ZµêŽ;îÀË”eyïÞ½^¯7‘H,\¸ðôÓOÿì³Ï¦M›ÖÛÛ[WW‡ƒ†;$×ußxãwß}÷¢‹.Â/%“ÉX–%„èìì ÌCìzÝu×ýô§?½òÊ+@(ôÊÝÐ%IzçwFŽIÍê9¿×‹Å/¹tÑίv7¾³·Ç dmC••¼p+êFèà õ“&üõÝw¾:|°7—-©­kïéª,¯LgÓ¡@~Û²d(öíŒOÑC– Ά¼!„ .¦ŒÜ!A€pU ýÖQF€€†¤@€1D\½VãQÈë “Æ‘ÁuÀ0Áá z€0Œ¡;¹QÈäsÉLZ7 æ ÌZÙüàÀ`&™âŽ«ÊŠÌqx6“‰ÃEum[••ÒxI0Ô%™4’Dý~¿Ÿƒ Ë@@˜&Q0 ‚8¶M„K$"æaQ¯§2R++µŒqj…p-Óqð€ `šÀ˜°lƒÉ²¤È'„(NZbu\*1PpmH@iÍô¦šúºÑ§MˆÆb`¸É‡Žuvyâá§MVÊã®íH>Ÿ9RýÅæܘê·AxÁ›Í§‡H b™.Si@U²¦­¨²E„ I NBJàÜYãæÎ‚¼A?p×$¶É(•e¡x88¸$¤ù˜¦yh|ܘL!ô³èÌÉ•cßûdõU?¼®äôfèéÞùÕŽ ›7QJ!‘€X |¾žžž3¦C>ó·wßò4:bØÌhèÝ7Þ„†—ÞöÓ?1üàØäÉŸ=÷\Á4ª«jÏú—+×¼õÆÈQ£è¤Êä—-áòR ,‰9‰” ‚ ’¬2E}m嫱Ғs\4mf3Â4 äÓi_8BÙ4 A@ñ¨Eu¦X$ºcÇŽãGæ† o¨.+S½>BäóDQͳó«]†¡7Ïœ)/Ÿæó©Á`JahÏ IDATêïoݹK’i0«3Æ%lçW»Öoþ2ÙßtÖYe õeƹ‰Ä®]»FOŸèïïìêìêŠV”þ¾ÁD¦—TE–å@yy¼ª2•J¥S©p4bºNÀðø¼Ô£X¶=<:„mç2UU-Ë”$©¼¼ $ƹ[WSí8ŽðåäLËø}^ÍCe‰Q¢PJ¹¡„º ×BÐjšRj:¶cL(’$¹‚sÅî©ÍÊ©VÌu KƒGè‘€Ò>BTB+Üì5 -ËB²Öqƒ'Äëð`4Þ@=kDMx â"Äøv4?,> ¨®††ØCõ„žPÑJ>›ÍbýsÑ,R©îìJ¡ôVD³ÄQT6€òòrx¸…8ªªbg°pZQ”à㜸á„% VM#*C¨‰ûŒŸVd'"bA)&|¦(m…5ÆX­„〟ƒºSÈßC—HÛ¶%IB¼”L&1+…p¨(ㄉ²P(ÔÝÝFUUEA,×uQ_7 áyÉäóùb±8á÷…‹n®Pwêdñaü:Š:Ã';š|» =ùßž#¬'¢ÎÑ“€ æ_véêWß$>­¶¢æØ‘£Ùš˜×ÎþñU÷<øÛsš~}ï­ã.Lvwmß¼ó‘û9˜YxÙeùdÚë«è1wüÛ=oÜò3¿7%Ò¿^{󛇴lÛõ̲g_xeÙL…Q 9=[Y^Þ1 W”·fr9ç_pÈ’c; ËŠB‡Ì’ˆÂN9¸±Æ Yœ~è±åñx¶lÙòâ‹/~õÕW/¿ü2êD"‘Ý»wïÞ½ûÁ¤”>úè£ ,Èd2/¼ðÂôéÓq e³ÙÛo¿]UÕyóæá3€ÇP¥®ë===sçÎÝ´iÓæÍ›g̘±nݺ¹sç¾ôÒKw!„¼úê«è-ýÄOà+--}ýõ×Ï?ÿü?üPÓ´@ Ífq¢6 —Ý¢ö BŽ 6<ôÐCŇeY@sß~¿ÿ¹çžÃB æææ|>+ ®ŒÛ¶m›9sæòå˯¾új×u-Z´~ýúÆÆF–\.·iÓ¦ ¼õÖ[o½õV&“AŽ.OˆL°˜ç¥—^2 cÖ¬YçœsN(3fÌÈ‘#}ôÑûî»ï±Ç»÷Þ{ß}÷]TªxôÑGÿô§?E"”ô)ZÂáöõõ]~ùå—]vYeeåîÝ»ãñ8ª™cmRmm-Z.”””hš–N§{{{Qq! Z–I¨’Òq¼ý¬³Î²,3àõgòÙ€/0vìØ•+Wþ`ñZÛöËL¶\ÇpŒd2yÕMÿrÇwœ=çìH$rË-·\wÝu-›·öôõT”WZ®8]Ï{½¾‚ëPJ¡\pá¸B‰²¢6  (B€P„H@!@&§'~ ˆp¹‚áp€¡(%ô„ÿ’ lîpÎ)Ƙ¢ªÀq³`hª\EÀqÁ°ÀãÍë‰F=¢@ê¸%¥„€É¸– ºåfÒƒ}‰tb Hw?Ö?˜ hbóý'ž°/½·ÕQÀå jJ$Vˆc¥eå5ášZ D’}À€nÂ@F (µ'€R¦ù€¥ëT’%(áL• #Èx=é†PP–°3yÙãŸ-ÉM“R- Eœ‰ Ún¡Àñ#^‚ Àdb;”ºŠÌLÃ(ñE@7UQ€·…O•Ÿ¬:.@–Û!UÓ ™€ßO´  3MEõ2€”‘ {‚ $@˜¬›-1Á‘”ȱÜ`Töýø7ÿfîRÊK€T”¿ýÈG>Ÿïر#ÿñÝyÇmrEe&Ÿ»hÖ"ànWoÏ~|(¬+5À^°  œÅ¥ËþûÅÓŽÚµoÏäÉ“ó¶éôMž2E7 èïw]^Y] ŒVVWmúróŒæ™j8ôŧŸ*ªŽE'LšÈ ƒy5 ¤»³£¢ºÚ qÇJT̓s0•Œ†#%%% À±¬€Ïoæ×_}uúŒ™’¢‚ªŸ¯ûС¾þ~UU‡ÕðUV€ËUY—Ÿ¹ðâ¶–íÜÑÓO ‡·Bâpû±q©A5Ûb%ñL>—Ëfc#FôôïiÝ;{Ä00MMÓ –Idiokk0œ‚"Ã!Ý(ÄKJºzºm×éè§Œ…cQo4 –ÝÓÝ…‚œŠ¢„B!`XÇß·¯ëðáX,«ª€\WW\Í(drˆD%Tîº.ç.e2‘aÔ¶mÓ1˜c«ªJØPòTÑ©vrCiTþ@§ UU‹yÜšÉoxoÂWñx'E•g¼ó" ÑuFã¾â}¹˜½)zc¹jøX’¤bbS.…B;ƒúÅüî1cEÅZäãLÜÂsO‡ŠgñûýB-Hă8G‡ gQÑ¡;P(½†vLx¢p8ŒçÂCgB, @4‚j{H;Ä4⊢œ7¾=‹DEÌJá1(.…Û'´*)úÆbçQâÜu]œóŠŠŠ"ˆ-ª;“iøù„¢ò-êƒ;V4áÕ4 Y…8˜Ø™"^úŸŽ‹§Úÿ^D$€ŸPV €~­T&ý‡u×ò09’EƒYÝ4¦Õù(Û~´PøÚêüó7JK+_ííŒGÞòɯ=ñ_£ÂUUZp×›½ûæóoºöûwÝ2ÿ¢ ^øÉªßÏôááŠ{nºã×ËŸýÞ¼ù[Þ}CÙ×ñzÜt>™ÏFüá®´®VÅÚöóÇÅ‹JœH|hвÜE>PJ©Äˆ(’e‘ ï¿ÿþ¯ýkœ„ãÇ¿ûî»1!‹¨É²¬êêj4?¶,K×u]×çÍ›÷׿þµ§§'K’¤ªêO<ñᇮX±)s(‰VSSƒÜÓP(ôÍ7ߌ3æ¹çž›?þ /¼pæ™gŽ?¾»»O”L&/¿üò»ï¾»¯¯Ï‹( ~ðÁ7ß|ó/~ñ „78 »»»q-(á»fΜùæ›o^|ñÅXµ‰e9cÇŽE#×;ï¼³èB] a°Äçó}þùç—_~ùå—_Ž+NÑšÚuÝh4F·nÝŠ6dÓ¦Mú¸Ÿ@w…l6‹õŽhÁ–L&;::î¹çž3Ï<óÎ;ïDÕ‡“ÃQ×]w]ssóoûÛ7ß|ùÓÅêwBn»í¶]»vM™2% á 5cÆŒ›nºéç?ÿ9 Ü1Æ$Iš7o+陜‡J¦í2.Nkšúꊿ̚ÙÜÕÝÇÀŽ–í?¹ñ&!¸U0::Úkªkl«P_ZÕw¤ýü9çä²YÍã™<º1¬hÕ%å @¢²0m"¤x›É0¹ëú™—ÈÌt 2!õ=Ê»®K!\p½`)ŠÂ$ê "NHsÛÜ•)3lËu¿æeŒrár•Q&\6¤“àºÄ唲¡©æ à Žâ ’`÷@^a äóJ!Ñ®PÐuÛLfÒiC×BŠººHY (Óí‚äW9p ”cÜO!\2vx‰àÒTî‚ÅAÏå3‰¾d"å¦2¥='“Íèº[pXnPïL¦ùÑ}Ür õ‡üáX<x}_Ð GTŸKwu…B!ˆEÁ2Áë  ÜQH(8€–»„ÀIº•èî*þàªPç±>pø½9æ€Wö[¼ €À]Mu)¨’ê¸Br`È@’d B€¢úÁ@™.E&Å›•‹®út,2pTR5 ¨”ƒÄ†¡õ@¡8@˜dðû£(#*O¬†ä7OþÉÖuËÐ3©´\S ¦ÝŸK¿´ìÅò’ÒœkÁˆ:0ÍH<^.ªª(ó–Dÿ¶aÝ¿ÞyW´¼ü½·Þ´ Ô«®ß´~’c}½oïÌïÍkÛóͶí-ÁH¸wÕ‡çÌ;~ò¤æ3gË^ﬔWUâXFqÂA;»‚Œ²±cÇ<^Å£­ûûê5Ÿ~6ïüóA×A¦²G?ibyy9È2 Œvt¬®®Y5i"x5ÈåA¦g^úýÝ6ä º/VKË¡PM×™:í´uë7\xÑE3š?{ÿ}Èòù|¾`TVÕ ùJô=_í.äõÒÒÒºáõ¹L¦ª¦.ƒ,§{ºïƒ¤&R^æØfUy ø8XVgg{DÏ áº–«©Á3==ªÄ¬\VQUUf¾@878H)“Y–eÍ€­çÇöx<*e¦ëpÎUUA:{‘¢ë©öÏÝÈ ³8¬Ã9ù¥¢Ëyño1+‚¿mÄ$'¿åä­6ÞI‹øç;¯ß[„7'?>Y¾Eðþ¿úDvÉÉ À“_=ùÔ'_#ž¯¨ˆŠÌ±â‹I*ü[<¼ï|fñ0|²8EÄrr'O6M.YìêÉGÍ…Nþþ¯gÇÎ%jOî0ú×ÿÃŽV’Šhöä?ù+(ÓAòwÞŽêJßùQý_i§¦ÛÿFDD¾MFp( ªz nye œ©Ú­÷ÜóÈâë¦WÜÛv î´ÑƾCÛÖmzäÑç&ŽÞß;øEä7©/9ÿ'™ooï&²,ù翸׊oZrí=üúO7ßuÉ”³<„-[³æ_I?%ßì¹`ô˜Ä×ßTT×ð‚ÓŸÔYYÅ¡þù—}4 ¼šË©À>ñ“«ÿv&¦iNž<¹··7 ʲ¼}ûö@ P^^Žî¢áp8‘H ¿2†EÁ –ÉdvîÜyÅWœ}öÙÙlöºë®{衇žyæ„(…Bá¼óÎkiiY¾|ù 7Üàóù ÃØ¹sç 7ÜP¤·^sÍ5†a\|ñÅüãW®\ GÅD<O§Ó©Tª´´}—‰*´ÔÔÔ¬X±âÌ3Ï|úé§-BFŽ©ë:V7â²Eéëë»ñÆo¼ñÆ©S§Æb±p8Œé$¶•——ã’‡üÀd2‰äæ\.‡*ä8ùs¹\8…B”ÒD"±cÇŽ¹sçJ’4wîÜÊÊJ\ 3™ f^J’4aÂÃ0òù|>Ÿ¯®®^»víäÉ“Õ455¡ô Z˜¦ùꫯþð‡?ŒÇããÇ/Zžá¢cšfEE~:>í´Ó‚Á`kk+’³}>ߢE‹xàÿ÷Ç„øÃ?|íµ×:Ž£**wC×½þÀÁ¶ýóÎ=ï?¿ûÕ¿üõªÅ‹Mà 2t;Þ0l¸DèSz|Ñů_÷…ßïM'Çë¦ßëJóÉ´S0\^–e&ÉÀ(¡ŒB @2“c”í{¿ÙÓßÕòù«Ê+FÖ7§ €š6åœ1”rŠ×ãp‡»†c3YR¨$Qf W•‚ Û± “RÊdEel\e@$p p°×3ÙôÀ`f0™Mg Ù\>›3 ÃÈ늢x~ $oD‘£éB¾rXmõˆa£å¥ Ó±åLõ8 8P @ŒgP ‚ÚfA¢LñÉàøJ#>QW+L&…¼é¤ÓùT*Ñ?€…°‰DB·\']HIâjÇ´Ë®©(w§»·G øcÕ£›&F§OÎA–Ši„⣜Cñ W8¡×R n0è€æP›,€º\ŠH8`'ñÉ?Ö’o?Ÿœç§'—‚ÔF èš³*`[ð“—¨ €}Ûa€‰ !³ŠÊòžC‡Ë‡¸âÚk~à7ˆ¸î'7A¡–½nݺ|V·ô¼¢jÛ¾Ú)wÝwO´ad’_ÿCД\w¯®’¯Û,ºîõ±èŒY§—––*š'V[Ž}8‚ ä[Œ‡R7ü;l ]•–‚帆1sæÌŽãíkÿ¾úxGû¢¹Ì x¼^eG×qoØ7˜üú›½£G ùCq5øý"›&.„bHÓ\.·öÃΚ?€ãᦦ¦»vUVVD"««õ Q:l¢¦H.{p•XEE… aõsþØ1J)ôùÁ²\ÇQe%öõv÷õõ•!y½ I¨ !„°,+Õׇéh‰1=ŸÏe³¦^ |HP{¨rCp BøeÎQÁ…k»Á#‡”¸Oj§Ú©vªjÿ?ûõý¿œ ¹KR¶TI0F&Üò†Q«V¼4¹{ Qð7WŒfÒQ"0!X•=ÒYWReÆêíκlѰ9SµQu~ù¿Ÿxìñk/½rĤIL76¬ûÂ[Zr0—\|íÕ¯<ùdͽû×HJ lëìRJ«S>mKç÷ߨ¨`^Á‚Sµ; BPÁ !@ *8|ü÷—-_ÖÕÕ588¸råJY–ò“Ÿ`É~kkëš5kúûû·lÙ‚ÂÖk×®]°`V¾üòË¥¥¥£Fòù|S§N}饗FJ¥Ž=ZVVVZZzÞyç­Zµ £;wî$„ 6ŒÒÞÞ¾}ûvUUÇŽ[VVÖÐÐP^^îºî»ï¾‹Ù}ôQgggKKË«¯¾:þ|Îùºuë*++«««=!dÑ¢E¡P¨´´”²gÏž?þ¸²²rĈXgÜ××Ç …B¨”ýüóÏ·µµ­^½:/X°@UÕÖÖÖ-[¶TTTƒAŒ÷x½^,GQUõ½÷Þ{ñÅS©Ôý÷ß¹ãÁÁÁO>ù$ŸÏ766†B¡ŽŽŽ§Ÿ~zß¾}ápx̘1~¿?ŸÏ·´´´´´Œ3FÓ4¿ßŸÍf_ýõo¾ùfÏž=©TjÒ¤Ik×®u]wòäÉ ñx|öìÙét:NõÕW555«W¯þûßÿ~øðán¸Á0Œ@ €”ƒd2¹sçÎÏ?ÿÜ4Í7Ο?¿¾¾¾««kýúõÙlväÈ‘¡P¨©©)›Íþ×ýW[[ÛÖ­[o¼ñFÙ×Úúñ‡«zº{>xûX,V?rä¥ ®ùôÓM›6¶lÛv`ÿþÛ~úS!@¢¬¦ªzVóéøýï7nÚ¼s÷×ñ²²i3fȪÇáîá£Çöîßîüù‚RÆ$Â(!T0JB‚ª–“͇ˆZS^;føh«;±õ“uk?üû±]{s}JÁ H^PüÀ%$—Ë ‰QFRÂ(¥”á–m¡:–°]¯"«Š¢H2µlË[€é@ß`ÿîÖoV¾ýý»[tµH<š:Ò‘ïèuÍp}„UUTèù\AÏG¸LSFM?ë¼s&Í:½bÌ(5ê…¸0A0U–Q¡8 ¸ » s0 @–dF™ €ÿœÁ!ñ÷Au\^7²rb㈩“Æ>cDm ¢çóVNg®Ð$%¢zÛw·Ö„KÜ|H¦S½=ë«XiဠP8HîKî»öf(Å”==% ¨Ì) „%œIÿŒBH L .B¡@è ¯€!Ç€!ü"H2!¨˜I˜Œ%8Á€0 ìÛ÷Ì•ƒÌçàºÀ9Ê(P”‰Y‘ÍB>ZQyÁÂ…SçÌRKKÁ°?~ýí–_$÷ìÙ3aLãˆÓ›šš¼e% „Ž dôŒãõœvÖœÊQ ¾hXóú}>IYY$^âÆ€R`06d Dà(PJÈPÿÄw‡@UTà¦Å•ül"ÑqüøØÆÆòª*ÕëÊCªͶ¶ƒ‡‚‘ˆ×ëí”)ñúz.˨‰Ç,ËÊdsz¡ Jr(^¶>¿WVŽ=&„0 b%¥P0@’¹eYI÷d2ŸÏ/ɲæñhÑqÓ´ºººõBêÚçÂuÜBA/++ÍæsM“%²ÌM-=ªŠÄ}ƘÂ$×q\ÇaŒ™¦%+2â¸.gÄ‚Â<*‚ —s!c“@w9ÇÂÿˆ×ž‚F§Ú©vªj§ÚÿS#ÂÀÀ"ÀÁ! $àLPà„ ÉB!ªi’벜¾~ÅŠgn¿íÚó¿·§åëªH©3õȦzu…õ«b_:‘òÐ?½üRyÓ¤ÃÇU©[æm?¼ù•gŸsrƒR0´ëå×6|¹¥é‚ù›7núú£¦ù}cSå;œ¤¥e½Bý&› 5yàåÿÎqቔè®à« #É@\—¹IÊl¸$°Ò!‘HD"‘“S¥€%€ÅØa__ÊŒär9EQòù<–ú¡B4º•Á ½ÔTÀ OiiiGGG,+²‡ !EŸc(Rf‘‡*„DoŸ\.'Ë2Zî`L4N—””¤ÓiÇq¢Ñ(!¤HØ+jË`]£ÇãAî,Vy¢¦›‹28(à8š 5[7ˆ" Å”4’úPǦȆLߢ™*äIɹ\#ÁX£%IÖ°vvv†B¡b­ä·al!pˆðÁÁ,:Ï I’jkRO¾v,v’™¤*ªm²G3õ¼‘×C¥%à8¹\.“ÉTÖÖ¦“ƒ¡h¸mSTT0ôu〣97re&6$ì‹[kBéPÚÂu¡`¡@% $wôxogWÛ¾ýíííVÁðù|±XLû';[}“¨‹Q} œ¥ À”»”ÊÀ9ÏN:kõ $;»Ž>Ö×ÛíŽGb^YS=ºïP4Œ‡c*£VÁv,C!2ѤÎtRúJ«+Ceqâó„*Kãõ#  ÀÀ´Îc »ì˜f@R‹Ø/ãVp…A€Ÿˆ à0DœK$œï¦ƒ°\9:»Ž>2ÐÕc¥Ò’ íííÞpùµÞ\jÜÌÓ¦\4T‰ËÄ¥€µ}*ÚÒÂPŽƒÛ%AÀ=ñÄá(2”ÀA % ‚ IO¤—ø `@‹hêÄgÓõ[ߢ®â#à¡S2pØ­Ž0‰ŸÈX‰=‡Û.^%Hú.—$I¢,58‰ES‚‚aBFEŸ×èéö”ÆÁ¶À뉅_O_O협í†B!!D¨´ t½««‹s®y<¸Ȳ¬0 •E<ÏÀÀ`86mÇ´-IQà@¥XIÜu]›»ÜƘ¢(L’ÀuÇq…À¯©X³þ?I8§Ú©vªj§Ú©öÿŠˆ\ €q œ—€¥@Ætª$؃M¾}îÑÙ3)TÒ¡ÒÌäô^nÿµs×y‹.™ë å³§ )¨ƒ ÀKÁdOë¯ÿõþ7Þ{¨ zê׿¸§¦¦¦íàñ=ëÖŸ]R©:t^i©Kw-£²òäûà«Ë?zgÄìf„Ë<À(ðhQYrÎ\ÄɈT°ì¡Ãl6+I’¦i¦i†t,ñÇC¼f]×Q½£•*Bdt`µ¥ô;4 ¬áÚûd2YZZZ,X$„¥TŠ'…“Êl¤R)¿ß/IRQ¦ØPÒÀ0 $Å¡Ó+ž«¨ƒ‡¡Ç«ªª™LÆçó¡_[ñºP´Í¶íT*URR‚°Çu]Û¶O”D4"Ëÿ‡½7·«*ïÆ¿ÏZ{<óon’›áf ³Ì ¥ŠXEýµÖáíÇ·8·l©¯Ú·öW‡VE*¯"þÚZ'´U´2©`PBB2ÜäNçŽgÚÃZÏïuιû âPßó|îç|NvöY{íµ×^ëù>Ã÷±Mög“Çt£…bʆ˜8Ó“ÁÁASÏÎ04I{Lâa,Íåraš2¹\Î ¾áúK¥R&¦.Žã(ŠÒé´!µkusÄÄadÙöôÄD®ÐT+®ŸŠÃÀj Ç1YÖd±Xhï€RQ*¥$ÈvÇÒ÷+3Ó)CâÙŒµ¬'ýöB‚ rXcf½ê:tÕ=±3¤„ÁJ¤€#A"Žƒ(ÖR’ãx€ŽCe ,ÔªžÙ½}ËS#ã0³oÐc²¥mKAL¬bÍqÜYèÐqÖB†³íT*m{κ—‹F þâ™­œñÎ{õ…™õëâZ©ÊZú®íúu¤£ 5+(²-Ïâ †Ú]Sãfd[ý¿«E’ˆ™µ WX b€y(†Rˆc(53=ùìÓO<7X*NP Ç†G ]ôçïCÚ‡M°)$Ö d5ÂY Þ'‚½@u42{‚fèz¡'°¡4ˆ_K+‚Õ! „7(éqÒBB h]dh°¨£^kšbBœ€d Ñ8«™&ZÇZCë˜ë ’ŒO¦Z«¦<Œñ‘¢VQ{{§pê…(¨Ù†Tеy52™ ÕRÉOg Qìèì‚ëÄa-R±ŸÉDµšíyQÚŽG‘eYLsèLìÏ–ˆ«#"n "†Òv0^ÆSSV[¢¾ ­ e†a¥Òé¦g Œ‰ÑñGyÄtÎYç:Ù4*e¤\0†wïÞ¶mÛÆ'''ûûûýÎN0# ẘ)©8mëìpS©çöìÉd2íË—O/]º4ÓÙ©Êå]»v™¼Kf IDAT²-ÃY–Õ·ntyzמ]žç•ËåµV.Ç3¥8Ž'‹ãæ5õ6éïBÚåjÉe«AÆ‘—ò#­ÂHeò¹8Ž5³–çÔåU†q$,«…ˆZÒ’–´¤%¿¼È¿ÿ»¿‡€"(hKhÁL€ ‰ ‚㊠bG’ãú ¬]·ì?¾yó©«7p©V‹,i÷uv-[þ½‡rÏö'ý•}ö²¶”,dà:Õêòž©‘‰×]ôj/ë:¨zô¿ûßm©t¡¯ˆic6¬VËnoÏÞ üÙÄä¹oþã×½ëR®Iaª±ÈMÀ7¬Í~ Ð\©T¼´o|†YÒ4òùL}4CgR‰ ~0*»ã8F_—R>÷Üsííí&7ưõ²ƒRÌŽkê@"„°mÛ\:Š"«â86,Æ!cj7…¡’3¸¨³³³V«•J%ÃúbÈLL: ±•Ú¶].— ¡‚I|Ú»wo¡P0ȤY[À¶m“‰T­VCÉ )¥!30 A¤Óiß÷ ¸ïû&wÐÔÞvÇ´655e8.+•Š)•Ðä{0¬ SSS===ÆÃfœ<æ» ã2-þͺIƒ6.2!„¡|1¾&Côi.tèСB¡`Š©)¥×àú~¹\òÓéJ¥ìú~ifÆ/MO»žç¥R:ŽÈ¶¤–ëJÇ‚–”D$%˜Y)’²î6!@¤€ 2ÉN$HA³Ž#á:–€cÁ±àHH‚¤ˆ”KפޱÂd$1kÇЊÃX0 NLØ»oè¹ýÓãÅŽLÖuaËH« "¥`K;åUuTŽCv­ÞUý§žsƲ—¿¬ûÌ—t¿aûOîÛºe󾡃ٞÎãN9±cã:¸¶ðm+•’–m´cjÒìHaK¡ "0_hnÐÖˆcDQ†Žç ‹¤%,KÅ:ÖJiÍ‚ KbId ÏÖ¾eÒ½kV¬9ù¤öö¶”›²m{rjª§£=ÓÓm"(ª;50K9ŽY<ÖÐlj^YÈD¤%E‚4I1 €ˆb € ØØ2Ôé`¸g´ ä%i‰Y¤bš=›ê¾°ß…€"hBLÐ -ˆAH)…RZÒÒR¬AQ¬²ùL*›™)U]Ï™ššö|7ˆBH â(Rʲm&([–e;NurÊ2•/@HT*"íC’”2Öʲ¬FâWý¶’IáhŽÒ‚0b¨(¶G‡a¥Tv2ÕfJv&ÍZ‘aKÛ’– ㈤$ã“Sayž+„œœ˜ììêîYÚ‡ (WJNÊG¥’éîff6oÞìy^.—ó|?.•„emyì±çö˜˜œœ,Ž¥\¯R«‹EŠãŽþþ´mïØ±cÉÒ¥Âó¦‹EÁhïïÏ8ÎÔäd>•‚ëè°V j†\+›É8¶M¾/…˜Ïd2†Jű1?U«ÛóY„p<×MùŽë Ç‘R )…¶í8®K$X©(Œ”ÖÒ²h."jJkwoIKZÒ’–½XH„ø#aŠ4¶ Ĭ5$Aij͹gsÉÅÜû‹ãÛú¤ïE®ýÝG~ÔÕ·ò¾úá=;>yéûo¾ó¶¥›–~þS×u—DyÇþÑZ8Y*ÐædÓg½æ÷¿u×í÷ýóü侯V2mÔ–÷Û3»ö ç¢å¸%úÇOBªrFž' HÙuhAëzO*›6à§X,šª”&@«éT1Åp z1aëÆ‚hqß÷›µÀúûû» ZÀiÂÞ r0\ûhði–ËåžžSþÌÐYšZ„ÆÙ¢µN§Óžù¾_©TÆÇÇ—-[–ÍfÉq$ ¶1Aq&P' CÓ1Céæ8Nww·é§mÛ†MÁÔz:s/Òéôøøx&“q‡ˆš\¢¥RIÑ,df[*•²mÛ¼%}\›¨f0d6›éîî6¿2J›q‘™®Æ© •JÏ›ñ³5Ý\ÍΛRM¸Àu]3 K–,1' ˆÃ(ŠÒÙ °2¹lD”mr’ Q)—Sétif&ˆÂöŽömà9 ˆâØvíú$—I'ƒYD:ªTMÿ3¹¼´Djzz*“É(ÖLd9¶¤X“m 3µ’kIaY:æ8ˆj¹T†4C1¤Õ¹qÝE=]c'Ç'ö<³C‘ ν¶¶¶L.ÛÕÕE¾‡L¾juzïÞ§~úÔ]{2M‹ËÖ¬9÷÷/ÀÀrH#Ю¨Šb–¾å:Ž Ã hÇHìj|ª86z" bY÷‹H T+Õ¨°š¦ô†9]/GÇuä/$³FAº=+Vô¬^·±Z}úÑÇ•&zlÍEB2A°¶˜,5±Í[OhÁ‘&:Ãléi0  Bj °c‚Üt’C´ h®‡–is¢æt}e“I ÔôPÉ`“”\cLá]C„¡u€ ¡µ&‡iMN•ÇI¥ÓÐÈgr¨qJ¦À°-kzz†ϱ˜¹¦µ-„מ"eKÄAdeS°„Í€ÇZÅ*R’”¬4šŒâ›C!Ñð¡333í…¥s¹ÒØØÎíÏLONIÛ:휳\[FQd96 á¥RZc¦R)òAF±V¬Ût|.—Ž›îè@ª8FG gñ† R]]Pš4”öü R]²dÉäÄ„´¬jµ:1Vtglx¤½½Ý,> B¬: mããjbÂtrfr*+…Ìf»¹ÛT—RŽŒ´wtB©z8¢Ö‚H’бb¥•VJ©°¦R™Œ—NiAÒ’6d¤bs¾€B€ë¼ ¶´Œ'­„ZÒ’–´¤%¿´èÿý{Ô£Ò4„À²Ëo£Ás„„¥ª—Káy¾òÖ¯kÏàÁtg瞉â4ãyÅÇ?÷Ùµë6ôtu‡Ó•sN?ë¬5Ç_qÉYÕ(Ý×sÞ…twæÙ‘ÅÚô·¿ùͺúÓç­^ÝévÛ â€3iwùŠûùCWõë=&&'2Ù¼ €Rp(jD̳`‚0q¡‰ŸÿÂ_¸éÆóÏ?¿££cbbâ‰'ž¸þúë‰héÒ¥¦\©©­fŠ7›ÚÆ“““ÆMa<0†º>Y€ÌøšLÉTC µ¶mÛx0´Ö“““J)cã4®'­µq­¤ÓiCmâ÷ «}­V»ûî»7nܘËå †!¢ïÿûk×®5n(ãE1ªªA#&mçΦt©Þc*Ì·†`¦5C· `ß¾}…B¡éœ1IG†äÚœcЋ)#`¼gÕjõ«_ýê÷¾÷½Ûn»íÜsÏmfR5‰³gffLãétzjjÊ8šš4Ù¦Bã‘7eÝŒ×È@;ß÷Mµ" ‚ÀóúÈcRZW¢°ýÚ—üÞyîÚU°ȶ„–-l[ØTçLkº]˜gõå†2-d½’Ǭ8&0Ø·[Z’ Ñ@ýO³n(ßd [ÒÀZK!HZõHBiö»–-éX©Ç,3K†d"ˆŒKÌ#…küQ"Ñ©ÑQbBÔ$º,£òs/“¸º$¾2ƒ˜:H4¨bL›‚h± ‡hnî¹ „Í(5ª—»ˆ µjèykh ßwl[ Y÷áè©ù.j!léz.aI)¥ ZW“,[†Q¬Y1‘0yI˜qÆÜ1¡¤C-A@˜­{•J§9VÆc##ÞÿÏqO9é¤-Û¶eò¹¶ÎÇuYkVZűk[žm †#%GaP®ä< `ªd è0 )„çÛ©ôøàà9¯|¥-*~üÑGöŒÊ•U«W‡AÐwÜúÁƒ =+W:þ„´ROmÞ¬•rm§½Ð6:8ØÞ×'™'&&¦§§Ã(Ì vÚ‡-…à Ré”ïºCCC)×#ÍÆhAÆaEZCá8¡ÖV©LÚöý8VBHiÖf B¡•Rq,ˆl×ÑÌ$ê¢V¤\KZÒ’–´ä ±f£4¸æÌ¾+ 5Hp#…GR…d TkOßsÿ{Þöö×¾ì÷zøg=ë×|á?¿…¶l³ëÊKÞtºíÓ2mÛ›ŸÛ7ZÈmxã%ÿãÚkBߥ8’DLÄ$DƒªžþAÒ *]&EÌüýÞùì³Ï^vÙeM¶€‹.ºèöÛo7”І`àöÛoãߨµVJ=ýôÓ7Ýt“¡[xÍk^s '<øàƒŸýìg¯¿þúuëÖÕjµï}ï{[·n½âŠ+²Ùìw¿ûÝK.¹Ä0\—Ëå»îºë?øÁÚµk§¦¦>úÑNLLd³Ù›o¾ùž{î1…£(ºòÊ+¯ ¼£ Çéëë;tèiÇÀ³5kÖlß¾ÝÄã}ùË_~ôÑGûúú6oÞüo|c||üsŸûœ u{òÉ'7mÚôÁ~Ðà·ÁÁÁ}ìc×]w©S¶eË–-[¶ìÙ³'NONN~âŸ0øgrr²X,nڴɨS»víúЇ>tÝu×õ÷÷7 “™°º[o½5ŸÏŸþù?üð™gži²¾ýíoOOOïÝ»wãÆoyË[lÛ¾æškÎ8ãŒW¿úÕ™LfÇŽŸúÔ§þâ/þbãÆ†…âK_úR±Xdæ³Î:ëu¯{]­V38êÎ;ïܳgÏ®]»²ÙìG>òfŽãxÛ¶mŸùÌgn¼ñFSÜäUnŽ2f˜F-¥f8©šŠ´fSÿQ»¶C ‘=Ï=t÷÷=½#'ÝžLÁ­]=à¥Sí½ÝnÿR´çAµJE…ڑ³·oß¾“Ž?açSÛz:»zVÖûíP©TFGG/¸à‚ýèG«V­2w†ƒnÏž=]]]ÿò/ÿòÖ·¾ÕxHþõ_ÿuddäÙgŸ]¿~=€ÎÎή®®w¾óLšÍi§vÞyçù¾ÿŸÿùŸ§œrÊ#ûÙÏ^}õÕW]uU¥RùøÇ?þŠW¼âmo{[¡P=óÌ3|ðACP~èС¦*s8„¹á`G…ò‡þõl›Ù2h÷Þ=+Ww÷÷_rÉ%¤ï{ö‰-ã‡|ao*z)ŸÚ±÷´ÞÞ>þ?¿{aO{ûk{6¬|tÏ–Ÿÿû`gOßëN8-ˆÂ—Ÿ{ö7þ¿/­_Ù?U­ H¥¢ÿtÿ®~ìÙÓV«Õ:RY°:&%Nk½k׮믿Þhe2™ááa­µñÌ•J¥ž}öÙ·½ímµZ­X,žwÞy7Þx㥗^jRqzzz|ß'¢sÏ=÷СC†hÁ¶íb±hR_V¬Xñ¹Ï}î†n¸îºëL&R*•*‹Åbñꫯ~÷»ßýŽw¼À¾}ûöïßõÕWoÛ¶­··7ŸÏwuuutttuu™ÊÙù|ÞðÝe³YfþÃ?üçžzꦛnzÿûß?22222’Éd¢(úÊW¾òµ¯}ÍuÝçž{®¿¿ÿe/{™éç¡C‡òùüæÍ› ïœIšššRJ™Ü$sÄŒÆ;ÞñŽ3Ï<³³³óÒK/5ŒŸÿüçï¸ãkÖ¬‰¢È¥5™6yú¾_.—GFF ¿ö‡?üá|à&0¯X,^~ùågŸ}ö_üÅ_¤R©ÁÁÁóÏ?ffFkÝÕÕuà 7|èCúØÇ>f2ªMg’ϯNÏLX¹ju¹Zq4Ùí…3^sÑšU«wmÞ:vp¨—S SO9íé§6ïܹóémÛö ù}½¹\NO•Ï8ñ”ŽÕ«>»sr|<$a©8îZöð¡¡|>o·òÙœŠâî¾çø5ëÛ …Z­Ö×»¤-—‚€1!—¾ïWjÕT&N)ÏVª)ÏŸ.‡Q¤ªÓ%–ö-g‚é”ËvX¢µ0$ªÇ¿5ë(˜e¶™d•œ„æ¿’ï]ËAÔ’–´¤%-y‘ÑâšѤ.gÛÚ‚ÉiWÑwî½ûÒW^¼2ß¶ÂËL:»{Y©PHùv·e g^qÊñ3~:ÿôÃO²ë?¾ëéâšlºëëÿöןpú(ðès;ÿùîÛS«–ŽÖÊmV†"Y÷-Zwo¡Ôjµ+¯¼ÒdÛ»®{Ë-·Èf³ÓÓÓZë?ù“?¹öÚkßúÖ·69Ù‚ ˜žž¾üòËGGG;;;Ï>ûìo¼ÀpʉÏ=÷œŠb»½;—ΰҺT··³û´S_²¼o™ªT‰qpÿRnzÕ©§mÛ¶{÷nÏóz—,!ÍíÁÁÁ|ggqb¬R*9Ž524ÜÑÖG‘Ÿ/TQÒZ§ÛÛ'GGª¥’ŸN°3iiš™VºÎ?™œQ†~fÑùÖ¤liÍÀ–´¤%-iɯ %÷ó]áï"Èr: ˽óŽÿ§m)Uxéš ÁÈh¬òÁ"çý0,m\ÙwðÐp—²™z(šú_|ÿ¹¯#Ú»®xéŬ=Uf ß~èîÏÝþ­Âé'Mƒ]ÏWµØrfcÙÛ*•ʺuëš›¨Á'¦·étúãÿøððp±X¼ùæ›o¸ádžá§?ýé'žxâÊ+¯Ìf³D´nݺ7Þu×]Û·oï{ß À «\.·oß¾«®ºêk_ûšñ±8pà#ùÈ–-[.»ì2Ñn*ij£¹žsÎ9aj­óù|­VðÈ#¼á oøÓ?ýÓW¾ò•¯{Ýë~ô£}øÃ|ôÑG v:ù䓇††Þ÷¾÷ŒŒ˜C}}}•J¥\.·µµ)¥ºººJ¥ÒØØ3www§E¦ì’ Ï‹¢(ŸÏÿíßþíé§Ÿîûþu×]w饗Æm4hb†¶mÁ„CCC'œp•W^ÙÙÙ¹gÏß÷GFFÚÚÚÌ —Žã8×\sM>Ÿ7 u·ß~{­VËd2Åb±YÑÕ°P¬Y³fbbbttÔ„#6Yì6lØ@Již©Dôkð->Ÿ‰f*%Ïó\ו@{Rä:!­ÜÒ®œR † æ8P$¥´­$$hʼõÉõëz;ºí?`—ÂòÔtæ¸ ð|!HÅñò5ШOtttè(/Õèhï’%Â0œšœŒ¢hlbœ¤€í¬>î¸ÛŸö,KÕ⨕*+mKM–«Ëó+¥"H!]7“Éh–Ï› ´pÎCì-iIKZÒ’–¼€Ýöùw¦þ'@.äØðh ÁŽƒZ×¾ùŽÿ¬ºâ‘[sù™Ñ±ÞlΊ• BŒNf˵€ÆF×x©/üã?~âýuù«ÿ`|lª£oÅæ¡ƒ7}ç;Ï;{JÂa°åy†æ¶Ù£Üᦧ§£(2‘Q•ËeH¤”;wî¼á†þæoþæÆoü§ú§T*DZïû×^{íW¾ò'644T.—¯¸âŠÏ|æ3½½½xÜqÇßúÖ·þìÏþìž{îÙºuëÁƒóù|{{ûÀÀÀUW]õçþç×\s)`:44d(݆††|߿馛Î?ÿ|C~DZQdóùüé§ŸÞÛÛû†7¼á]ïz×yçgÛöÒ¥K÷ìÙcTgSà5ŸÏ¯\¹²R©ø¾¿k×.!D[[Ûôô´ã8ÿþïÿþ¶·½­³³³­­MJ¹|ùò‰‰‰eË–ýð‡?44ß©TêñÇ·m{llìÜsϽöÚkÿò/ÿò-oyË}÷Ýç8Žáœ0tp¦Z‘ ,,—ËÆøJD¯}ík·lÙR«Õ^õªWÝxãÝÝ݆ûá‡6Œp?ûÙÏòù¼¡ä^¾|¹a™{ûÛß~õÕW !Òé´a9衇Ç9î¸ã~þóŸoß¾Ýðqk­¿ô¥/½÷½ï™™`óШôʇ‘_…*ŸÄ3õ¨ž(TZ!åŠBž% †Cð,¸¶ˆm!=WØV²Áf”y“G /Y–pj©], IDATø.R2>riX@ÊFÚÑ–Ž(®‰8N»^{Áñëp( C“aex°Ð,éÙa¾·ä×&Òqâ8"ÛJò"åA Ž‚Pņô¿££ŽcûþеkW¯(t´#¨™Êho+A™t­X¶|Õq*3%r»{ré \wåšµ6Ä¡ÁAŽ,Õji|â¹Ý{önÙŠJÕµÅË×­;éì³wïÞT* ÞžÏóVlØ AŽemflïB&[ ƒ ³wIOW÷Þ½{GGG;–-3åÈŠÅâ½{'''53&whÞ;5ù,:-çÕqjIKZÒ’–´äECD‹ª¤ ¹®gµGp|HéžqÊ5_ÿç\ÚÏä–í:¸?•Ëä¿SÙ…AX’žRèzÅÒ53Oï³Éî:eÓ—¾çþìÝ/ùƒ×f3ÝéEÕŠ §Ã}ìdAO=õ”ã8Q Ëðð°âÛßþö²eËLË»Þõ®Ïþóa°tàÀB¡pûí·_xá…íííétzÓ¦MZë³Ï>»½½ÝuÝ믿¾­­-N‹Å·¿ýí_üâ ]ì–-[2™Ìù矿{÷îo}ë[étzÙ²e·ÜrË<0>>þ| Ã7½éMÆ5©›ñÕ¯~Õ”úèG?:>>þò—¿¼T*A`X ŒŽŽAp×]wýøÇ?~ôÑGK¥’çy?þñï½÷Þ-[¶¼ûÝï~å+_i %U«Õ­[·Q[[Û§?ýéÏ~ö³×^{íO~ò“{î¹ç¶Ûnó}ÿúë¯éK_Çq*•zík_{ÕUW)¥&''ÇÇÇñ‹_ÜrË-·Þz«Q²]×­V«ŸúÔ§¾ô¥/Ý|óÍ'Ÿ|ò©§žêyža¥»âŠ+îºë®ûï¿ÿ‡?ü¡yÏ<óL>Ÿ¯V«†Í|ll¬V«1ó\°zõê÷¼ç=÷Ýwß“O>ùîw¿ûÖ[omkkÛ¿ÿ­·ÞzÅW|ýë_ì±Çn¹åß÷ ÝR©ÔwÜqï½÷þüç?ùµÍøä| ¸ÂrlGH© 4KØù >ND=ôвeËzzzvíÚµvíÚžž“;ôÓŸþtffæ”SNyàÎ<óÌ¥K—ŽŽŽ¦Óé-[¶¬X±¢»»Û`ž\.÷Ì3Ï<ûì³_|±)þ3>>þä“Onܸñá‡>þøãÇéïï/—ËO?ý´)a”ÍfMõÕW¼â†rÚİ™®Ç |òÉA˜¢¥RJ×uï¼óΞžž3Î8ãŽ;îð}?N×jµ3Î8ò¬ûî»/ŸÏGQ4::zÉ%—4|øá‡«gãÆ¦rÑîÝ»wïÞ]©T.¸à‚¡¡¡gŸ}öÔSOíéé ðR©lÛ¶-—Ë …mÛ¶™°ºSO=Õ¤îF>ÇqxàÞÞ^Û¶W¬XÁ̦ÄÐàààž={â8îééÙ°aÃôôô¾}ûFFFÎ>ûìT*µsçν{÷öõõõ÷÷›”­¡¡¡¡¡!×uÏ<óLSÖÉTt™™Ù¶m[ÇkÖ¬éééíêêÚ¼yóÞ½{ …B†¬¯™0²¿¨5FæÏg T´´,¡Š™`5æ ƒ ¤¡u¬„¶XØÂ‚É9{sʕλ Ĭ"h"A ´¥Ù¦YùóR“·äÿBa@iE‘çz¨¨%­bÅžãq¥vÿý÷µÚÚµkWõ/‡çÚ¹kjrü¸SNýÙ]woܸqðÀþL&³|Õê‡~r%ŽN?í´¼ôvoyzdxØÍ¦Çj¥ßó›ûÉýµéÊÁÀŠ•½'Ä“ÅIŸÜº¥¯Ð¾ný†Gz¨··7åûíÏîÜ92:ê¹î’%K …‚R*½|ù®GY³n2ipÌLŒ¶··û]åÑÑr¹\«ÕúW¬D.«*åÉé©|G§•òѳrÞ«dŽ·j µ¤%-iIK~“ˆh¡Ä,®rg ¬ˆc„µâþ½ýÎw•·í|ý꺫ñÔ®}Ë–vM:Õb­ä9cJîTzô_}ñÿœþŠßÓ‘N1¬aÌ‹pŽZ»mî”MÆ¡f¨Õ±î ‡ÓÈ'‡kžÎ .2yG³!ˆB‘‰3±"¦¦NŽ= ÛiÞi³æ©ùm­V3©y/Íì|$hš–Ts|¡‹£yæ¼ìùf›‡±ä¯ OÚâ.A•lßxE’ùuX|yN1S”¸IyÜÄ0t˜\Ž£i>š‹ˆæA#NFì/»%¿[èsæÏ<‰ƒLÌ’ÅäðØàà ´êêêêîê‚m!Žï½ûîl*]š™zé¹çÝû_÷¼ô¥/µ;»øÁÙŽ¶•«2Z>ý‹'K33p¬ŽN>ã´|{ÛÐsž{zgÆó«Õj¶«}ÃY/Ù¾cÇäÐ0‡q37›Í/í_žñSm+VÄããÆ³r`àÙ;N? åÒÌÌôÐÐP:ÎårÌ,…UªVH ¡ Ê´å3…< LIèÖ3oIKZÒ’–üú娶b ‚!¢ºõ;&ÄJ0“ôÒº·ëÿüà¶+^ÿ¦ütóÅkN(¬]³ghÐËR%ÆXZ—:ò=ùÔ{";°²TËbS^¬I K@[5ERRÛþ­’…œH¦·¶m'ÓQšiúG¾…yÙüÍæÁ fn¦ 5¡£RMfçdgpø@üæÏ“ˆn!.zÁ)ο±¼”D Lƒ|æa!Ì+ŠzLÔðs¯€¹Uehnžco¾%-Y0µ¹¶‚å:D”ö=X6´ëþ+Ê¥Ò¦Ëg*åöž.»·û¹ÍOe ù'ž`g²#Ol/¿qS)ª©éñt.+'WÈ···2Yi[^!‡T*“Ép¾¦j¡ã8ù|>Ò @¨âéÒ Ú‚ª•ò7¿É¶˜Më½{÷¤2Ëq˜(Œc­u*ãæÜ|- I ¥¡ïDZš¥ZÒ’–´¤%-y±ä؈!€P§Š9V4<=åe»kŽûÏ?¼ó‚wýé¿>þÀN‹Ëí…l¡§¤ÄƒÕñý«Ú2u0;Щ(YN"À\ 0|À]X«ñ¨PS¿apˆŽQž·yè"éjzc ýà dž´Ò$VŸxüÆOè\=069Kª™éÁÑá•kìL àC‡”@Û‰ÇGJÍ”KAÂ÷Ò™ D½3ÓÑ ­£½Z­ !2ù\ÏÊËV­ìèéêèéêèꬅ²xn©R­–K®ëŽîÞ=53#mËñ\’Âò<7vÓ)¯­É²míùöŽl¾àx)°Ðrµ¤%-iIK~SòBv °$,B ‹D,‘ɶ1„'s¥ ô§W䬗¿üÏÞðæ SazëøÄ;oúä ¯ÿƒŠp<‹cXõ=\Kõ’ì‚6³|^°~]L¬‡kÿ°)% <0³õ×碑yPgáƒy ÿ[ó¸)[d NÒÑ4ÏéÔ<²h¯%’žwBò¢G#$@®ýßL}›…©ëü¢9j æ^a‘¼&Üj9‰Zr, ˆÓ)9‚(´mÛ²*ÖJ)K@X”’™tmjªå öÐÏ. ~6K"]ßëìí âÔ„ŸÍä:Ú¶¥ÁåjEÚ6Ò)üt*ˆB×v¤”Hù ø®³¬¿?ßÛ3þØ/P©LNL Ž@s­V#)¦f¦{–ô¶ww‹Å œ”çº.y.Ë÷  ¤²tbYk=Ü–´¤%-iÉDD€Ä@@À€†´àXBÊÕJÖOUb Òþ†×üþ];·¼÷­o;è:ÿrÛ7+i?•^2>Q©¬Õ5 a”cñâ¨MwÇotÈI¡‡‡C#óJÜÌÉŠ„Í’A& ]XæÓ˜]›ˆËô°ùÛf³I]¤9Œ˜ëÑJ"¢ÃÅõN³hû¿-Zó(´Ñ£¹#Ͷ³µàPKžw¾qó=8Q¼†í8Å Ð`°´-!LÞ Bx…ü §Ÿ—+ÃÃÃKW­¤cp*ŸÝ¿kÏÁÍOÎT+'œt\Q)l× âŠ’@€+W¯VA815Ù19aår°d:›%™°ý™íAtwvõtu<ÈÌK—/só9Jù©8NNÎT+Šs–Í‚”V–°¤~l!,$[¼%-iIKZò[ˆ`A´6ª° ‹P)Wlͤ‘Ne+NFµÂŠ¥ÿr÷÷ƒZù¶ÉÒd¥=ŸDKßÐ4AÔÍ›ú…¦°/Z³ïW«¨EÁ$fXXd£‰ ´;šØ³y?I’A7Ïi^eÞµL~Ñ<—ÑnpÞ™ó’udÓ¾€~y©SP"kh^tÍQLù''9 4iêÇÜÏ–´äh¦o 1À²zI²”´†%‹cc]í`HÏY:° JÍ”ËÒ‘‚‘ko«…ÛŸÝ·wiÿò®ýÕrÉO§U1a|rbßþýË=ÛîÈ ÇY²vMéÀÁÝ{÷H×Yº|Yª³Ãò=„a*›QJ‘%#‹\®3Š*¥²ßÞ‹@ð2i7 GGG5X8®ëºD¤™¸¹jµ&KZÒ’–´ä¿ ""hÉ¡„ P–„ˆEÞOAk³¥…Å©BgÛdµ”Jeà9¡p#ÀnÏ¡«ÊÈíX“àÚR¤-–ÐÐ EÇ̬p4Úü/‰p~ÔÔÄ É<ŸEÏÂŽê`QðD,É‚9‡W‹–A\ØóEHÉ[àÅØ¨~d~#@()ªIdóüyÏ Æ…cè(c>¢ÙË@ ÑR [ò QÂÕÙt›/šÁŠm[frY@°Ö1k›P jžï+¡!½ý'W‹DûªÄ‚@$m+ßÞ6Q¯Ôª• –Vi‡ S(d³YÏóÈ’ ‚ã Žzz{}߯V«Û¶n]2Õëú~y¦ÖŽfMRäÚ ãS“PÊO§´Ö–åjû:–C+ƒ®%-iIKZòߺ®2À*’ 0Aè¸\³R)0—J¥B[‡ ”ŸÑ$¼éZÅñRp]@O–©3 ©‘0Òã…ÿÛU囇´ÖL àØ_’Ob‹]“ n!˜Yxð(YË›ÑwGTÿíå×{g º;Ýx„bAt‚»®éÍuk²çüK÷Ÿ…^ЙÄ<áÄwŠçâ»Ä9´°,Fî"ž¿KGw|tôˆ§=/û™@ÝBttŸG%âˆ+°im±û „h` ó‚ lY*OgÒ)FÌ’ë5µ”¶m[µZ5eûÝR”¦§2…|E¶ëu·ÞÏç£Xç»ÛµçFJÙqŒLz`ýú\{¡â&ˆ…Hu¶k¥<Ûr³;Ÿ §g†‹ÅöU T+eÇqlÛéêè&"KØŠ¬Y±–R6½£ÌsWBZì Í5+ëÛ̇ÓE¬c²ö¼È{òb-òbL³`iÝ6{Íþ\õ£9š'@‡yØ|˜­”^\ÓÏ_¾AGú|ÞçC—ãÅfïaf1«cEÉÕDÈÃfc‰º¾I®%’6íúþ-LƒtTZÈïŽnE¦¢-=ïzÞ’#?­ªð"¡9êBAZ¬Â"!jµØv$8’’€¤šýA ÛÒq³l,š¡G¬Ab±%‰Ž¢É%˜Ì~0¯PSs̘´gºÂ‚ I°Éº'@5–â¹ÏZЧ:’'"bQ×ëuc2‹º˜§™ÅVòV´f³&H)¤ÒJDZ縋ÞhhÊÄÈÌ ½pÈæluD È9Èjþ‘Æ'kED Ãg1bÎ s¢^ÍÿòaÖwV:„ÔõvC0C:`fG:*Ò6$I %¡Á¤54 "ALˆ5È<1€"(až–ZÉH“ t !”€"!žžœ™Kµ´åtäÛòù6JÙ‹ÏuÓgM` ,˜m-ê·C MKƒ4CÐì(ÀT×Å¡1G`†L„Q}„"†¦º^K§Ï@`¦¬-5“˜´-ô&”äoçM\9ûÄê÷¥š´ä€0ï  ’f±kóis#=ŒuÒêÇ$%*±@ÿ˜÷Ž @‚“C:Þ%ºZ¿\‚T“Eã½`3xÎsd ”9´…Å*ò¤M,¥ª›ö™  œÐ:´¬úÝ$—èyt6õE^0ø<¦&ïhv^'e€Œw’¡b†fè†BI [”¹cÖ ªl®Ï«8†Û¶ ÊH à¢j7'Êuc6&A󜷀bhjÌXJ.g³÷KhZÎ@ªÞc¦Ù¥™ë£-f‰|4ƒhNå;š{áæ'§ÖÜ•¾¾³0“y ‰÷T1˜!DbÛ¡#Ù’zŒ>‚†£çžO TŒZPM§|¢HÙ¶L,“ÍìÓKaúÚè6êÏ·þÀælw ˆ¡LQ˜:Í,êNöÙyÑxÌf3ƒ&ÔÃIƒb¤ÌÚ%K4âñ›O^'À‹±ÿÀ,³¬fWýÆ®¤„Åu7DÓfd^=ÝXõ’>$ÅBãËX±ð1…éÑ‘Û_xuŒj/?_Ë´˜ýh!"jüŠ”ŠŽàÊhÉ‹å]Xœ€Ðàæê&8 Ugwl!¢ß‰y²¨ÓšÌâ ›Y@ÖwcÖ „@RMe%‚l΢ÆXi!„u«T9iZåßÑ Ð`@3+³£Ö³×êx€"Øu=‡¢VÇM´cTs¥X0qCÓ ­˜‘ÅuìÑÀ?Ìææ ÏìB¯ŠTc}#HÂ\Ýɨ:ÒÚ2)û†ÒRë0lË•RÄ n*Ä0 õÔ»†iÁ`m4•Ä*Ðô©®YˆÀQÌ‚ƒCƒC E,@ÔÐ̨®Ÿ‰Es­L€ææ'1˜´€dÒ‚ˆI‹ùŸõKè†óPBG: †5³Z®eRyhVB'ë,¬§ÀÅ9û4+KC²®¸€,ƒT£¦×ö Áº®½ F3 ìzoÀÐFc°©Ä,‰%ü¡‘q‹ X‚4A7K@èÃlŽsÜ4%+š±T  @@×tu(#ÔaQ´¹î¬Î&©mP-³ ækaåE%"3vQ³.'938yÞK±@e¡Y(;Ï*ްa%ŒäÍrÕͱš£Ð‹zã1týÁªYÒ‚&Ø¢ˆÀ÷R˜¨û:NœÓl¦üDDÆoówÄI Žê“ͬ%Ï“œFˆ¡uýÙÕ¯¹p·ç#Iˆ"æš› š5¸…븗°ÄR'ž‚<¢7¤>‡u4&ðŽAD´Ð}Çb®ÆÉ Í‚Ž1kuR—U ÁLÂlJ°¬…"„X ZChÀ­¿Ø‹ëBâ¨T1»|Ï )g„µÈóì:!Wcé=L\‹Ù)Ä‹''öfm€}Óæ&(fMD‚a„±Åh5ÇmD`bó+bÚj¾/*á«`b@33!4I™Ç ›|b"ñ|“OCKÉb‘"Ý´Hmw¥íæmÒQø|æÙxøù¼… ÍQ)9¼˜O ¾/ÚŸ¦m'ZKösÖ‡ö|w÷|D-yñ}Xè«mùˆþo „mƒ%„˜˜‰V6KQžg&GÜØÈ…ªÏ„šÐHÏ+Î+Öê¹­ÃÇí(¿Â0Äb1.³–æÙ]€XLŠX‚ˆØ2»¤Xày‡N"ü¤-pNìÏ]Íç{f73H›N-%Iit"-a VJ@€¬9q‰ z}ø}‹¾­|Ô–³úÖ•<&æŸÕ°a¿€O&MЪ1tJ äж-†ª…5_¸–t  «ðm£˜%æ`¢¦Mš থ^[VSQáÆâ¥èj@žM–m ‚#Ôüi¦Dq¤ DÌ""l†ŒPo@@5¢H%Ã1zMß`ÝG¤¥ŠëÇ MgFRƒ&V€&2*7$ƒIxŽÕ]‹ºåU°–³]ÁºÞòœ*¥Í æ,a®ÖÛÄMÆÓÀ VŠ@R̃;4%ê¶n¥…ˆÀŠÙð‚2“,!Ž!%H€dCá'0³±¬‰„î-m'ìÎuÁJ0êLÆ’ž\$”ù)ia<’Mô£}¥¦‰ZÅ¡d8– -  RÄAdyvSo› æ¡yæÃnm|ä8¢Eô¼úb¢‰Ó3Ú±9AÕñR]iiÖ'³ÑÈõi3Û¥YHF:f )(Ö$IŠ•E–†Ö¬/‚ˆ¤Ф™O"@(¡ARÍꢂ „d-µ)NGs\B€VÆx F©úù³nÅ4ËI‹Fác" ANbØšÎ=k7ƒ0Å ‰™ VÜ)Bš÷’gßÄ× LZòX,żxå•ìâ1·&¥ †ÿŠyV¥2kKÒ¿Ô˜‡4g埔‚µ-ôª5ï'R zèºnì–Ä­Q7×+a¢-”®4Ø"uü™Œ{¯;¹¾dAı6wal‘¢ñ òsHýº1XÁR³~¸ùƒ=/b!ñ\DÃ7Yÿäºÿiþž|¬õqÄ‚½>áæú©íËÃÄ¥òaq’^ØO]Ðæ¾šÇ%´Ã,8{ÌŸ0i·|D¿Ñ¢ãÉfï™ë#:œw¨å#úB‹Í‚B@s¥ªü´¯€Zψ뺉¦º² ph!¦Ph˜±Àºn›'+¬×(aõœM?K˜cÐÒho›QÒ³>%f°®LÈ:ÑÊ‚b@©ÙŸeµ@õhÓNS ¨ÇÍÕŒèðFR.b‡ŠÇ”†r`Y°T¬kßM#2 9¢®ÝkfMB7¶è榙 +š %"y‘ –4ñ òx¾á“øê¡œØ…çÇÐ-°®ÑlØŸ±„I=gÅWC¤IÕàJL®ŠMDãÜÞÐbÃ-­ƒ [¤-h‚ÐÊŽb@ŽHÁJƒXƒOt¬DâI5f˜-¬¹KS#²ŽŸD]A“ba’Pš“Ä;™6ý'šS·–’aDzþœœc³sÜIM}È(š‹®¸j1K" °$@*‚ÖP`H†¤ŽÁ1 Àv½‹uJÑÔ¿ç¯ÞÉ(SÀŽ§Éº³a^”ÑS¸Ë9[‰®G"jÌŽ Ïu=$m׳>jŽsÂìË€RMÛ4" Û+4óc¥ Òi-‰ÏÊ µ^¦æ~G MÖL¢„§Ú˜t`V°œ†cÊÏâáæåÌbªç‡´QÕ=ÍRNÌóäeÙ†Áà°jÞ¤fV ep„´Ä³·’Ú,ƒµ €$6OSèF’ƒé‹$m¦¥­Hò"{-j9Ò ?jÒçÇÔˆm[2H”°-nwšcoZ¢ß¼è¨l`³ÿ×BD¿ËW+–—*—c/íT"Ø6ˆÖà» D„ºí<2æsÝØMuQWð—9ªp¤(šEÃzyÑDŸyç7¶wâÅ'÷ü ÁÙ=æù³.F!ºDÝ8)feé*Ê1b†vàÙ,9°šƒÉ Å“ç¯Î‹ŒÌ¡ #‡<͵E½uá¡Ø tÕxlBÕ-,&QÇĘÙ6$05VêhËÄÓ•v¡*@”Øä›ŽÀ¹¦vjØ¥„XhØFÐiãˆkRÇRÚ¶í ,çç¤5¥fœ¡b­ Q÷@¤ëŽº nLG^ ·ÈÏTOIp©b¨¸žÂÔ胶qnQ]÷¢F9ªZÖâX €ƒ:†ŠÅ`°Uäê*Ø$Ãù`®q#ÀDpÝ’-`-X×{E&z‡@éY>$cܯ-ÄœiK äfÔ;f(®dA1´jøt];ª/%ª­ÛÐØ™à8ଓ3 IDATFà¢e´ÆÿÏÞûôZ–mÙ]c̹ÖÚçœ{oDäû_å²S’|÷ Éð-ð AÃ`¹E‹†‘¥êT› $,Z ËÆ*!•„¡JX…Êz®—/ßËȸÎÙ{­9µÏñ2Ê/¡ªp•ódê¼|‘7OÜ8÷ìµçŸ1~#2Ô ú@Y`þøøxóúÕûŠ]/®.~`$â/syóûŸ^Ö…x_¾,Ùf{óìuAB‰1öMÝ>ü¾Îuæ@Ø lª@5õTpÿ¡ !…¬cÑ”.ïoø|—ÜpYá³½Ö|—÷‹ÍÙÏÌ?ÿè×"íyD$ áæ~‚óÅÈÊ‹®éå›ö¼à¾7Ù¯ÿÝãDÒEX»¿gOæKƒèüSïs¯ Í’°®7•\¾hç¿òk?9—­ıöòÔú¸úý­çÅcáÕ 8o½ÐXHid³d2SÉœŠå)wp>à|‹Ü_^&óÏäS¬÷¢Ö¸9Ýøì¿¬ï—uùL;²}£ö²]™/“ë~ÂxA) ‘†jCÄÕðgûB½^•sºöÜ3Gî“Èçi^Åæ¿0ÉÊ÷ œ^þ¢]ïIö‰݇w™ýãÇo@ú#J[}bðÿ©@ºOmhŠ}ýqŒOÔ4öñ¶lvD³“•¿þ×ÿú·;¢?…Ñ×2ÜteÍýâ^øƒšõ妦o¶·ü¶#úçññµŸñWÿ¿÷ïÿÇSû_þ×ßýïþ‡ÿùîÕwå|>Kƒ‚Ê`§vãm_-¾Èö%y>ŸŸ3£2§ÂYrØE6xÕHSFþ^+¢ëcž–V褸 x”’ (¥¯HEÄ{àou^_|?zæKmÛ˜/B{/w$+ MRDd¦»Ïa)fvç”W™˜Fß®Ãé—þñ<¶eŒÊDºóîÕíñ‡‡Ã¯ßüô鋟üÁOÎoŸnÊM:‡uIÒÍ ©$‘™)?êó[PD õüF½¼J)æŸèz±eÎï¹”2ÁŒóÿ>«K)yÍ$½öŠþ‚Ao¼N’¬„¿ëÏǤù<&·w’,D$&æãùáæöpYªeËñŸüÇÿáÛŸ½ý¿û÷~òÿ#W'ç¤ÖòúIȽ>üà¬q!/Ùü݉½ ƸÙô«kùNؾ󽇱þ˜—/-‹@[Â8Ð×±t{c–&€yhK£7˜a=YaîÞNmÈÕÔ©4ÂXÀxZ©¥7 ¢´bÆ·Í4 !Œˆƒ}ª†AíÒ ’ÓÄR€Bèx•›82;ÙÉÕ´Ûô ¤'Ê«aûù ÷þu[¢È˶(¸¶ŒW9¾Ož*í®½;Åoì|çZJIÝž“ÖôEHCŠd‚B™æ™ *ÅKõ+Æ=8jD ¤L&gæ,Ý,òJ,§i¡J9º/nžÞ=Ó•Õ¼z1Crÿ¸G*æ ³§m[¥-5hð"¢GôLkK§?mÛ›ýè7þíçæû?ø¯ÿöß^¥Ë¹c·°¡&Lr!˜½ÙKqÑGšˆ_Ôʆí5¾‘³]4¤ÓÁOÉÉë+DÈ(’…pZ1Q Cq* è¤Sn0PjK§ˆ ÃPî½Td…5ØB_’KÒ„DßZ®Z%ší'³xµ¾+,¥±0)"” \r%í5âÜ5Dè³z>u‘¾0™œF¬„æž•s÷K‰‚ AlÈéWÜ‘¹È=b8‚ójÒ0¡”JÖ5Ú.¢“ܽ8ͬ÷nf´"1b~÷L³‡5»ÐÀ.4°€ìá9ys<§a˜–£÷ƒWMùº BÐ.ÌxNøÐGc(ûpØdþÓÿü¯¥ðû·ÿþßÿ{Û¶µÖ"¢-åÅïx¡Ÿ¹‹…æfjßb]×=­Ñ(bžÉLµ‘&È-ÜÂÎ1÷jF &›Ýß\”9Æ«R*a …ÝÁŽyASBÈ=GWæíñ™ÌRä¾¹]k„Ì·ó6ZhS*JxÂàfÕXh²M`ªfVÉ•Úî襾½€×7ù—DÆëM/Æ”óÃûÑ,ÈåãÊ?k²÷Bñòf/{zâŸÙ ºÅ|¨Ùw˱×ÕÏŽ¾’àž7Y¸FöižúÇCû¶#úÓè”>AV˜gÊ/Ó =ßç¾áoümGôgæóà7~ã7þÎßù»¶Øõ·þ›¿ö7þ&pR–¥ꬕ#‡2]ꤲà©8êl±ÌŠ]Ôè!Ü k¢žƒ›^<ø¢Ú/üÜï.ÉQOË«æ!23¢ÏÿªµÖZ3°÷Þ{d&…í|yI+¥‘3ŽSf;‡zçyV÷ÌŒ¾IrçlŠ23¡T$¦gÂéè븪qø\†¹m[fC)¦føþ¾w÷/½þ·þ£÷ÇO?ýÝßù?ÿ¯ÿãÇÓ¨ÑÆý—Ìs8猑ɜ’‹ÁL†9öÒ&¶þ!zWd-¥*rörÏ™`$Ýý¹Ç{Ÿf¬µæõqícý}Vò®àWfF„dP!ýv/)CŸ¨0,‰pÇì…6Eô$žß½úìîÝO~ì þÂwï~ïÿíßù‡ÿàoýãýƒÿiÁ&›Ž‹éH¦oá#-Ó±Ûz¡Û—·8—Á1>ëøK›ÿ0Ú>ûîÛíüóþÙ¿r ÁÎ[?¾~5Wš³Âwe¦ú8˜-ôð-SvȆê—CÒããûÎ_«õõÑÆkÿê5ÿð‡þô¦fsïyóvåYƒ#0zFO YÒÓØcsW§ã›W¯–fÑ×qÛ\ÊÅzØú©€É¨ÝÐòâ[À’h] ½Ð\bÆÉýv)7µ½9Ø»ÖÕFhqk¥–j¡¦’’p‡Ùç_½{Rž#†™ÜCì1•Ow§¯¨Ïß}õoü•¿òŸýÍÿò×þò_þÑ_úWßÞ¿ë¬o¨, ¿î_F±x/@M^É.W§G~tã“ïÓÓ>›wе3.w?ÕD²Ul‘UtZukF78QË(ˆJ+Dus¢Ðz•în.®µ1ÆuÃá‚‹Gò kÉðž ÊÁ.ý‚˜­ŒKQ½Õ¥DO:Ü+„‹™ K­o/.¤³'Ò´ùÉ‚ôé¥k!)‹ Ìœ¶™€˜+ÄiO’?÷í·~ë·~ó7óñññplëºÞÞÞnÛ†Ù³í$9Îß1z73ç¼)îMã>Q2š™¦/ÊÌ2âMf•Â)/½pØmËÈÑÝFbÍLlÈ,>JY©sŒM¸Œ¸Dp+ÌÁ”Õ¼/ y +p2ŸQ ­ž(`ƒÙËÌn&…« @R/ÞP‘iu&uDza²¥Pi®_¶¤L@úX™/kþ‚€âvD㺠ú Ãy&ýBçÓÉÙêë˺nßhIõíã_5Ç¥G_«Ûùvãó/Âãü´Âl$zÐËq%î·q<ÜHÍŽh„úü DŽ‘dœå C*cŒ½¶ŽÝeëîFÑÁMbæ`25”„‚p! £B¢a+“àÆ)»ÙKÇ„5ûÁr1Ã÷Ü"Âd¥?ê…æóXWP0£Í0«2ûŠÄpšàŠ1¢¤F•ÝC M£w*IKK“í³OLíùYŽ'@Å äãÓ}žŸ¾øòééÎÿÛÿþÌ;»ûî~‹ÖŽÕDï:Çè ù¾Ÿ‘T’ f&}š/E ŠÌž Œþ\¥å¼±ì¢){lÛ†1¦ØÆJq÷Å<3s ‹®‘@ „ °˜’'£ïÎjÀh×1ç’ WŒ.…œ6äÈ<†gZe_p…²€¤sªÑâx{÷+ÛEEç/~úek8Ⱦ(‚Iw†fíÃ$ ½7% 'å1‡'×ÝbÜu|ÖÛwoÎÛ¶ž[œ‹õVQ½4V·‡§Ý'¶{ro®j;7´¸¡ÑŽ^­´¯„³åYZ$Á’¸½ Õ-Ɇ~ðºÔèá·’¨ lbWÄ@XÂ(Z )%§6= 9Q6,–Dz  =Ò¤“@"vÒCŽi<&+ùÞ,j¿sJ}쟂*Ož·Õ½ŒTõpËRîªnKÅM‰W<¼aÿŽ{x¼èÒapDˆ1Íl’HPc#ÓÝKœŽ6VÄ%FA1l›¢G xh/¨L%á]^ WpQÜV¿SúfÛ— {/ÀRüÔ–*F Ms)Á mfÝm(ZF‘º¤Dˆ#DÅA|usÛÏ—x»,Ë«Wo¿z{Eäi¾gå•1Y`ÎíÛn;™«VŠúÀÇÄ1QϦ)¸v2²_ÉNXÌjÄÝ”©)ËHêî¤ÒÝR‹¼sÖ>Ÿ»ãÉó±DWnÈn1 I<ÔV…–h™­Ë#L¯ýnLF™ªP©ƒùS¬LrÄ 8žFmx…” ePDÊñ´5X•Ê.ÔrŸ‘)ŠQ´Ø%nJ$]‰y@¥ÂÐi³E¤§ñzä&,€MÚ`d¨Lâóúp?ý™FÔÂÓrX–¬µF楉[êqŒuÛ`zô0ú–ñÜÕÌzÈHr@!#ͽSÏ¡•©]×57¯Y(]Ò°xYï+µü!ŽVœoNoN§“ÞÜ—e9ŸÏ½¯côç/|žÍ‘¤ù¹×yߌdL·‰^H(”—,zºÃMŸ„HÙuâ𬛤@ÍÊ’ ˜˜‰9 Å+ù`@È:©Œ¿œj.ù<ñïpÞ_-9_ó=q®R¹ òûÕK/¤°¯Ûðy( rÿHfõ2 ¤RkùÿeGôç9ß󛼟ŸŠìó—\ÍNÓ©'þÅŠó“ï³é}?Ÿú¹|Ó¯ÿöñÿîÑ‹ÖÁÓj„ãö»Ù‘¢ôŒ€¥€%eÊœfE`Œ! ¡˜Õâ UEãÜǶ•¹Oˆ.I/,îî̵ÃèÕ®b+3˜%|¤¯Ë"iÛ6¥œ>¦±ÃÜJ5‘L¥ûì@’¢¼ a§›WOëjÂr::øx^SÃZ«æsʆF†"0NºX%%cZüôÓŸ>š–R}\Æ ƒúv¹i­ì ŸšE"ä$™Žy3s~cö¨~!yð:Äì­Ô7wß¹<œ7kÉ‹á\–b­¦¸ô"V3™"F§çB´TQS%PÅ ™GÉë6²³`inÅíÀr¤Ûè®8Š·­kuò1“ëfŒ®™ÓÜÅLy±ÌÇd«YÆ+Ç]kG¯5˜©ÍXi9FP«‚™€èa£@(9¹Ã³ "å^šÒd4npAtk% ÇuÃ~¤/¦/îß~Qôù=ŽåöxÓ¬aáÛŠ±öëˆ`ÈeHD3ºe+V9Å-ÛÑï˶ GVÑfÛ ÷Ú/}ަ¨lžüIòXÎR56+6òÝv~@ÿ̯½xg··í@c½”¼¹YÆè9z¬¡Ršµå)õv]ϧòóm{ÊéÔN7ÆÓÊnùô}»5ë÷͈ŒR}Ä}®+hÛ©Y™É3”)ã¾ð‘æå¾s:§é=ÛÁ©"ÈH#Š`d…‘rê@ûž•EzþJ"-Ó¡6?·£—Åܹm÷ëÆã!Ô„;°xYJ)Ž\›y²Ëê³e1Kq}wš†y¡ÑËR¨O_ÙÛË鮎1¬øëï|÷˲¨Äy}íþ)Ë‚7ßyµ>®qÙnïZ£ŽO—5i¨Ç¶)n^cë—§³™ŸN§õé2‰vVÍ 9¢÷mËÝaÐ,¥H¤ Ù“`äpâPK-¥Sét·#ÎÎ+%<ÅõÌuK³×p­ãòðómäÍ¡þð;ŸŒŸ=ž+Ò«/°uÄì"šÌR‡º0RC=Ñ•N ²½c΂ «tÁ̆²÷>Ál¥d(·¡“a\!w¤ÏéW¦¬ÖˆˆHb— HÚî>r»øJ 3H±,õr9—RƈÃá777mi_~ùåÍá¸,‹Óú¶înÆL•â$C1F ¥—rº9ÇÊDz”ÌøÉ—?û7ÿê_ýƒúãw÷Û¶Ý¿ýêõÝ›×õ`çΧ±òñrÿøxûæ®÷þª1¶Ïnn._¾{U‹çVŠ/‡ZšC]ë…‘Íì–ËqmoΑÖÊ9ôÓÇûŽ<Þœ•G×¼dn1”£˜Ã-Xœ^h$(…rˆ&û¨RˆAT0(7öLéÒvòü~½éœÛ*’“-¾÷ì”qb”NA)Î¥˜• É$a¥Ù7˜ÌÊ<û@)SˆéÐÚ%×gf–W-T(„d†Výª‘Ú£ßvD ]ø€}Š9ÛýT]úµXo$”™‚”»X¢Ð9ÙŒïi“¸Þï3Ð)âëÉ ™ÒÑ¿`» O¼æ_¿%ì#¾¶S•‹{¥í¯ëŸHÊ͈oކ™¹ÿÀ¼¸5ÖJ¨(ÓÓi ES–M‘á tˉ’"4$$é“A·A4¤4³˜åûäx™ÉKEÊ¡„| š™»{9R#339†ŠÂT„PY ‡Jq“ 8`Vån ÜC÷OÛ:è®Þ1nƒfBœ4sßó–FŽIÏf8eR°’……48­+7ê‰w‰%1çuµ–VUµaíkd’pH@ #×Q¨^ÝaœÁI4”¹pGHÑÇ茜ÍÄœ5iŠü¯cÊ´?‡¦+“4X RBÒçŒjFÚ̬ ÀPrHe0ÉL“ò ý:#™šSØ(XŸÖ ¹1‹ä +ÙûÖhîµTÐ0ú9ÇÊ73!SB±oeWó'ºF2 ygSÝ«1s[ÕÏèFŸ©—† ÌÀIåW§®D“9z†l V懒#ÎÙWõmwï †ù¾ãIÆfFÑFì¬õ åœySHeÄ 2œB¹,¼º&˜®< °¤š©ÂF”´­çaˆÉê"æœX%!¥÷V‚s† ’©´=G yïÍÆB,•­Ü|çxúlÔ; E×ùiS[ײ"ó TjK圔î 1Ó¼>2â¼^æjxã#£[&{Œ!DÌÅ$›íiSý,ÛéL(4Ê`lŒ’pàŒç‹¶ó˜z¹ÜúÃx\Î¥2c ÀÙÊÐèÌtÈÔ‹À1F^bí[/é”·Ì’Óð=^ä˜<ãÜy‰0AhlîT¦/ñê´¿¦¸£$’OÔQ(7ÍÑ»YàNMT„ÃuŒ­F+˜½–œé2+И5QcPš¹ÛšÜ NB#¨õæxl&gæH¨È  ´2½ó£íLáôWv<¶Ë¦ÞÇx|wÞÖóÆØÔ€o–ÃÓyÞ-Oç!Ã9¶8²W+§iÓï/›ù䓉­À ­q@":E¥hÙ˜á§÷—,(†â¨fF’‚™™zmc›$ü¶ØrÛÚíÑ0 Ë¡è=»,]Fti Ø{=KBöâè6L¤†*g_¹SŒ¥2¯ØŽƒ[‘R»ëÿäY æ–®ÙüÌzy©¸¤Fîñ¡sÁ5ÿœ–»k"±'<0İRš›™uA­µír‘)úP¡1ƺÛcë2chDf:-3/—K)ÅÝ{Œ¡4³ê¥ÝÖ_ùõâ˜ëèãç·oþõ_[¿ßüg?»ÿêݸIÖšf¶¸/Éžei¯_!lTf-r×ë¥ÜÝojëëvh¥-µª±²™úZ¥›ô7~\.çËH‹m£dv»Œ¾ÒHc%/`Ö8Yø2Ì;½òÜ—½%³UlÆb^½Tf3HØ…æF'‹±h®+)$…2 LDdzf~ßÏ\sÓKwù#ù¼…NaLú $‡‡‚Édšìëž‘´çäî½úxÞ£H¿*‡„Ció¶™S_=÷M6‡)óW>ü /µ,|HNß[h7š$éHNæLQŸ™éâdÊÏ=UA|}©î•î7åšÿ™©hùGéã>µ{y }µ\¹NsW¼çëeâØ·?Ç?O™`D‘W¤¬'gÅD˜—[qª¯ÊAJ6’ ÁZ}@É–•“*#}gíc§»1íÙ{:;˜J¥jåbfЈ̀ÇêNÐAG"¶‘*Õ>ã³sh²V­øLê˜ååH)‰Ã­s2áV—R¼–BÆÃÓ}ˆF§MÓRÌëî#“¶¼ï.ÁÕ¯´´ÄFÈQ ÓËHÚÆa¹¡«ÆyãÆš–}µíÝb`$ÈQ–B—í™Nsw’ FhäÄzçÎ {o0¢¦ gVMÚ¹Ÿ’ÍGW*²:Ó–ý]dˆTï@#¡çkýj[‚»¹$9sÛ =Þ†tÂÌŠPÝ–Ì‘Y¬XA…aĶ娤$œny•|K(>§õ×9YX (Žf¼Iéoœ?Z¯Ùã).OZ;œø/Q¤ÈÅÃ4ÇuóÕš‰T1”p¢F6F",,/;1. …’Ä‚~0 ·QpöÈÄ£bp%ÚŒAÄ.‰á‰Ü¡  .œŒ¢ŠVÌÓÈÑS{És ¬%ù¾Fº†ï„8È”Y)$Šp Ü:nµ’”7­¼öú ¶D¤2Gp}‹@Žœª©—ðÂêZŠ-Åk¡!úÈìpJfò¤Œ¢Fô¼bíóùV’téȃàLY¦À <‰¹m¹Ëh¬„¼„–ð L´Ì ÜÒÎ݉Z€!ÃàºùÚ-0)‰¤9 ðP˜Eåì`E ‰E˜1KWLL;¶«Õh³,»Jã–«}¨…¨`1+D-f4ÊL´0÷B¨E0ËâVhF™Q–*ŽæÕ‰ ÁK)CqBŠ1ІMt.D#­XV*傽 J›¦L‹á¤‹½¤Ù¶ùØ=×aà |Åú½ƒ½>Ýüà;ÛãÃåü°Òú›§%}ýêÒWô>S¸1€4´B<âäµYÍU „Á:rä©4 ™cÄ3Ö@Ãñ„p”ÉÜ©@”xý괄ݤÆ—-$}9ŽvIwÁyfLÈËH@FÛ G:¬Ð‹”¡Üœ©æN1C)Ç4 %L¹L©œv÷Þ|ŒHÒrGžHÒ¤”Œ˜q¤™ ÷2) M âL( e™‹»A1ú¬ò[µÃí×’#Fv¶ºõ®¯_ݾ}û6E dÆ. ΀„47‡ƒ"U›—Óáá³%Nyºg{÷Y)w?¸ûÑ­¿»ÿñÿööpZNŸ}ÿ§We‡Ï¿xüâm<Ù›å„Çõ´âé«wc{ª@¶¾ÅÐj)^i£ÛQüvÉúz9¾rn<~6Ž÷ýòý•µ vãY8C«ø¨<;»SdRÃábó­ îˆÂrD®Ä!sÚäªe3«³u Ì”!y"¨Jæõ¥_ƒ¸f«›sö!×Ráêð(R9g}ùœgõñߘ9ÞÏ„EìÌt%47î¤ÄTNL>" â}—!™6EóýÅé‹~!NP{þØLÕ9cH®S ¨|¯ßãÌ/Rq·o+Ñ?…ɧÔeñ ̵ßáGÛ!>§V¿x©ç—ÍOtDŸú}¿UÇýsøðQΖ{²=µ³C%Ò YÜ«•RÖqqw™Ì,¤ˆ ÀÃ23c$B/B©»æiLÜ*IK0J5‡Hæ>ï EÊ€lP…dÓn4mšÊP‚°BóR!)ÙSâD1… JºÁ«—¹_¡² [ÛavbdŽy¬fŽ-Õk]†ÆIËtŽ9R.å¦Ýidï];'916d ÄTG5’R;K²÷ÙBKôC×)åÙkBÔã1xVl6ê‰ÓÄÑÈÛd˜ÙØV˜sª%s¸AdNÖÒûœ}½žîó ~‰•Ø­ÒU%´_q3ý:¹ ©ßkb'òn2²3S&wïNÿ¾¶FHr*•œØ£;d‰…œ…å3Ü2…~M”Ê™:’S]áïOƒœJ 3L¨Tƒ/zÞs86Ö‡uû™Î?§Þ†A:J'˜–¥ öI‰²üÔ¾ b2G!¥•Ž^}5Dì1:žò›’t) *6\Alê™A$Œ.ƒ%ÍrÞX÷óp†n8Ó,éNOšÓ'Ä‚2 Y£™ öÙcP/Óhv@+‘@1{J#wá¥Í]¹ˆ7Àã®b9Ý–{^î™+°%5d™t«K˧KÎT˜ÜA¢„¦B¦˜-ËrsZn6榊‘ÉÄtC=l²µ|?ÿSš5 1Nf £Ãb —©Â IDATV½˜¬”Úb 5,í°X ÆÚÏÜc¥PМe1_èÛ¹‡cê##TiÖêeë´ÔT\f £N˜y¢ ëFtÅ’-Q¯M‘_ÝA.C%s›Šål™êd*ì3¬f5wâ}[Å9È6M(X±™3š:“B©^îbDŒ€“ÖÇ®ŠÚ¬.Õ̲zºD­—•ÕMÒ°‚.5»ÁØC5Q ƒÙሆXq{Zê›Ó»¶m¶=öû?¼|õóíìűàÍrj§ª‡mÅ#>zíƒ!öÌÜ1Æthr5N ÜR€,„'ç³4eéÊÄu‘¥ˆ)Õ²|²RosŠþxwDŸÚ±¼¨_TûläúÆu€(Ä×òþ¿–æ àY„õ ޾‘ºüµñ§òùÑà3M»¸«šµ0+ÕrX†0w>¦4@«ÌB‚V&°{Qd¹o$|Ï@µB `±Û·•H¥ fVŠ@ÊÌʤ¤4Öjª SéLh†óÓ#H‡£zs21D hR:ź,Õk]"b‡d{:ú-ؼc)“1àS„î°ˆÐ<…Š£ÅËr\|}—±¡ ¸O¸)¶3JCM8q,­+Œè‘°iò%y'|&¼I{ã8Je´•v¯|иßðåžxX€:º°]6eSm­äØ(I³øC‚if¸jÜu%ÏVsŒ1ÙÏzhÍ®éëö£ÁçÞé½Ê9¯B$èW©='fæžC’fs¤8yÄ6%yâiæ(‹YfaÕ¬8‡º”CaHÛCx†”Òô!Ú¼ñ›kkÚšjÏ6à+þH}Õ·7}îøÜpoHó&KÓpN¹™|§©€HT¯S„–æØ©ƒPʪ<ÁdŠ“˜Íx%§‘LCR«â£Ó–è"D»"!ô[cfÆKv%1˜+¡sÄcö3¢„3ËNeöÌiëÚ® "èýñ~M´™ Û|NŽ0é™GÃÉq¬Å–²üÎ÷ʇŽušè7¬›[Ï rfÃL£³ÃˆÌ4/t·j† Bd¨\Às2’E¨'Ó ”=ØòB`Âù|vš+=!¨—Œ< G ³QŠ–ʈècsSV¢ÐéeXœí<`&,Kõ1úp%–3îsÀ[ ¨ÐLû˜o]Ѥ°æ„®œuvÛ1 Ï5:‘LMXA!LYÀ:qsz¦¯Î„«D¹¶§3Ë Ò€ÝFÅœ—‹Û¬#=Aö4W2¹¥‚a; 89Œ—j„‹m.Œm˜X½––ó.ìc¬kzA9,Öêe{xÛ{_Ÿ>ŠGàx»„¥˜9¸/³·[<¶,>|Œ£×*E×ù¬ƒe;0*ìXʩŕùd“¤°Oöo*Š÷_|™ØŠ£åÒÌ#ÕsËf²E›9TâÈAa#®˜ïQ ëT5t‡;œîiqé.@»XµJ)(ÀŽrä1ØynÅ}d Ɉyäg&B ½ˆƒÓ˜Ân´ÇH¥å øé=ÆF…Ñ3c»9,ei64nO§7§Ãá×~í/¾{÷nΤÜÉ9x’Ì8¡©™]ˆˆþîÝ[]€§ê'×vΟ=þáö{÷77ÇÓ¡‘7?Ížoò“Àg_5ØåÝ»:ݯßèp"–Ów>·/û}xA;=Žä: åe[¨c±[/Iœ~øÝEÖ/ëùþÉÏys<zíõ ¾èçÔýèïF/ÑÕðD›BZ hR.¬-A *˜A iÊ€µÌžtªi4ãBkÀ+U(©¦]Ãj’QÁ«4Àñ ²‡™í³p*;v6P$ðADǵ>üÚú“»ðñÅöfÞ¹j–Ù"O Ò’6ëŽ_ÒG”ÜwPøáÜUúFIåúŸÊ*ôò5ù> ʧv Ÿª°ÿø|5>+ìoº#úäûÿâëŸ;%|Ÿ?øK¬nÌþdwDßRÚÿ˜1¹ÌfŽR¬Yq[Fuá BÄ´-7;šÙ•àLè}ÃL:Ì$]ñÍfV&­R3@0¦~ Ó,„}|9%Ü×cÞϵˆ8 {¸›l‡Fé:CÚƒÿ r¥µr¹ŒÈ!‰ð]dN°÷J›ªsgq cíMM‰TƒËܽ•>.ÛxÈÜÌÝjLT¢%?œ–åT½ù—§5³÷Õ3Z÷×¾üJ³Ñ~@|—öÊØ’0®ˆû_fÿ²¯_Ÿ ÿ„xl°ìІÈtº—Z}šTr¢þ˜`NÔç@¡ù“Û¯ˆí©J“¦>^õ®z1ûàÄÑ¥{@çüáÎU¡bòº÷ÛÒn)•^` 2iHyMõÞBÍÉ"úlÜhªµÀMƒ)õùÁ"‘ŒÌC8gÃ3Ó]P§Šò¸ Ü +ktÄÃvy$žˆ‹a&‡Š5(‡%Qa ½Nt²¢ÒË«6&vqPfP¥‘nPÑ8ÀnPdMkÆ ³41zÆÌá–×{7 ’ä†äUeü<ô4£÷tKã†1c{ˆñDl†êÊ1•³G›±@³)²™šú|'Žgl4¯E8ˆ1ÃÆ¨ŽƒP̲`õô7·¼ÛÊF d‰²-5vÊ51ÛÒÝJ©µ.Õ›YƸdŠ˾R `…Éj^‘e ‚&/DȤÁàD8ÜX -#×è T€¥‚5Åèz\·³ä6ÙT胃D;ÝX®1¶-•™ž(Lw…å0¡i8“¢Ño‚Gðµ‰^7õýçƒw÷ê¬0£\iÁ¥x%‹Á,i`1˜YÆl&«Ab¦”“;umŽzs†Í ¶ß­æP@‚͸]Ð!óºþi¶åèˆýi@–£q˜}bŠ…ùpðX£¯¬ÔƒÔQÍÊútî},û%¿³=•yârÁ»ŠÓq9ÜÞÅ¥Ÿ°”1rø·ÁT(r•Âó‰ëÁÝ›-VóÖ¼¢è‡f Ï%—Œ¦…XæfÝf Œ=sšÆ}]Zô ‚Ÿ´šîÏe-~ãŽèå¯Àš3Ç×å½aáÿð©Þ§ˆ Ÿì|>Ñ ÿ2¬¼oÿß??31€Äs¾g"2ä¥\ Ê2˜rßjͦ•0ÀÙ´ìgʵ͑@ÈS‚f(bç¦N-¦Í$ŠDSzk%S€gÜêÔmZ…æ5c´4‡Ñ¡”À€Ù#”*àÈÊÜÌJñþð´µ$¡mÃèèê,Ê0ú±Ý¼ºQ³s?ŒËú„í}D«‘J¸l±vÓêRʱXUhvQÙ`c[³_]ÿÊ©üZßÛúg=^é¾?’,Ýó¸e¾&îÇr‡SýY=u>GŒÄ)ÆØ €4Í@Ó¯¾£e‡å•÷êœäÌÆ€m'¤qs˜MˆM`Ƽ#Ï!ö³jn.æ‚"‰cõWÃȘÖåù¼Ó¤ šLiHÂi˜ŽŒ±ioƒ÷ËSþ7A½šSt"´/çÌÏh³ØÇLU6èÔñÝîß—ÿ¨×›ÇxÄV2\0¢‹¼ .®Œéôo°ƒ•“ÕÅh#™n݆F#‘…21™Š°‰´2Z²ÊoY^±–ì.Õ„hX‰ŽQ´Îtwá¤Ã\¢Óg‡!)=gkmÍJi-2/±>nãBŒŠNlÂ*Åô%\»ü}Ö]»…wrèAAÆy*r2 fBîLn1 ‹[-¦‚ÍÁÛƒB±"xµVQ\fŠØ4¦ ”™£˜0+fÅ­šrÃaÑŠT_C)¤àÌ«Ïk³$@Ø©¶6?0©ÅÊM]Žn‰ms“‡ÔÑ×ð@®±õn2˜§‚I¥Éè•Þ“ 2 55”Ñ ½dÏØêàv’¿I?‰w@CÌá €µ¼š»]ãVEšP”%÷¼B«´B¿ä¸†—þ?ì½m$É•¬gvŽ{DdfUuÏ É]iWp¥ïúÿæ~’..vINwUefD¸Ÿcúà‘Õ=äKAX\Ad¢‘]]êªÎ—ðóböX`>$…½ñ¨ØÆgŽw†÷Ã9ffŠ/?Î5£¹ù°Ôj¶Ú1öå)‚F7ÑÀnÂÜÌçºÔâòËi¿ [337KA­wdîm¿Ãçdl¨.Fê=l½× vŽ(Èä”ùþºf´Ò oûtŠ’æ+­ 8õèØrŸbzž¦Kw¿5Ûc²ødEa½'SÆA·hÓL&ILDÆÖ[P»£rmeCÙPZX‹’@EýTZÊRhʵs02kú!ió·‘ 2©¬SÊKÈ:d2§±coFYB!tc7 ¢;îµ[(ØÐn&æ©Z-±n[‹^k}Zæx½àê‘“Û$ëÍRHd"m˜?¡ºy)È$±LSõ"v¤L°Z–Zºòi™·ÞöõN÷êöÇßÿ¾,ËXÝ»Ñ.¤Ã„E7ø°zT¼‰®Ä]¥”ßL?bSï{(ëdÑQäÅe›7…’×è+®ÿõö‡bø×é³ß¶Ÿ´´ uEÚN´P(Í‘ÅÜ|¶i2{ûòûg·§ZŸç:U¯[#YèóÞKD!Uêežž'ût)/Óé©«´©§¹ÜueÜÂ6åf¶ÃvÏM(À ¶jwXƵJsjB¬‰Y˜šh“±N?¬>Æ:6Φñ^œpSšèXÃ&t8·î×ëCá±CTd;LÚ8 ù(#;(gþ²Úä/ˆR/lÅc e:!Fž\LÁ2¸QM”¤„©õQ· %þÒŠ¡ÿ'«æþVÒßr<þ†ûÿPêö'ÿrþRó};ûÍöv8ß+îZä÷ÑuÒ¹@‚Í1¿'‰Aå÷äuñ¹÷(_{|wûøøm™ùÈÀ8S¹ü1=ŽûÒ÷ÿÎßòxþãö[‰ÜÍ¡@fo­mý3tãù”Ú€fÅæ2±ŒU·µ5ì!P€%<‘ =3¥Cv04jãl™Ê4ø*RK'4°Dö°©‹(h…dfdvøM BÏÄ<×áXí±ªw9H÷j}ß…H˜9 ¢‡ÜÕe2&‡.YJ‡Wó~:Íó\Ì{õ¶ßªS)•í¶ºMç§ËËËKºö¯­ßïýv䤨d0uÝ+ܹ\^>ŸåJĶï{¿·Ø{ûİeù_ ÿÅúsn—¦SV2{ñ‰~vþèñÓiúÉ—©ØE÷ÿ–ÚvY®¹í›ZçC;E8lœ¦Þà ÂÍ üX­·ûM²õØÐÒ«‘6êº1rpgâ[Ô÷Hnõ#ɇ<\Ð#Hj(ñ #¦qìv §›\fd1#¡îìcen´¨™ ¦k¾Õ¡®L¡'ÜÆ1©ÃÐ†Ì í’z2šêÌB­õ„X=QÀª0Å(S4p¢Ÿ¬VÂ,Ó[fP ¤D SBÊÀ•-Õ!§÷ÉKe:º‹ž¸ )2cؽÀ‡\¨AL8á’z)Ós©6Õ{l{3t"ŠEf’€27S6,Àòð}àÐ|ÈîJq€¨È…:9k¡M¸/XÏúcÜ^÷m‹|ÊeFq“˜ÑïÑ1´LÀƒz+m}Ÿ"÷´&óŽ S‹N•Ù;ö÷Ž=^O#gÐŽ‡"Gé2W¯"zëè >%æéÔ÷Üö¶­Wù¼‚,0Ÿh[ ö.{ª‡õ,£Û QÇy`þ°ö›Ÿ€€¹ d6hˆÃQPD;^”‚J!³GK¨æP€9­d{´C"`!dd#Éâ@ûÈ7o«q2Mcqìo‘ÂJÙ{f‹>öTdFkñj*x]oTDa*–'ÇeÑLœçˆµ÷nHdDÛãÚ™x^J°w‘à¶K@-÷¶ï…Æ+¼É¶uŸvûº™üë‚+$m<\²¿Z‹s §øË¢þÈ Mƒ6>>ƒG8òøÂA}S-ô èAù8Å?þgçý)8 ²¤™2™†I‹Ç¾m¤ØbdÙÒ„„ÁÆ/ñ]Z˜©>P4Á‚·Q¬@e¸÷†œÝB NR¹Rê§.ÒF!•ƒ’4ìît&#­Z¬÷Ö±›-¶8¶•….ëƒMÉD/‡px-=q p‘GG$š™?bÝD½ÒÉ>âêÆp†­ŠUtÁ‘3‰æƒ;ÿËü-`PÃc|lGG>V¦ýWcfÿ¢ªð?½wÖÿ·^¹Rï}^&3Z°¯(ó¾¿ÁÛ`k´­Y›„’`ß7.Å[oývE™Ê4÷uæ—}íPYæ‹Ò·{Cr^ê¶½N³»•Q à T"çËÒZ‹ìbÂ:YXæY{*÷½73+¥RJ§ËévÛÚúŽ;Ï˲´Ö¶ë«Me\=ÔA8§‹R××퇗O‘jm/Å´=äVµo›"k¡ U{î{_-‘eªt¬mÏ-s ìŽ&l&˜N;. §† p)ÓÉ9Gߢ°¬o·Þn8dàÉðÏ1ÿï§Ïÿål¿ÕûùË6朗¬FÍ•ýí)q:—Ó§ùé_.ûùúuþy« høãâ´,?)2O‰2³Lµ=° P=_ZìÙ{BÕ‹› ­ Šeß[43¦¥`æe9ÏêÖ3zF¤àfŇb¬‘H7w}°ÞwØh~ —™?0^£˜6§>>8Ût*¥DfÛï{Åé uôctöŽ=Ð]Q†¸€N€ž€Üê°µ wÔ˜ÿϦrksA™§ðú¥«µöÚ·7Æ=‘ÀìFš!häì ÒJÉĽ¯òeFá¾cÝ[(_7£pHbÐ, 7´fÈ‚ŠvUœ³_¬T/p_S7åÞ§4/ŠÐ9ÖmdCîc(¥#=ûžÌ^è¿«“+ïÛÖÔ:#*;ÐÀ.D·£­ª,7qGøX•ÅáT’GpÜ‘³åE¸§¢ËK]~{~ÿ)ÞN[~^êäçÖrÃÔ¬tF‹íÞzˆ©º»¡¥z³Ì6ÍöÏÿòÓRèPÛ3ºU<½þüåiOk"ê€ f‰^÷{4Ýà‰"ª°É ÞÜ̇ЭÐëÓ¾ÄýþoÛý€aÒžænµo›32Ò2iò€“ÚZömδZ­…šÁK™…vï—óÉÒÊT±µÿ—°cß<›u ì wøfXû®„yíÊû¾7¤Ñš€Ü2nHFÃä(NtJgj1sWDë ŒÍä¥á7ß×xÝj,(ÎÅ&«^,¥ûÖDÃlPËi)"®{osÍâµ#*ÐR‚x‚šðRÿhÛ×¶¿þ¡{-Ëeºoow¬š S±½…Ïåž©-{ÅÖ°þ¼O†Ü³íè+ê[µïïÓD,w4â½£ ÏOçÝâýv/·â²ûµý{üüã|ªd`ðc…ë‚"¯__{±Ÿ^>ûõëtžjÈi9·žï¯ï}ïÕ/ˆûöúªeËêEɸíJÃå¥Fµ[nYD&²'[øŽÒ0%*À‰·MKAgnȼEúÌ»!œXXênº·"0üî±eõˆ‡)¨,ÖÐ÷v»nûkF«°ûÙ/§S½µûÚZ6;æeÙ“_Ö¾-€ÍðŠºðü|ž>F5DÛ×{Éü<Ÿk)ë¶ÅÖ\€Õ}Ý`œJí{ëëzªs¬û„" Á˜ƒuEvªVj™Šˆ{Ûhò'¯¥l¼÷Ìô¤´¯oµÖ h6»Q0­ù›úy_o÷ŸW³éõÔžžž×}ßÌ8«Kù=nׯèÌy)§ó§½½ß¯ï:-e~º+Ñû<×Ï¿ýñòtÚ¯÷ÛÏ_¸Þ.µ>ÏËÿò<½¯÷ûÚ› ̯À ¸gÏ:íæ×ÀëÞÖˆ ½‘›°V©QÖ½lÄâSÜÛv‹8Yž@(è¸fT¡9àTKé™&1B‰23º!Ò(4üÄcŒ®B’°·x,lyš+5¼L’â;ìÐÈÓ€þÌFû×\<´à9¼tb>çñ™ùÿ$ŠÔ1"~”ƒ(‘Ôt–¿?ò}lcŽ{}HÐÇçÇLk°ÕÑ‚Žt_ÒhÈŒTèˆ]DkýÀîâXGŽÑUªeM(Lçp6éÌPŽe‘ y $ÒàCùÚ•…p/LuܕŌfõqvëp’9&I¥)ë1'íU÷Ò_c]»°`MXpõ&È™È<pÇoÉôÅUz_ Úo qö¢–ÈÌ Á 7€Q¬G» >ØJÔѺ©&áHCAÎ]3Zö\€b؈{Àn÷ù”éÂá3Ò”.˜9f÷EÈ!/3uIJKù#îsL¯~ÿ'¸QwãkéiHÀ2k‡ÛȪBêBGvÊÙ™N³rQ‡ñ3„½À.V¹Ì¾«–ÊÙâtwe!öÑöT¯%ü\/¿ýÜgöX7‹å¼ôŒýºí¯7Ü5§ÏÝÙBÅ»™õÝ`h~YÕ ExB_ÈÙáÁZ}Ç^ºGŠh{zÍ&ÀŽŒÈÖÑ£€‹2›ÁiKñ­‡Àxs IDAT:¦åTTp‹ÛÛ«F•á#n¦Dë)Ãl%]i{ñÞûAþÄ1Ý‘{!¥H¦¤!ɫɲ³I#€ ÅŒ4‘2¸\)Érì‚2ÛkG§Ei‰Ÿo·«m%ÓBOó<ŠrAJÝÌeúù~ÓÓe¾<Õ²ÔiÙ‹o÷u6 ·Øž»/gŸüïëþv]þ·Ó4½ÐN§)RýP¯åM™Ù£,䥖ݽƒ\…Uº!ß#ß‘·„»‡J<‡ Àº)§Œ‰%­²„ew°•ææ3£«¬™Ž4£FbІ†Õñ÷ö¢ƒ—0ØÛÆ‘&Äü6òÍÉ7o­~Á?ø‹,åoñ2ú¶²øÅ°[¿p%<4Yü†c©UݿǎèQ™ÿõ=[?ávìø†>7À2eC&aÔ(l îÈ,)×8Þ |<ARˆh†sj¸9ôÑ•e%dŒ'¹;à^­doÇÏç.·Ã¿nÿÀ ÚÉÐ1\¦CŒPäã8ï9¶GÇê²”arõÖG*!L?¼þJ9>Dw‡g‘úŸ™¾ABþôe¿ŠÊû«JÄ¿«–è@ƒfušXæu'z¯çÅ~äøXFÉpIÓäMw ÝYª“†èˆÆ©ÃÙ„]HZ4/£Y F¦¬øØxdÊû:Ô&Å1qçƒ ýîRRfÎ:×ã æR0CKÐaÇPF²@¦bÛ÷Žò$zïež"{D˜§WÒLböhok+¶õ¶m[t­·Ö=çéG2{ñc7Òˆ(®©ß[ßš™€E¼”åÓ)sâ'ÃeŠ©…{Zûóè½Ý÷x}Ã{ȧÓâu.„Êy¹ø“ï/íz ü~‹ýŽîèådf½·ìAó#Û´q•(…ƪ­¤ƒ—D€Œˆï§b¤Ý ¿_:dÔ/†dcŒe;óx‰´áÒ7(¿Ü=©ŒCˆg/hƒÄÁRŠEíØ` ÷Ñ÷|rÐÈèÃ`š6Ú£á¾M•šì#e^C¸GºŸ• TäØ5Š1=Ä}«^Ätw‰q»$Œí ¤\F Ò‘äô!Ù} Šd™YÌ9M‘Ù{*bÄÒöžnpÄ(³Ž€¡GHè†>ÒIšÁ”¥ fkcfž½ç·CÃ/ôͽ2BW0°\j|G¥å®XÛ¾îíë×v›@°D= ÷ÃΛ̞Ù‡îÝàÙ¾”ްV!c»]ñžÚ{k`g pãѲŽ!òi#{å˜Æñc+õèA£ñ|Z~¸Ø_¶‚âhPÓ ,vÃÌØzÿx®?$$c˜¢C ›€ µS²…Y3ß!tÀ•…¶"Ö1v”:rú8¡Œ£{wóZf D ±d,ɹÁ „™å°6REjô™œBwB>:$Ðl fnêÃ4U¢Z çyU†¹—޽÷áȵ©²·êõeyjµ|y¿Ú ‘–@‡¹æiš&S¶}ÝmÖB>r“¼xãˆÊÒÇ…}rx­¬x*j´žÔž¥ÚÂéý}å$ÊMj‡¡²÷n³Ë¡ ˜—`C%žÎ¿ýyaô-ö³¯(ÉÅgl6Õ¤û¾¯Ê‚ à‚0–³í»[ÿÃõý=z^ßë2ÛÉ·³‡ÊÏ_ïëkþÓât³ `yž‚Ñ+ÿé{Þ{ô5lW\µ¾·¶6Ïî³—¡DJÀD*qï˜{–Â"w´-Q·XÐlÛ©Rœ™Ö3£µ‰ºÔzï12š¼z9ÍáÚûvoÛ`„¦väHfJ37ÃcÀ!!óÐ^ K&ì;¯‹$Õ¹JÒA6 %œ'¢gF„à°º—¢ÃpÓs©grEÖ©–©Dä­í[´Ål.媾'*£E,ôjòjÏ?ýx>-z_÷x‹} HÍ*¯}ß®_nqÿt9ÿx¹Ìçi³¼÷-÷}±RËThˆÞ{œÌjaÍÞi©žæ]Ù27àKï·ÌãRœ&Þí¸*¨A9x¢\#| Î$Y@KV‡R%ªTŒ&°…逃N“2¤B8ñ÷÷ü;ü?A ;&†2ØÀýÄùqQr´o 9>vòü…Ú¿ZH~d{J¿p£˜Yþè:îí±)ù;ìˆðKÕÖŸÛ…>ôÉ ­Ã‰¬_|¡ ™ d­e0‘C(“+‡„>˜™Ý¡ÂÐ÷ÊoWBÅ€ŽÉ.‡ÝFDGî¢cD;FlcUe†©Ò½dd T¼|šÉŒˆuͶ™™ö¾ j5ÌlÜ! é”)òd×ÃÝÿh‡_\‘°ÁoŠ£øûK±°ùí•Éü›ÅbÿØ=®Ö‡y^™‰!:*^çÉþų7 ®I¡·ÖQJ9ø˜Ð¦©T72 ˜ËhòV½&Ž)>è#,âP˜$ ÁN2Å$eƒ~*e ôrѶmµÖRŠ23Æ¢‰‰i>6]1\”¡Läà™˜";†º@&Zk‰#"i¼k¢wt¡V8Ç&d`‹T+ í¿.@E:ÑpßÖ}ß§Q¥â\êS)Ÿ§þŒ8çfÑÔ7…êÈîÈ­aݱ6”Z÷,[zÏÛÛî½–RüTö—½M· š#¯)ó#E!øáÛ>’4jd?†/Ãôœ‡¿·!5'ËÐÙèÝËh2>Xtʳ› þØÑbÙCxý@ŒÆÙLA‘¦ •íC/f=ÊA€z˜”@ú¸ž$™´|œOw{,@”N!˜ÄD”Çœ-¡ƒGÞH㠉ѼzR¦ÀH~+ÆÁ,d-5”ã%â`@Ù¸ÈZšÊXSÐJ¦f$#Í‚hÊ–êÊ z¤U+¥˜2*F+¾Æf’ V¢Á¢õZFhÐC”²g$¹@®Y)Åp5ihò;uðñ(‘†|·q^à2Ùó„Ë2]^¦åÓ¬ç2?ùrJr©ÞûÞ÷Øs_{[7OHõ{’(ÈbeÊzžF¯4L½íý†7å:P&JZêyh̬ìðøÚ i1r’(zïÙ;Jî›_ÊóççÅq/í¾v¨ •VÀrÐÙ{j‹ˆŒ†á'úžñ¡²s„Ê?jÐ_8ÿ½Ðq¯‘jðÑä÷Æaêu77‚è(ó.õT޽­F>€_ÊÆc0ê=xÚÞFwL –“õкª'Šaª˜§z:]Üëíz¿ßÓ Î—é_þõwËRH¾½½½~]÷=”òøÒê\¦©¢Ç^3J¡OþéÓ§a«V¨µØoûýºíkLå#­ˆ8r¨>Ø Ãv ŒÃ+¿_ýõGÿ ,üÕ[<†°-cm;¸Ãë4Õˆ.¦'}oÑ›)|H.Ñ÷–~`b¿·s”ÂP*C!S]ÑOO—–ìÈÜ‘™¢-KÉ̈ÆÃÑË=là“stEHÅx–³ïfvÌÂ3B¡c9S±Žé(–™f‡GAHx@·Ü7L¥Öê…=[ï™V«™ŸŒ…®RJLÖ®·Q‘²Ô‹¸{«yG4庯–І’8³¾ÔÓ§/çu¯jØ#L ‡sÅŒŒäMú®è÷[ìoܧítÙm.õÓ§—ß_Vü|GºI©8æ„ß”o™ÃÊïBZ¶ç˜R)•B¹(,e²ZÌÊG„+¥D2cHJ]Ã$ÿ(}GÑ!¼N¥¡à€Ì‘4w§³Ç&VÂÉÂQ² a‚Ðæ@æXM¥Žp(¥€eFí@A‹£Ç)PENÆÊÃ'™RS6 ƒëÞîŽfì™;r %¤Ì7J˜™¿Þ¶vx#29l¯^6æ`‘M^&Ã$+Ù‹K©gìÑwõ62Íœ–™š™™ŸmVvïId&ùÌçZJ™úXíEÈjTWmÔ@ãTNWÇŠÆOá˜~>b²s@mÀ ˜Ñµ¡5Í,Ø«²`À©úéebÞ×Þ¢÷ÞãÞ·[[¯zFõÌ‘ªsãœ6»* lGR¤ËÌÂã'T¶Œ&ʃô#Säð˜O´ «¤&a#÷ØcÇÞúžX{´”IÈ<×: wZ*Híʵ÷¬òØ5fÀ1Æ"IÈæklˆýŽm³¸;ö*HVg¹#™BW¦ÕS ¨LÞûà€¡ Ží¶à¥V£õ¦¾A}r+^Šûx« ÆuJÀThŒG ÍÈï¤ÊtlPyªX¦˜|ϸZ^ËþÎ0Ãyî…¶—l@MhÃ\[Þÿûí4×çóÙO}]/,2#áhÚ#öž­N$È,#Q*¤Ìˆˆ Œ „MÆiιöûž‚-Ð[Fî¶§ÈS™«O­Ed¶=†B¥ºWÍsg¶Ì­µ¯ý¾›fk"Ÿ!A²Am¯žSM‹•yê×ÝÕ€éÐRËËË2y¶·=ˆ×›Ú*]^Ï—eùayÙžò¿¾ËW,Ï—Ó§g½íow\î(ŽBºËUî}ŽÊ”iðS|uÊ–ˆÝKa©I®mß÷ Ð À¥`S2ûR ®6S—)&ߨ;Çròˆh*oB.¢w6&Ô»±ˆýÈ´¤±üî¾9ºŸcËZÌlo;L‡›ßPÏÈ.Â?X7¤15ò¯R‰.© ¡:aŠlb ‚UªiIðßþÏÿöÛÓe]Ò.>Ï‘5ð¥È»´úýýËmçûóùtBµù¼o}ß·ˆ0³©Ôjæ‰s™|Û·m/æ¥ä8¾O†â¸;î´'Ã|#_a«™wïæ i0FÝÑ”Ö8‘>¦(‚‘«8jW—ù@¨ &½À&ÀÈJ4²2+Xáe mÌ;Iú÷‰!9Ðá¢`>¨xL€à$­ùùÇåßo„þdSÄï¸eü³¿u—¤¿ÃŽèŸ–¿²jû³vhˆNÞwå>“îÌÑ9ÔJðI¡°À£†ï!ƒ;k­VÂ+{„²ÿîó“Q)µÖö}_›"Àù3Ìqy9_žŸaz¿ß¶msði¹Ô2_NOæõv½¾½¿O•——ùù“?:O¥ž¯e:½½½ß׫n÷ûùi™çyžk°í ‰6/eY¦|v¯Õ«±´¦·Ÿßÿýßÿðúå­ße ?Lr߃ P¤ \²G`’ôí!•ýíK¡¿ñEÿ.ýÿì6<ˆdfï=½§w Rve?†ø>lgˆA`³±Ï+ÅËœ½÷AðŠlÈ@ ´æåéØaæ˜ÀGJ9VR rÂDÁÓŠQèrÜ­õêVªÉ<| 5íƒòL÷êN3kÛfF3“¬ç373g¦y±Z«9™iI'-[¤E~ˆvöa "sŸçê‰)Rý–^Jë-PvÌä3ýs™Z4ßÓcŒÇá4–ê>™o_ïmÝFÏ¿Ôi¶)£åÖñåmÏä _ž~¸Ü<_ÿýÊਫ਼ÝÌŒî€C-dꑼøP }(o‘16gC/eînî#Ÿ.3‘#aóZå1ͤ!ŒÓwzpm?ôÙ<ì.CD’¹Ì5PÜ©ÛDKX £7ÒݪÌa1®m=3©E¸;G³*UÂÁJ›`f`¦Z¨¥vi§äf!ä :€Ìî–‘ÎJ—éC¬G6Șöv œÚPèYeÎôYî.¸%ؤ-r¾C*^¼~£ÆKH)–¥: fL–U˜Ì—Rk©A ª1:ØtؾÒæcÉ¢_˜NØì˜þ£t8Ì_Hñ— *ÙF(io£Áîˆ&¯Î^\é*Å­š&Ú¼sU¡™!M2¥«Ì^Ÿ¼#ÒŠÞ¶iÏ*^XàÚ A h=­':†,Ñx‰™»óÅJmÍdeÉ V­ÎÓ_°~¹¾]Õcí•X¦êª.Á€HqLÜ•¼ ”î 1Ò`RÏ 0S’`^£U`C´Ä^Ìߎšt¯ê"lÉ€Œ5 ‘i²#“=-ÃFR´Ð]Å0MLÁœŠ™`CÚpXt3‡4{çмS0Qf@-éÊmß×ÌWîy.Ûbî…Õ`™€=7Ýn*‹l[»ú6Ó7éõíΙ(®â²h‡4cqf"zF„²G"šPD7D¡OS+Tf+´P*"Ñ;z ¶¢vjßzk9—4ÁLÝB*Z¶{´¼õý ,¥Ebï›o© ÃóÅŽ­Å\¼Gª«)[bŒû´Ií¿f¶ÍÞ£š{?§ŸÎ=‹íµgÅy™Ü{SìÓñ­3 (žæ2¢àòâádÒ:¬9£í™€¢ä0Ä*êà5î=3;jTœ’ê½o-0±ôé –‘ûÕcª>_¹Ü öv½íÛ­GÏV¤ì1^óÅ ùP‰ê{&†{\‰9¸N£îr"¤h=qtDCã-Åœô±%õ¸F“A¥;4¢!‡‚ä4Ò•i y-ciš<4¨©ºgÏ;öˆµ-p@s)§€PàÜœï©}o_¿~}¿¿O*ÿtþ)ÙZDK•ñ3ªt9Ÿm¯§ÐT¬še“hévÒ~KìÆ·qÑò.²kª…¬[eÖs²ÛCTHP­‘t³jtÓÀÑÖ4(§dŽD°Àfb’&¡ˆ,uÈUÛñQGŽçâÒ9dˆN‘ž8ˆGÊø û€FÕã;F×qhžÿ_”šå¥=þþ¾Usú“Gó›wèã&™ƒ5ÄÑèfd7/n– Õ‚Ë™õeî /nI„²÷»ÐGI*GV>f¥J>ºîoÐwKÊ_…[ü?° ùßÙKs(¤u¨Eœî‘Ú{sãÀih4Úܽ¬ZiË$iµîk™m:¼¦¤€ëýnÅabqE&ˆIeB‘}ˆ<™d1=Xs@`KáB&@t1‰]ÀPgц–kPeÁ 3"‡lÌœ•3L:#wr"ÀÂZkªƒ%ÓÜ}÷@(g™|bkk‹äðwOÄËŒš—ß\ʧ‚³X$Zƒ&ï>yuqßwDó4ÍË\–ÜJëö3"¶¶¦?_~8]X®'B1Oóö¾gos]Ü|ÛZªÃ ô òð©+z|è›%Á J$E²ÎCâ5:½ˆ|t6vˆ7Ìh: \Òåçcº?ÎÖA§$<9ü"‡ÆòÍ_‰ˆL$ìÀs`ôCL¥BdJŽKTŽy+dæÇâc¬pL(dAV¤{æžØ2›r3 ø¡É@êî!iŒ¦LÌêÖCÒGýê³F#¹ö‘xsˆô™ tEÕ”«b‡`ƒäèèŠÌT’YN‹N*æËÈß)Ýû¶g\ÕïÑvª:Ì¿¢¾8vw0òçQ^%ÉâeÀå8T©BüôÄŸžìùóÓüyñ¦|áôä§É~¿o͇ÖRŒf©YT¦f->—é2Ù„RÝöû®-æäI¶÷0xg4©§Zf 0½E8)%•¡#°“¦ÉÍ›ES5XX¦iâ3¿^ûûz¿JE˜NçY-¬§ATxÌbàD6ŠÕÓìØ¨=Z¦{îŒ@Êa~3óÌì†8^w‰Ò%µ»b°}¶ÖD39Œ=3#…PÛö7º…ˬíRõðIePKîåÑ 9P‰ÅìT‹jÆ(ú?øÐ¤J¡YÆ[׆X[Ez湪Ԟ²Žºxµ\z¿µ¡hpêzë÷èmvÑ{Ö®Ê(C2J:£íÊ«Âð]e„.¸ÆnTñ^ý]=×n™èÃ8˜±i…Lû„U&°§[¯´°}í­{f-^X¨2ùšÊÌ .})Ë’n÷6©l×{ß°!cØ¥Ö—`ïhBÜ÷Í‘ö’¿ûá¢RýiªµžXÔãúúe[ûT¬•tgÞ÷·kÏŸ/ÿýí&<`l‹/uörJ¾¦õÌ¿‰A†Ü$†–$³ïûšDfWAÌj&° ¨ˆ ±¸ß–¡Þ˜1×édõ[9¸ a¢ÛT'ãž™Ùa &ÚË;€ùÒX>R°ê…dxÐøÏ™}Ж?Þï”1R~ Ü9È[£ŽW¡!3ôÃÜyˆ¾òèrË^—³eFìÜ[ÇÈ'£O‘ À—K/j†÷}}½Þêô\i:ŸÙ#²rÒÉ–Aiv>OÓd Hó]qKœÀ:Ü”…8y¹ïÉ{¦2‹”rGÞ>† ãÿ"Á@¡ó0À`ãØ©ˆ9+(äLLÈMœ¥9U¥Æ˜@¥*dDÅcæÑÿŒ• ˆö0_޽¶”{O ? NC È#aä—÷Â3ó!Ÿû`;ÿЧˆ¡Aú†TÃEcહ?k‡> ²‚©A\{Þ½V*3P|þÝË¿ùôÓÿü»µ­ëõýz½^oØ×­7eâ|±—§úÓO—OO/’ÞÞ ?\;â½}­ÏŸ—ÏϧÓéeútZÛžÈóËó[YêÓ§'¹âÔ⽡i.¶¯mç½Ì,';-&t›÷§ž¤~½½Ýõ‹ÏsR:§õ÷íȢϮ¾›¥“ñ2ù¶µÛõë¾EÛ±mq¿m½ïÓ¹X-EÛ¶mÛmk mCêÑã(AQ!WY…CëGŽd¤GÀô*¦ ¿Ðýãöq+¥8‡?­ªÖ}Sì»ÜˆˆÈÞZ¦ÔaFƒ<ÃG„X-$¦èÍ̇Yq¸qdhÊv}Å2»OA9’!?®+Ààë[Kû­´×°YH™È€BBî£#Rˆ^LmIƨԇšþ[ÔÚzAøTzß·ý>ü£#IÖHRˆH`²SÉ­·°¥)2·Þÿ7{oÖ#I’e黈¨ª-î±dUWuÍþÿ?ÃWÈAïU™ánfª*r>ˆZdTW58†9C4ã!ˆL¸»™©È½çœï¨ãºèßÔå?,Óo'_¼cGÜ @´ Ç ÎËemä-9”jI°v7ˆÂ´(©‹òE0q•x7xòÄBØ•£™+Oh°‹†’‡­#A<¾ëR«ˆ )ÒÌ,#ÆÍÞ{ÆXiìȤñQÕï¦D4Œ!L$FÓvFÄÁÐe*œ’ß®,$Í!£FyZürØö,ñÜèƹŸÁ y6œ h O¢*!<î<RHND¤d ”2Þæ‘Á„LCX€e•í±··z*ÄÖ1˜µ²Ô`ÍLîmoˆ•²Eö¡öHIQ7{6ß°œˆKù~›x¼ %%%lK„X2±g¨¯mõÙZkòóÖÞ|ãyVBrEDì{ßoëú–WTf@$ÙŽñµ$O|ú0_‹RP½A3 dÎB53’<ÐýI$awË$ÍxêmÇgGFþÁŸ æáb%2 ož] ¤º#}ß®ZŒ!)„X $ÅÓöt2Ä÷¾gÖR©u7X‡Ë®EšßÁC¸äH„gtïáI66$»G ’šÛ7/èª ¡R¦,±KbfœçËLGæ± š3á,yFkÏgž:8\Ϫ]‹4†Õ9ßÌ…ABÝœ2@•‹¤9fZ÷àH‘’ Õ¼'O'n«E ;œ3• 2>œûfÁI¬„÷ðŒN†sº”‚ÒÝ·¶k€PFá¡<¤1|†ñê™ÀT›w‰©V sïI9´Ä=‹´°ÞÓs/€"•z†Mä ÔZ 1»SÒBL¹ÏY•zóÌ" äôøio²e¥RÊÎâû¶¿7ÇRŠg†bïØ+wšéÃõeºž[öý±öû>õ,Æ–âàgþb¦g ‚G)Å–=.ˆ‚uB'T¢ sßRu’ÖÜ:Ú£Õù^'>iµùÄA‰§"e"’n><“œ£üð+ÀÇk§g³h rªÕ‘HŽ#±² l¹âYAªÒ»?Ÿ¿Dã´ÌÌd÷ÆÊ ÊðÊ"G+9{dŽAìÈÞ¿Z©çZ–i:•Iö½·~ó––n™4ÏóÇ«Nô¸qo¼ IDATßwúùnï/zYæ*sæÞˆTøÇ÷¯´ï Ó©–Lï0/„%Qƒ&F!fШ¯ÀF\.éÌ‚9ñn|0ßÙð  ˆ ˆÄŠ, ØÓ5¸2aJ®@ËèD5Ò>h8ÃhÉ\G1.0#Óƒx,x™F C:!óys|J7ÿ}ûûbÌÿF[Ýð/|Oß~Fšƒ~×ÜøNò[ ÓwrÕó¤Ç/&_Á"u¼º¿¶ˆdÈ©G EDfŠfæD˜ƒBÔEG… dÆ2óíéèÔ¥@ Ÿ~·üçÿå÷/Ÿ/¿ùŸûývãÇC÷V£›Y ·ß|ú,¢}ß|ü])Óù‡«,/ñÇ­§½ÅWÚùó…ëuªÓ$YtªàÜn÷¶ÚÖ——yù4åù⻵÷õôq!¢Öîyú0γ–üøé¼·n*çszuãò¶—Rá'>#íþè¶¹*93:_ÛÿõËß}ýñëíÝÜq:Ÿ…sË>W)•„¨”ù7åe]×/_¾|y÷‘-¯ŒR&JîÍûn»EÑÝ!eUJß­›U4ÑÍâ™Jæ±4§m4;3ÿæKÿï ¸`{33”Ây´Á€ˆDŠŠJ¹}Cøüúº­{C™ìÑ ÷FHAÄc7"~¹~^׽ߨ¨– ÒafäA¬¬Ø·]K)“šÙj3³»ËÐþÕ✀e7¿7L¥žgUîD}QDZï`ž¦©÷i§óùñxEÑB0¯ËRk½ÝÞ¦¢Ä)7óÝœIŠ”R<¢TÙúní!UÀ›Jñ0T©²”Rc÷Ýv—" × —,KŸú½Ý§SÉt—ZI©7[ÿxóÅN—EUçË⥨«„®k_Ûf{C[‘„Síb_úÏå£Ôß_ÛÛ?ß[• `ïMD bmWFº÷ÛSŽ™Ã D,…™“$uuöæ TD9™Ã:ZÃ|:-ñF‚ ÃS7TéÁW!’¢"hÛVêRæE…{÷Þ}h?¥–pŽÙcì!ŽÎ‡2E·"ºm+ÜKEkmß÷$1ËXŠ22<ã6;nùáäA ZtQ¹L'X<Ìî}{óXÃwQSa®<ˆȃg;jÜ"…ˆ‘ÖºK”±¬u¯•ñ|’ˆ –g‚&¥NÌ ¦iš‰äávë{Ëàª1O)zÌ1™œ™fFNö-Fc ˜/çûnÃ,”ϨµvÏŒîîc„ð²3ç1c0ô¾g7Te%FyhÆë„×EêuÎëôXâö?­·?Þó´ðÉ…&¢ì­§å,(\¼§yï#ŽÀ M­amë“ÛíË»üÑ/ÄJ…êýþÞT! §Å­£äƒØÃy<[1òA¢f6ÔZóJ‘Ì|»=Ö½ïª ÒûÞÜúY5žALUª"‰’"&¦“Ô»/SI¡µ™@ÕbcTáyoåúSëüQX„ÈÌG¦éŽõ ~e´æ"F°7­Ó£…ªZf†#;æ.W¼Î *^§IzïøxAîøíËbïë%åóùåöÇ/X="¤° w‡¤Š7ž”Ƴ–i†æÑû^EÖ­µÝ‰HSöô°œ@¡õíë>kÆ—ÛŽ‚é|j­Ybž˜çrO»¹w‹$p`Qt‰B=Dب'8¨q§EïkvúE0)ûÝœÍàº`«ðÉ»âršL åãù§ø)$Ò­Nòr½ÄDÙÑ™£ª¾ž/wÜi¦úéñùãâSL¢¡üåß}šïmÃ/¥?z»ãáþhBTŠ ‹™CsCk­ Lд £f™Ñ"YËn |ýùKýx–Bó›Ï âk¢Y¾¯ýËÍÜ( X3¡…÷Íl&©@Ø3R('¾û¦çº·dÖët½ýôåë[¼ž“€×Ë´¥Aøÿüßÿxþ¡4N–Âð¤ ÷û „QØ\´ÇX ë@ë2#:Qò¤!Üéaqœ‚Ç-Y´F¦Ò褱m¢ž"ý ‰°3¿#™L̢¦@Šp†‡éPÜÍüŽðBú’qJº›>O¯×zOŸÊüåí§¯ûzz)¿ÿÛÏÿ¹¿}Ýþþ²ý_þñ§;noŸ?¾~z}QÌlttS¢·Ÿ÷íò\^^ÄÓ­-<ˆŽ\FuF$S¾ï&Ì'Ñ.mÔæ2/ólm/*DäHë1d€i¸„†Û~¤­˜@¹úè9¦`1BË÷âq.ea ðpP"Â}”ä1óp$+"RU­âÈÞ{wÏV"â±E}/øP«øû—騮2áð%â››üPŠ0Ò”K@UÍ,< Öî8dÒ†û¯¡ýå8ô?–å…ïßßþðɸH`œ)æžv”•;˜Á:átÅéº|ø8NuŠ~}¯Ÿ‹œú­ý¸Ù}‹[×FâzΚˆàŸ÷BckOÖÖ½ïnÐÉÑ¿ÜÿôKÕ2Ïó}½[tª^pÃm¿ßÖ-:®…Ïõ$"f`Kݲ”Q­­ëvo{*¡º >|eÛö@k­¨ªB`Öˆ‹ŒÛ¿[D«˜Y¶ï¡äéaØånä>jGM>.~aù$x¡˜-x_Û¾Ý×i!ªÆanîƒÙz·›T±ð¤LA §è˜ ,û#ß•š>;.ŒÍ P‘¢2àŽ€~ dÅð㡈¦ÖºýL‚e\D¸€JIÕáëø–ÝQDTåïÒã©ÎK)™ÙöάDRTÍÜz'ጡî:0§pz `iD÷Ẉ øå˜~³%e2ƒ%sðs ¡`˜ý¼…7¢4á&l ÇX['êqŒÂèAn­œ•Dˆeø3ÿdxt3X§1ú¿Ü³e»·{ÝcF€ƒ»âឬˆ®¥ræï‚„È3™²gî èþ¤cÂÜ2C„5ÍÌï°cžnÔlu 0¼ÖNót&õÜѱ¤à¶£P¢mìÖAŒôG¢V™Î¼T{ù„×Z'ªŸÎ—9¼ÝnÜ:UÌ'òmÎÑ ¥0ÆÛƒNGIJÉ*Þ{Ft„ç,TÊT¦G8zzXZt §-xB †Èe8j²À0¥7D'˜BzwdÃfÍ ˆ TÙîh‘=‘ šT„ÓÌ[@…¹˜w ‘t-,kNĽ÷¢Þº:é\ù<•ìham3ƒ+d–©TÜc·vë ?k Ú·Æx™R¡Æ‹ b/åŶÞ[l˜À(W 2Ÿ )œ'BFÂÃæIé™ILËûÏ·x»ýü?Îóôr¾¼LÓdâ)N¶~z"Ò‘NF0B ËÌ…w„+Ëi–-¶óùc½œ|Ýï?Ýö·²° ¾îÝUÛjiGT$)›ù°"ee*ª3HR"Ä3ÆÔ‰äb PbPq@ž‘à >–áÉy܉G Ü#¿u£<ûHgnÜÂ…9ÿ:Žfù–8ÝãïǰT>™h9XlÖ)öì¾%òJuC˜Ò#íÖû\êÿå?}þÛÿô¿Ýÿ×5¾>î·7ëÑ·™yF‘DLSåp÷¸y¬ûNâ^"£ÛîÑ`­Z^T'ÑÚû=ãÑ£2B5ˆzä½Û'Кéá–á<Ã)÷}ñÈD9£_Ìà„EH@LPP!`$ d;à’’£3P@A#zKécC•IGì42}ØÙƬ‚?gdψ{Þ$é/rÿ}ŽFÜô;»Ê÷óÕÁÚýÕÆ¡oÑ·kðø–¾ÿ×_k(úžp„LVJ!Šˆð%Š@™1¿`y¥åe¹|z9_/ež"sY–:qx«Ÿ—j¹mxÛèÞdMqU.U˜5áq#k]¦œ´N: “~º¼¼ï½N‹n÷m³MI§iÒYbõ2—:+ mm5ÛUQ*£…E÷´ˆ!V•­”ä{À2Ž÷T©üú¡ŠÉ¶ÒÒ5rW¡Ó]>}ø‡¯tŽØ»›y€X§Zi*Æ•µ0Ïéh÷–áÛ½ƒÛùå<Ÿ¦×ë‹}ÿzûñ§Ÿ¹œNó4Ýî÷ÛÛ}ï>¶Ïa£Ðã(>¤'½);Ø_ÿ»›ˆƒ™ Ìœ°ÃMöØŒc9'-··ö€.Ö;´Œ^éAE°k§iªSfÚÞÌ@TFôÜ2™¡ÊÌç ‰X%,1X[áL–GùxŒëbò¨¨ñ€]鑿ˆpkÁ’æÉ0“±„3kR—ðФBZóo°Ž{–<8à!"¤(33E8N‘ áÙLdzZH X.Š+ÑÖœ'F2Ô§˜ŠóÖ:šk3÷­÷‹ ©!(»Œ*Á,ÁÀ8²E¾$®„Þ ©°ÁVAø0Åᛢ‡ ˃3qü€ò_ÔÎç† ÝL*ªŽD|ÞŽ”£çðÍ4ɵ”ÞÝÌTyª )gîÑ{ 6sþb£Ñ7ŠQË3Èw£Wœ˜9‡{Ò3†¢‚''(@ I‘‚ ¨¨Pw7·=}Ü„v¢ÎìD£ò‘<î£8PÐ’QH*¡B ‘~›­G%ÍóaDÌ”f‚k¢æÌÊR"¥…w„e4 gtD€s¼# "=ºE rØ#%)2t³òN±º5Àˆ}Ø¢Ÿ=QωȇôéHÂÆM‚6ܱ,ã$ Õ¼pž”úÄû${µVµV¢ÝvB")2Ü]ƒ kt7kÙ÷h”`f- 2ï°È݃×PÃÄ¥’ÂÓö pœ8=#bu|s@͈ÜCîî€Ç÷cp¦7óG_+Çr>%Qèiè”â}„°€fTfÖ;BŸkX"r°Ù ˆ€™4Ì;Ñš±‡í &3:'´k•B81í–¯>l÷e:Ñí–x …Áœî`Ƽ”ùEÊõñù7Ë…¤½½u7®Ó2•išòê®Ô@L– Ïì1ÂÖḋ}.=…ÉæðZ@ˆ8É©D d³°Èð§»6ÀáFÀ(bô£Ä€IЫãAÙ9&¢€ Ò'D€+01W5'7ïT¸ž'‰Ö‚öµ»N…Y‚£]À/³_9J¶µ7ì31”Ó”§²!¦R —¤àBTØ$z÷y©{³&àŠ¼à&X B¨/À„u2rgÁÊ}>©ž—{ðƒi§@„²h•zZä:Yß óãåR+§%‚$H’ŽzG‚àóžMèš%¶ Íý9VfÔ#¤KÕ= gõ·ýáBó\]è¾E©¼õ­VÒ×e¿‡'¨#Íàœk 7p…–âLÂ2:(’  §H#BDÏ„!!îB–9g:ÈYŒ¸RLàBi™š)4ºŒ €$(‰I’(Žì0j™Ã)8ë­Á­¥§}î—&Á,ñçÅüó¡è/ûˆ"BˆHä©‚àÓ1FýjÑ_Ù…ÿåŸþÕ?üï?ýµ´¿ªzôÁVûVFÉŒi1–Wüö×~ÿñôq)§ŠBuZÖ¶2» bšQgËð~¿;o¦;9iLA:zá«Ã!“gëfp™$©ÑŒp7±Ô,¥”Bv>/"œm_÷ý!™ó\Ïó¢^¬å¾ïÊyZæ/ç—×yšyo7ˆšhç0#"*Riáýí½R m²øË4_O×Ó¼0ëßÿýß›{w8ž4¹ž ûÞîÛW{ô¶¢÷¯eÒžqkKÔö¾¶›E$@eM%—Óea© •×—×Ëë—·¹T|½ÝmwË_–é¿,\èFféß½cÀcèBˆq-v ¬§“íIË4MûÚdš®½J0ˆîÙšžm‡˜%3˜™ª{8šýèý½­÷ý½b¦‰/"VJòíÞ€Àιe´ Ja–{ü”,!NST——e™Îáxùá“»ßö;-HÂ|B½ &?œý½ï A­¯–Ø 2Sp¶ìî餹\1ŸÀ%S6ç·`Píei逮Óåz&²¨.ûzwövzÉ0÷cP>¬ùOÇÔÿÿ+=r4n›{7OŽ"b½ßn7ïæÌ…ˆÜíz™)‡YÑÆ&›I¸2ÓÈ~‰†ì9® #UOtÈáKÀ(GGƒ7ŽÎÎÑtBü Yf J˜§…yƦ*ÚDj‘Μi"$*Ý’Í:Ò£03|@8¡|P’Ç# :æäÌT- / „‹ˆÀÁÉðmŰ ~RúAêoŠ| B#´„{’Ø`¯ž91'Êx;zQ0QjXxÝ *…‚£÷î'Ã%ðRð`¬Çý= `‚"]šN<\ë£Ýá9ž5S­cô2ü aeº0×ae„$cH1€:Ï'þŒÈÌ3hÔ­öîxö nÅgµtä€[¸ˆRÞÒøxÆqõ?d¨ü.Ï9‚°B)HeVf%îÙ÷ô=}§l,]Èž4f˜áèzz»’T’”Ht4¤µa¥<*Æí$(%91…Iðè‘ÜÝ 4ŒŽ#«áœGMîØ­ðÀœ‡óh9.h2<ˆ;å˜+°¸îÌEÍô‰´ÌŒÑ´C2<2D(!5óèè î”" ÑIË$üHï™÷h£ˆT‡V-š5·Ý™@E‰Y#¦¥¼¼œ.'-ž¹kX®+ aË´×ð‰k Ë4pE¤';ŒÜ)`‚ÅžLÄ‚d"РE2I­sY"Ì#1T$ ò-½rvJ"’“g*Óî¸GŒEÊÁ4F$çðQî¥Â³Ó{Ãé3º¡úëÀ„ù‚óGúøÂ/'¤~[?ý©¦à²„Hüü†mL TI—ÈÒYbžõZНÓ*»ž‹ŠÊ¾bÏþأθr]wxÐê9(‘S¥üÐj€#«Ï Ží–^Æm™<ã`KlT 2¤èh°ÒR¤–d6AR¡ZëœÐô3´g¯‰Jh‚`)è{IX:l%‹J¥N"s—SaHôJYU0sŠú¶o DC F¨D aþñ±¾½¡®?ôO3g•ÇD?ÿd¼¾‚^—Ë<çû;×»ºÇ<©…Ÿ>.—2a·íþøz·ú‘U£ÆÞ÷÷Õö½†Íûœ¨2)KZ7·­<$pÂAìËLÌaáŽîØÉ ¡0 @3Úám±ÊT@Ê×ëǟ׷½5(Ìq{‹èŒu:”EDBÒPd‘zßÞÞ·îuæúéÃO_ßûvºžÆt£  óL\ A c[‘Èeƒ’H†J0<Ì£â4ÌmGRh”o…›°ìŒÁ‡BúwÞ*ɤû¶´¥á2ð%3  ˆøùI<0±™j˜E„“3JDšIfZ[A))a¥7¿Û¶÷/>ïÛ[³æ„€†q#7sÉTdˆ§&bE.[­Ö•džXeá9kZŸ…ORG'5"EZî"·@#u’NX¡vÈF±R4 ¢%F'Ÿ?5–D `x‹ìQIŽšpÀÁÁOÜa_Œ'†–èè*Lü¹ø—8 OÉä bìàþbtöï•"m ™™’£`Fu|x.¹~hÄ7wÜ·áïT˜ä ±º?C. U”z¬–¯æ¢&j/?œ^>ÖåBY{øcÏÛí¾v·ZµŠ"-;coms£R§Re–2©.²,K™Êõú²>öÖ"Öµ7µâ—/ I§\Â÷ð»=¶‡m»ÝwUV•˼ÜûþXÛö؉¥Î2sâézÞÃ(Ès'ß¹ö0k‘ïÞÍHÛòÂÓ<['s{—•ûº®ßF _mþÿÆD4xnciß-áÒØúÚûí}oÂU ½5·&|dl8%Eæ"ãéIÄL2>qn€ã:ê½gþ¢ÜÁ’L sŒ¡Èì`5¶PËZËèi0³p €DDff¸ÛpŒy†Îç¥õmÔ ! ɪÕy}VEŒùmçÀp÷üný?0oÖ||¡”ìi¡;$Qëó’¹DLÉ…j™¬¨Çòfž-#€”4— DG· Jêƒüá·‘ÞÓÂÉèJËß\}]ÚºâA¸‘Ç8‚Nø4ÊkA !8Åùù¦Žô ~Š`îNR‘Ç·îºáú€„˜#‚(ýˆÞÑsÿu ÚnD’àÈðÖñ|*DIæaÓöÒ=­gh°ÉS¤1³Ì𒣿¨$xt€"•È™%™q|ë s”%¹‡'@IPâñ¶nÖÌ’)‰œ8@IO»yŒ®Ðƒé+?pöǑȔLÉà§ÏŸÂõ0 IDATãXÍ· Ð'lžá„øÃà¢y]èp* &æ©ÐeÖI)-{C´‘ ´GKp¢XK³ˆÀH·%«0¨žêt*çÓ$êÑ}‘ÒæÔ5ÁÉn„0 O˜G€‚2˜"¸mzÐÁ «z«ÐᲄeTóètt ªC>ÿr¦»PôoÈZ„’Jš25ct±âèìNƒÌ#ûþˆh»Ýækí¹cÁyÂç‚íB¦¸^r®¸Þ§Skѯ¯Ð¢Zf§›Ó„Ó\TÈ“ìË×örÍóçÏ?x9ÝçÂT¥–ÜRßW»LUe²[w™mch8¢g…QîXª¦¹÷lÍ °Ö´„dŒq¼ƒl€¨÷¤ÁKtsI-\h’’ðT®*'ÈB1o1樢€ ˜H9ªÞîoMÅ3zOï(L½òÌ“@eëý}ßÍöL±Ü”J­u[÷¶£Öè¼Y ­ßV¼o@8Í:V·Ÿ ç?üp¥E§eê¾æ×èíþeÍ·Ÿ|¯&I¯:}øpõü§ÛT¦ À{7K¤ºh¿¼žËRçsɽÝ×ǽ=6Û±¾C:ª¨Þ›¹qï£Åç¹UIìžDP¢@jÆð­Ò½7'ÿÝo?PIžkñ¾?,“0U(ðòÛËùrýéO?¾ßßêR’éçÇv)º ú cœ*iÛÚ“ÃǃH@Eµj9³”LÊÞÜ1´\ÎìÉ=!ÄÝ=‰8ÇhÂßn1„÷QGsR {2I™‚cœ1Öq>ž%¿ #4éX1%’ lÈ L”"¬,  's¢` JrÉÌ´€*«;sÌ!ÍÒÂLÌÊD7·Æ‘šÄ rO·ëT²·hV2.Z>NÓë4X¼ïçRfJx | ÊÙâ5ȸv³ì„Ù#ñf¾ 7¦Æ´±4pc_I¾xîL ¡Q#{¦"%‘8±éᤤI¤!1Êݾ<ó AŽt8"ÓŸ¦¼`YȆ0{'p3ÌF×<}›ÍÆ'ÔÌZ#Cršª*Zß[ka†$O<Ó@ætéQÈÕY U-*5HC·‹N"(¢…)§B[ÜÐ l£?O •‰óeÙ£õæÑ"êeù(tÇÛ?Rÿ±{Zï=#I„™(Ž‚¸!‘ÕÂ44´á£H"bQ @£vct×>=ô¯Äýˆø–mAŽ•Ö`y3òÑž®øÄó0Žè8ʢ㨡!Ƹ¯Æ'@a™”#ÕJtì>¿Skç8ÉFM»°‡;¥³ ¹UyDÁC«á±lM%ªJRFŸÕ0þ³R‹GR}W€íãŠɃt7˜N"»»»¦Îñå …‰Æìù}íö€#©-殞A‘r,ŒŸEõãçÎBCõ¿ôUnÀ¼ŠÌpd2óQàM`Bå¹È©N$=Âv·Ñ2àáä#«jfif”PÕišníAÂÌÄšãtFzº8݆ù1î9 WDØðóAÆÜMGÈ- ß*ª2³»kynµ3‚U-(êÊfÉX™…!Ò,Ì"!B2=!²e(%sžÑ³³Œb#6­þ·ÿé7—¿¿ÿãŸ/ÿñÃea²u½·í-¬w“º‰àòát>Ûo~súéë{¥ð‡¯»ßRP&œNe8ÿ´äöÀŸþ´jüóëå|:ÏDy·¶ïût¾D=GD./{”w¿ÉT{‹Þ%÷l=2Æy”HI‚žë á¸é2C*D¹¤ÌRöÜ9I‰ˆf&cRU-ÄF®ÄsÊ"òqÖw½“£Ž8' Â1iåeO³æÍ0š™X‰$𴵯ï+ZA’[8Y™#;`ÒÉ­7‹½GYðNÈÓy™ï =¢Ƨ¨WÔß¾lï7¬ïÛÛµÎbö2ËåtúúãûmC±‘^¯¯²nomßh‡v ÌPˆ¨››gdìóD×yžß¾`ÿÚuó:MìÓšî),\4T=m3ïaD"®éD.Q€ ÑvïÝç÷7wbYæé…6Oy]ÎûcûùçŸiÂ|šmÞ¿ÜÊY¡òåÍçð³+¶°£(!ÇŒõH“‚HšÙo= üÜ5 qȰ úMШÙ6ŒdPaIÿv7äoë ÿîÞ=JDò—‡;{k/ˆ˜ÆéxtSdPƒ@iB»“(‹H$LƒB2³°¦=Òv7fª0gd BF3¡˜"™yäpFw»°žÏÖö”½¸#¡Ôš!¥5 Ó(³"`ëÅ}Ú \²Ôí„GÆ |§œ¢íÌMegÚ{z ~0w¶aé¡LK4¢H8X<³Ó‘ ò„Á§tQ0²WÂIßz¯)‚É$Ou¤ËÑZñg…g¼â‰~ZžÉŠ«ƒè¯²¯ãɃUblöÆÿðkLDß¾ï'¢ÿÞ—àƒíüüýßü¥ãr÷‹´æ4JzZq~)× ±;Ú‡ÏçÏ¿{ÙX„¦Xcí_ÖFMÎe¾ÌÓù”½%QÏÜ;ÜÁL$h!a³öØoÝÛ­H™æi91k8µÕm 1*A‰{ÏÄE¡ÞÍ*K½,åÊ“fJÛ¬oû×Û×÷Ÿûþ޹,§Ë™™ßîo÷›µÍÎݘßê¬@¬[´Hd&=/i•‰ÙËÞ»sìÞûcôî:Õi™//çz’= £í·À-d#¥ržçë´œªüu}uÆ.êË´|x=¾|˜ç9—,)QwßZû¿¸{³&IŽìJóÜEÕÌ|‰ˆP«YÝáôôÿÿGS2d«äá‹™©ÞeÔ#â22#Ý,’/HI2ÌÝTïrÎwdõ…S…¿¬™@U;éùÛå0-½÷ýFîkC7Ã8CÌC”üu,Íø ÝH)þË÷ëÈ_Yëþ#¯›’Hø«D*ÓGÉUI.¯W¦ÌÛÖ‰Z=™ûvÙe©a+s$“Ü(2,,­o"RŠ‘{74Guf-”ð° OgÒ`eQɤH¨ÆÊƒb„þP`p¦ÂZ 6ðaƒ)™E&•Yᔥȣp'Üï7w+ó,µ :F3lÞGËGBRˆ™IE„ú}Ý¢#:UÕ¹€¸ß¼Eß“¼#”P€‰ËS¥SòA£dRxx¹û2Ÿº7*,³Ž…}Ö”™Ì·H‹ˆ0“yrÜvsd A ©=ÅÁ™ A‘݈:3“X¸ÌLèã\s@NqrX,cšw·èiîA@ÊHf}ôƒ†€…eÀ#u*ß—DãËQJqϰ±Qf§Ÿ{‘§ ñˆb. øÐ*TX()³œ‡µ‰e8擘#´‚"$S"•™%Á”VáÑ8üqa e~¢(hb*aδ‘LB¤JCŽ÷ ë± R‡\¦Sf3é+Ú…óÎèBI"‚ »K8¬=[P™e¦¬‰Ìl‘™¾1u ’’F?C2D¯á”çåHfpé˜H"I)—Z’Å!=ØŒüvÛâ–Óec5…w‚ C=ãÞ¾ÿöüý\hÛøp:>•ŒÜíí&Šo¿YŽÏ'§Ü±c·æ~úVOë´a¯ŠiBZ’y-¤Ûðås¼Õç“SÞ¶ëuÍß¾P)u²¥¾ùZb–šOµ¿e„íÍ3`ˆƒÌzQÉt ‹læ‰ð’aAÆÐ‚"RHÄS+wPXr¥±jKöf;#@Å)<­gvr'>}ól·ÚßZ*¥1‡ˆ—r>/Þ÷x»¤ïJtär :¥V扦5Zf{ࢠe×JR§¹Î Ù=Û­@¡ºL‡ÞÞ,÷¿m4–ç§oòi:Ÿ©NïÆjo?ã›Ã] çާiúîBBz<~¾^ß>ÿÜÇóS÷·ËÙ1³  ¶l·kÏpopƒ žNøÍwÇÓé៮¯÷û}ƒO44Þœ‰‰,Æ@QškuÞ(“™Æ¤Å÷ÄÚŸ?—©–"ÙC™çzØÓwë½µ·OŸ¿\[#|ûÍ!ënUñçŸðÛ#ÏZ?ݯ}w•ƒWï©à ‰§tK÷é†ì1˜™„"2ÄzŸ*ñqâ&ÒðÀœ"Èx©dìˆ|0rÊùˆ1Åìû:ÄúEqõK5*‘A`G†ƒ;eañ¤›{B¦äÄÉ æûý^E'‘esФáŽRXX4áÖ{zon‘ •*JRF,6sJ¨ É\ËRÐÐp7Ûz# x€¥NÂ’Þúl²(3 5¢ÉS)æÌYiWjŒ•rϸ#·ô92YnDƲf®È-Ñ™ ™L™ðÄNd !»í© l‰‰ÈÆi0$”•ªð˜¸òW–ì#0—~ù'm%z,(i£hLúšJ÷€áŒwåz¸qJñä÷qæð´/Ù_¡#J¢òóÒ¾'Åûòñ/\ôño¨~•_ô+M'h8bñ~¤±ðt!qä-™n$)pž,Ð 2 Oßž>,‡çºœj=a7ù‚³k¡Öv·>-U¥öf÷•v×–Ä*ó4‰ºíͧãT^N{ì÷õ­¯7XŸUX‚ö×°Þ²_vl~„HKŠî·Ör§ºp„ìi{7Í¿ÿïÿ@×ëõãçOÛ¶&S+c9b®IܶÞUùéåä”×½é$Ó²·ëk^ó@e lþp´¥üþÿx®ó±æ3Q£õrŸ«¼œž3ÈÂ×ÛÝIŸ¾=ÕY“ãm9߉ ží»õ½«ó<•²º²ÍG9?Oz”ÝßüÊ=7oknv2ÍZ» iÑù‡—š‡eáäËýg=¼·ækÏu:ñwsmî÷û—·ÜVx$E«„ö­# !ÁêïP,'h=ò£@_¤¿Œœÿ›"úÿSC„™µ’¢™!ü0O¢G’éÚ®}Û‰¦2O)Uý‰zkèÎó¢¥ôî A`JÊzP÷Þcgf)$Î=[Ï ïÞ“„PŠj-ᙞÁ£=õÁ0Fó±O`b'Ê@Ï´L"*f‘"Ú›GÊá|Z‰¯v¡àRU„#ÂÝcß0O˜JX”á=ÃGŽ ÌBxž«¡õí  øŠR‘‘è¯m à “ ïåÖá€ÚŠÎe9aBWsJ™õÜM&žx+O›ß7¬r £–j‡yÁÍQ™´°»ßÛõ.ýn‡Ós­ºï[Ç&‡)N°Å¬ÆÓ‰o’-8’w—žUH”¶ôT‚ˆ9a3˜!D¦š t‡'qÃÎù/‚Uµ”’œ­Y¶(E•‰ì ÌÕ;Ò"Ó!…1€W*¥˜%ˆDõÀ3Û‘PJY ¶s¸DJ8J]Èû¾9 ªT–TxFF’¥Œ/!»u!8 Lœ/<ét¸ö¶³õDZ\´:lpe”HÂ…å@‚LOôd„ü?Ĭï07HÆL¤‘Ä¡Âgð3DSn?{ÿ4é¥Hœæ™Å…šXˆ“29Ö©;–ÄÁs ˆ¤'Z¸Q´¤×f»häH[J?7!Â#Þã8X@ !Ã[¦"ºä4;•ˆè½gtNVÎŽÿ=ùožŸúúc‰|©ÏO‡­¬Z£\ûÚZãjà=J2 Y𗶯pʦ™¢JeíÔQA¢}\ûóÊOû!?ûú¥oWàîÙˆƒ Ï‘½=¼Û&9j‹$‚2%°uK.æ¹¢{ì>ðß²ƒT^˜?vܤ`jtÀT"¤™±u BR!%x· Ñ­òVxï&• 9.­ï:vÀäx»ÛOÿãwÇÿö÷ϒ?ÿñöykZ¦ó1šÙuÅË7/·u¿·?s]çzé[9¨>Ñ·ÿõÜeo7<-VSíè8NXOå|>‰æ—×/ëŽó ¿ÿ??¾|ƒ/߇oŸ?º¾õMnߟ¿yýùÓAÊuHœ?ÌìíÚ¦™%u³Ð xw¥~^V»·Öµ`Zd®Š kít>­ë~mÆÊÉË\ëœQ¢ùxíÄ]O²vµ©ÔõK+7£â¶ 2sª¾LkÆå¾v:ÌËùå‡qY·Üöc‘§ii½U™h*ûôùcÛÛMáfŠmæR¦Ò¶­žy‰ËÎJÓùt¬sغ;Šá7Ç—ºL?}™ëüíù‡ÿüóO_ìtà|Ž?nøÝïJyzùh.ÿåC»íÿðù*ÀqY&v6› ÛKÜ>¯è†— ?¼°4Ð’˜sa"I0G¶ ÁÈê`ƒƒ‚@Ìò‹hìhس2ßAœ1ï"FÛ¼¯´"~_åø>öc€7þ#(<>Ð_wGôoŠÿç×Cï1ƒ±5l,"@¦=ìû`"'aQ¤Eï&Ô×£Ro~øöô²èBÎí­Ý×v•"LOÖv ö¾‡¹y6ë·¶¹`z:†rd¾ÚVˆgKÚŠK“ššŽˆ[o÷öÖ×ì÷pá(%õ(ËÀu»^/ˆyß#3{éi¾¶½–ù|<]¯×­íoo—ËåÒ,UJfÁi)ZçÚëçÛý²í=aŒ?¿M}sìIt~9O¥TæE¯Ûî`*Ì}ßÉÔ§I'…j±ÐÕ"³u»Ít˜ŽçS_ÍZ¢1‘š&(z»Ùràù0Ïç Í»mÝ,šyZ£ÀÌ•g ×*µê¤ÄÊåíÓçír½ÇÖ¯Ÿ>½õ• ׯT<·`èmïfô8éX2Üc*ÓC‘ì Ì äá“ Gpþʈ÷ÝG$:ÀäÝmÛ6£·ÌN\ç:eˆYdtsGP ÎÎÙ©,,Ä ‘Á0Þ;‹|TÌ)TeÈ­“H&¥!"h­ Ð÷È©ÈṎñdGCâˆ$)U“æpVăxeæ+Ì2‚©)PJéL¨Êµð¤·ÖáÓmª “ Ø€@º0N/µª…›™ˆôîH“œOäfÖ‘†‡_>ƒbš¦œA• Ë‘|pëd[î˜L…(s€¿»ò€•XGGJ­{ïáÙEK0‚…A=¢ÔÖÃè¶Þn@©à* D©’Õ×NIˆlÐȶÇRà]/ÊÉÌ"NNŽÆ?#ɉ8H–wh(=œ,tÓ|HÕ)co‹`%'t$È#©DM”E B˜>˜˜ƒ)™LÔç‰&ÎXǤϳVâ²ûºÇïO#Ùc8Œàù˜ ¿þÓO?®Ÿ?yÛ5 ŠIq`P°ÙÓ¾ùî»y©ž%N/ǼÜî Ç3X©µ» ÀhÙyaë¡fUªêé4Q¨ô݉BA…˜[dÄízã£>˜3z·í¾ú²ÐéeþñóUt†ªÐ,Ù}š–ãa~ûò31Jżp˜êy: î4“[mo›½z®—›t÷ɱ˜ÌA×Öî~]–żs†ñ`¼2wÜ7ëiÌ+)¤0 S°õÖ:lVÖ™è—-Ö}½lþæÛܼáÍ"€2Ótqkû–Ñ}@“ÖñúÖgzúæ|"¾™ïÍÚÖÿðùóß}÷7.µ²_×B¸]á{¿ùéÛoÎ3 %°{OdÌ0ß§Yu"pJ–`E˾weHˆz¸ â£pk– ØeÝ:¬ ŸÐ|ºÞh‚ Ö¶Ò«âà ã¿ÿíßõ-?ËíÃqmÀÛOoŸ¸H:(’=KRAN/(Âõé$»Ûê¾ûP?V-¨ºz§e“ƒ)39“'íî=Ó<ÜÓ)‘À$¥#½7_ ƒ*Tñòíóûûß}óýsjlv“‰Zn–¤$èCk¡NUÙƒƒBUÃ9úÖ; +×ÒÝÖÕ+£<©9÷Þ÷h‡c-‡å0È康v³kÃù›SrÕºœæãS9–nûùòÚ®—ÕA=- `L³ÔyþéãÇû¶µfD²,ʬªZ™¾:Ÿ§Óù©“|ürùÓ§O·¶¹ÐŸ>þ´…’Øá\Ïççã©tÛöm ·¹ÐÓ±hä¶î#qI¢iÖÓ¼Ôî÷¶‡ßzs™&™´Ð¢JÖ²¯æ=2=ˆ<,8x)4©Á›m­Gwßï÷¤È$$«ÕZe.útœUs$ÉŽbåp˜ÍD³HQR:´½ÖósxWÉÃímß^»oFIæDß x›ôÎÕ¥Ý-Æ.Ã(µÁåI¸$A'äѬxøÖB‡L<-$YY‡ =Âäýõp³ˆ¤ˆ2³…™[F€„"ÍÂÓIÆúA1XRÃù?JÇ1|á"¤mÛùáJb$eDwt„#yh©ÍlhîFN¨ˆ°ÈH‡;Fð^‘a†¥aÑ"Uæ¥:rZªº›³2¹Kæ2U¶m[o÷ÞS.3ÏÇC9Z¢O-9=Rˆ3i£Õ9UtöÝÉ€Pq(‡‚Ò½D&i-½÷°!å‡ä¯ÌÓþíS~éІÂ0r÷ˆñpBR*—â<(~¥fâWú«aôW1môðk;é×Ó’å1÷WU€GlÎpýJ{œ_O_G_þwÐc)î° ¡,ÌAxFüÛÒå¡Ä°°ˆ…·}Û{ëC*>Vµ®4Àâ믮—w¶?4^ˆˆôezÿÛ‰UBEØcÊ\ ‹Ö9e…5Äf½ÃÁžl”=²G<ÍFÒdä Ý1£¨ÌZk­¥”=BÒݬ{†äHíô ÏQ­”™þ²øjv´‰Çþv A”ëa*”ƒ;ÈÌÄ<ŸŽu޶&bI)BÓ´ X3X¾0‰˜‰I O\uÖe¦y*=8(Qdwm(iÏÞ¼E¬Ä{zOtÊ4[¦ÿ‡аzGœÀÄ¥!AïžšDŒEzdBEÛP17ÔR:Ó½ÙŽ°Ž£"؃¥¹ïé»K1ëfpóÖ³ùå#žìíù\µåbT¨LÂÓ?¼ÞRA€Ýðçßÿ£üöoΤ×-÷Ûõ©ÖyªYsžaHvÌç£].W%™ÎÇ¿~ÞjÁ–½3U=æì™Èd®å~ÛUyYæ‘YÌ 4'ú @#òÐâ[ IDATÝ‘[Ì“,Á !‡ä)Ì­a~Á|XHJ¤ ¶ôtš_üL¸È\ËrÈ~GYx÷¸7m)ù0ä…ged©šîaã]d4ß°Åu¢È">&S 2ƒ|$m)Ê\@ˆB¦ép˜“bm£xѾ}¹Es÷~HXôàùåx.§»ÜöÖ‚ÎJ)%ê3ûÚŠç,Ó.|õûn§ß|x~ž—_«àþŠ×¸ÐaÉnmwga<âï´Ic»RD‹ fª`íw£àÊ8§nëº$ªÀ7‡-˜¾)åÃiÿùóów/“Çz¿r÷oç'1³påŸ×/¯¹ë“ Jû¸±a–|DÊ#Kbf©ìðÁ?ï3õäLzÏäz˜ùB‹ÈôÁ3‰‰•HÞOX÷h8QñÌÊa2ˆuÀ¯‰9“Á &JŒãÈÈ÷ƒAœÙ)%|G\ G°„»£%g¦+œYD0•\itADL„!Z‘ã˜%!Np"áÄ6pÉݶµÛÞŠT5hOÔˆlDÈÀVÔŒWQã½½]Úç7aªCæMTJçÞ®ww¯µ>?(¥ìûÞZ‹¤Í,ï÷2ŸËÓñ =od°s›ef–éô´G&lëå¾ßê"U0Uw+A¾aïkÐ~8–i™ÊqÖÖV»š]o÷Uùh` ”k²Üd7’’Ñ·l±Â¬2³…»»õˆH’©VP嚦%"Zk\t9Zßûm§äù8¡Q‘PYøI—Ó“2-ß<ýîç?~ùñ?ß¾\}Ý}{x„‡‰° ¯Å×:zG? ¹ôŸ!ÃhlÀTj)¤…¥¶fNh7<ø8‚ åÂŽÞ»[ˆÐС¹;!b!ð? @Ê*a 3R©’RÒ‚èãè7‹ÁS-Ët´tI‚”$KR¥2) 2¿ï¶Ñ4”& =ÓÁ¤“ ì€HÓ`ÎLƒNˆXXo]B§2}ÿ_¾¿|~½ÿxÁ 8Ü¡ÆTh$RJÑRö_bpèc‚@$yä3ûXÛ¹¿Ï¶ð/ œað{GÄ̃¸€Gï¿pi‚‰E⥓ïYéã¶|î| 'Æ¢f,I0ƒ’(ŽHD| +DæfýÖÛÞ»)~ÅVúÉùKtéWÝÂ×%ˆ™™Æ·!"Á4æ€ *>=‰= Ñ¡èQ¦™u—–imˈà`uh<àˆÁéô¾-cŒäY0 ,ü€ïýL'P zR%ò‘á“°pϰ1büŠ;Ï(ˆ "Z<¼g†AX$ © ¨Ó\ʬ®{lak‹w+ÐJ†¨Z“blö˜™•«V©²ç^¦2yš "‘œŽ©ÓÚëŽÚ™ZšÅ´Knc@ÿõçƒr˜ÿvg4‚2ƒ³™V$ ÙA)1¨jÈ‘<ôçl•r's*q©,‰bääÂNaŽ–¾‡ïsQ•¬\÷—éxHlë­´zœgòõË—Û?üèˆÎ àËŸ —?=J~±0¿µóဪвb­õË}ýr¿º÷ϯoËY?Ì/4ÕzÚo·”Í4MZµÛ-C¦Óáíã ²÷Âê› ŒwÞ˜ðpYMLqß×½ÕI“°Â)®o÷pþð,eº·m]·Ë¶2ó²ë7Ó’÷5!ii÷¶ö¸ÓÝ.˜7g™‰4,#Œ¡“àÓe'–Ê%»ß·~Û¡ÜaÍèr>Ò"D8#ô€·q#€ÏŸ .Ëš„ÖP—ýp¨Ý»G¿}ÜÎOÓË´tì‹Ö'>ô×õü|z3jeÆt®ÓõÖn±öÞ¢mÑžEãx|º¾¾µn§ãñ8Oþy½ÞÓ¡¦:é\gOdމ¹KõéÈŒ¥iÞ°fGQr†äîî‘HayP±Þß þO±)*ReÈ«’ÂÒ½{ËÐê‘57þUG?¨Š$'ôaÍËHwsä« ´?È–:×TÉá&dÖÑxø¶‘ !G¥Üa‰ìÄAp~Ò±§0K©Ä뉌,Öš2K!5³ìž¢Ê¢äÑzÒÍj¸_…¥(:© d¸ÛºN ³˜µ¶uâÑÒ]šuë÷î[‡9fQU®˜¦ik«[„GÃ3€‚È˼¨'YÞ÷=E„Q"‚“’b·œQÐ$R õ{ƒuO¢JçoÎø6û‹õëæ›ƒÓ‹ôž½ ¾WŸª(Ô÷QæŒööW¨ˆfÒPegZ"Yïèd~|A’™E€~”~=ô¿*žÞË<<ôȱÛâ÷-³³’J2Kç¿D«q¢’{%TÖ ÉÖ½…·tOzÄUáÞáu_!'üHˆ$´¡d`X*‘E°ƒYFü¯ƒÉ=ÃÒ«ÇZ„ffJl„[š1@R3ñ4¨vIÈÈÌ1õØà‚G6bfïn‘[Dã1–‘+0Óà&ò •Á2ý« ¹!YñŒþˆžŠR%…]8Tšç*“ÞâzOÛ‰öÞÎGš™Ew³ð0X„,½y˜an4PкåtǼÑÜ„:¬çìÂû#Í6‘£ŸÍLeú×B’D©£ fnz‚@ʲ0&"踔…ïkÆ–y §Œ{ÚN$Að$ {'åþ¾#+ ©çãiŽ~,ª—ëýã›ß­m[Ã?㛿Á®øô†ïO'|`âKÏŸ@aÓl½…3Š2ͧçç˾ÞÛ~_¯— ½n·Rdzzº´WbtF¸{³ußÓ“RÏç3ÍŸ{ÇÞ-2‹¨’îi…e˜ª9AÌ) ¡‚¢98™}š&bj±mŽ~x©‡åÞöÛ¶ÞÖ¾98c_WðÄ›A%kb Û‘ o¤ò|ŒN{¿Ý×½QÊ~‰'‡& ˆKB8A-ÂÜ=¢…ïF0À›'%‘GøDÀŠÃyîÞ8(9«Ä$Så…\ÜãzÛû‰ŽÜ¼õX¿\®§ÿmâ–³âp8Ë2•Ã,sÙ2n°Ëý’ÍÎUf¢XQœN§×Ï7*ý¶ß®}Û­å`ð<=½TÖn_¿tfG-¼¹ß¢ÅÂËù¨‡â^åòö…ÜÄS 'mSëh`‚œÁÈ˲.tµ-úóv-»—4n¾6k×ͯÑî>“LS69*ÝÛÛþ•Á’ÌP¤x€S™ï­%”Sj‰''G|Ý$îIn¤‘P2ÁÜ{äÂÌD•ˆÁ“h!$]÷--Ó%úÍü2ÕbÆ8¥¾ù¿1b‘àpN Ù™–ÖI ‹%<Ò}GOx¼w‘‡×ña¯aÁ°eŠs1o¨”*¢Â bâî–*yÊ€e˜‡™½Ìu™* {3k[!®ZNUgb•‰±¦HE _€v €&Ð :!ODWÁò*¸x\3öð=ÓB#éœp‹¥M”NìIž¨H§œÁ"ép8“ˆ­U„X‚¿hóß” ìíƒyôxèñ’=ò‰~qZÐûÙÿïÞ ò7þ2õaGD_a{¢¯F{ðƒ„¤+K5¸òoÿî7˱ˆÒºOÉHlÛÞÌö¾·ù0æzÛúz»ôާ§ùûßõÛI0– ‚ æNI•ç2?ÏO’¹û]LÕ´f;ˆRG&1¥f‡ov¿oì4«LT–ãó}½HaË )ÇRëañëz»¿íÍæ©dоïc`|8cË|»Ü?Ýo߯þýo8ž—º¼S­µ¼Þ÷}7ËRŽá×0xsšËùåøÍùy*ÓOüó¶ùæ{^_ÏâóS¦¥æ,3zo}g¸jˆ‘‘Âó´è¤ªºïýõír»îî8Qç¢óUÖmké–LÙ{ßzë÷­9Ž"ÄŒù0¡{f'Æ|¬óqòÈõîûýþöv¿¶½,|>?źüôO~ûÒp DŒÂBÇØàk!Œ`èxÈN‡9å?2zaf©J„|àUˆX5ÜÞ__BažK#v8ˆ“†(ëÝ,ÈD2#ƒ„u.Sîœ(LI x ¡Pê2•2U-™iÔ=„L»ÁAA|€2©'“'"0"P€¬e·èî»;‹Èœ<oðÞ@ÑGÌ£Š¦(UAIá9~9"vUfßÖŽnY•Gà©ËõõzËÝGB‰°rr²”H(‰Uu®“»ƒS ‹¡Kp´ Îh»!HŠ£„‹)˜—IKé­õxßÒŒz=×åÃÒ?6¼m H0hZhôâAKôØc‡…8Ò‘ôÁ =¶Á‘„0ÖZï2³¯9 1Á6¤<2¢Œ#Õ¶Û?O5ÀC˜‡7I2ðp=%¡LÄ`¸¨JÑ!`pç÷¤8!é:0~ô¸{z" ˆ!OŠw{ëøÿe§Ó{(á¸Å)è}®‡¡ÇvsRFÄ_j#ÆKòlÈìwŠÏ¾ýä»!"OàJa,ÌJÊú #ÛL~W–"Ã<÷Èn”!ï8#†ÌæýÉc$´>b‹0¤t1>2‰S8‡SU pެÀ"8.E'é|˜hq™‰ŠQ¬ÉÜ7÷nÑÃû ™gw·ÃaÒ2Ov‡Í°«U‘Â2«D)“)(ƒ‚AáLI$ß<Âé±F4áݽƒÈ(Á)ìö!0ÖBzZÿôû?Þÿ„§UÉöœøá‡ñí©¾¾êëúbò´sÝëþRÐ ŽÌû÷ÛõØËó|x:øî7}í;•îËm–zžŸ¦Ãi¥",ˆ¼¼Ý~¾|êŒË›Í–É=Ðî¨Õ&‘¹Âëíî_.oý¶Ëæáo_4y}ë=Qmdp)‘°…m†Ì(E£ÈkÛúZ+ÉÖÒÑ@šð wŸ&P>&׬ ¢÷¶ýáËçY/ýxQ%„Yx’ZŠ²ÌµNæ~œ'Yìr „¡ÙPÿ(¨‰TÉìIÝ3=Y”–IQk[ÑCÓ2&8ï2f0Èѧ…G¸‡Yp%Dvb¹Ò­ˆŽf…ŽPíÌtã`ª$~Ÿ1Q„=Šñ|Ô¥B&wF'' †1zë ¨S:È(<3AÆ„‡ÜÆ@ÀÇ4xhó†- ‘%K$¡!Òá'8eÕ‚"+ÌפÌn-¶&J窬Ԣ‡&ÕÕš¤×tÖ2ÎΡ‘DYhŒi¡È’!&ichÃAÁ+hKÂFH‚3zf‡;=tt™Ä5‚†ùãÑ RðÈ¥@rÂ^bº÷=®½››³Ò2r»^o«mkçÜûjûacÎDŸd®eY&õÞb¿‡µÖw/e:æZ—Ûm½ïãSv÷eY¢í×ëž¡€/§ÉrïÑŒ¥“å¶Z*Ám>~øæC!-5¨üq[Q—Ó¶úzßÃ"ÓˆE@ÿ—ö‡~)ø?°p.ð3³¥ ôo‘i®ÛqX&ËÄÓ¢=²7ïž…Í1ùHɇ!‘‘A ”ˆ€‚ÔØú áQħ9ð@âôôT¥ш ìCBÅD̓8ÁŠÈ0ä{"[F$X Ä‡3Ì-:,±Ýî{4†üؘeJPVÂÈv Oó,fa 8ù¶nÄŒ­R¤*©™ys»m4r>3ɽed.“bNžØ¹¸óÄÓ“õ¸¯w"JNR*Í}ß³QG´ŽLb‘B©žÅ¨2À,’™û¾£5üßܽM$I’žùŠˆªš™DdFeuO7<ì A`ÿÿ?Øã^ X.9²«:¿"ÂÝÌTU>ö ‘ÕÍ&/f˜(ä!«Pénáª"òÊó°HNZíyý~š/ÓÇ™/7ÿj˜‡Óœ§ ÀÉÔÍf¨Ý:1e™°ñh’;fügÂo(›?„tÌÇŒhHi(`‡ç•ß÷\ü/q@¢²㓾íNpJΞˆèŽîŸ˜ã·Æ'„8hðx4Sv7æBÁcÃlÈ|ÇV ycl:Â$Fÿå›n7Û[>ü\Ö½®Ìñz×^ý~CÓ=¥/§‡«—4‰twôŽ€JÞëÞHbðVÐÍúwÍçEzÛ^c0ãõ1÷ððàð¡Ö¢£»ÆÌA¡.ÂB¼¯[A [r>?MÁ3Ë)R"g4–…ÚmßI¡–ÂSv‹è¤ =¬÷ @¯^+.2sócpüC“Æ ß3ËRïêó<9ê”s)©÷î°ý»ßš) ¨bPõb~"Þ¿ôH ²7ß$Ÿ§]ÛËg¥3aZÀf0Bøx>ï­c«3c¿¯Ýðu«‰±u2*GÓ~ĘN¹’K8‰9Ý÷þËívkxzÌ3ËùT,tknèÁ”‚; ¾y¦”sYÍtõ.Þ 2sšfó–gž¥´u/kÛ69ÁÃ8òœç­9Ð0'°«2ŢΠöž½ƒ8@>äx> ‘f"¥0!sC„Ç W§0WëA¦½! ¹ Bë[çøÒG4™ˆ„ß3r‹ÌË‚"ÜLbˆ¡ÿ&v IA0Õ~y³‘P¦÷*RŽÝ˜€›ÙñˆÐåéð4÷CÿíÖõÈ13=£š#¢Ä aÙ‘|EM™q*‘æèûN&â]¼ˆd{xr}´˜Â™™) 1i¼-[9‰h¸'Ö`p e¹F @‘:\”)aX-œ ÞŽýû}øqËw·LäÄoü¤{$ÆäؼÈ_]Þ7oß¼ÿ$Ño¦AGàà·Û·ÿ_`ü<ˆ†‰Ã/D Á;š‘³,§ééééé§3y³,àETkÎyZÊÃã%ç{ mëËË“lÝöç5…’S*â áÖû¶ÝîzW/Èš²$sLœ—Ì2çÂn]Û²,«{ßjݶí|>sÊyšÒr9Ÿ–Óý~¿Ýnªê{üéãÃÇן¿~û¬Z»5l´·€¶~¿×®HÒ Èiš§ØW[70YÝ÷œ÷‡G_;íFJ“’'ã¹zj[[koÝÖ-TC;ˆ¨ïÐfÓ,’ÜsVRͦbá!Î ".¯ß_¯W¾^¯²3hGkÍÌþã?ü箽ÖÞtžËï~÷iÊåñññ4Ï_¾|~¾=—‰¯æTÎÓòÒ>ÿé•R“lçÓ‡ó#寳®kûéÓ¿zyÞ¾þùëË·­êvÓþòÑ úß°0/©L‚@W«Íj›s™O,@ƒÊ$e’ÐÞÉ]X<ÈÈɓѸpÑØ¥ â? .q˜A‚ÓÄ@'‡Ž˜úøÄAfªV{oäálop ÈÑ»¨©ÐÄNóYZ§V² R@ÝÐ#ÜH(IF%;RšJÊIäÑj¶è¦ qžÓÄ)ñ¾ï ÑÑÌ¥ä=ú}ïêhÄ$G{ÌÝ]›†DÈx÷»÷«v)ìîdŽäi’T$QR­á[x‚wÀ‚D30fç̾«!¼õ¸ï¨Ê(Dd¦÷}ŸÓT®Y.â3#D"S‹ÖšÃIS†°$’™‰@ >šh °˜Øª:6|ØAßæ{1ð!à¿2Mªîƒ8o.¹7*½ ÆNI„Žß€Æ[æ¸kX‚5SU¨ªªúØê6K'r‡G¸%¡)P‰DÆhç4ä¤z$écg€#øÍ~ðÃ;7æ–Ãáë–‘ü7Ù÷ø; 4‡%‹‰Ò…eáÄh™l¨EÀ :xßÇK‡|Äà‚"‘˜“…óû.AáÑ»“CýX…Â!]Âß8Æk G°Få~Ôî]‰ØŒÃ…8{$Â,X¥ÌMâÛ­Ée.y™.!˜ey8Þ×f™Z2$óc”F¶mæä˜4-"¼^€+R%(™E…· Æ¤ìÁxÛ"c"v\ÿÛ09’1b~Ë;Á€‚€3ËDÜ¡JÈ“qQ>9D®ÌÉãþäÇR;"äOUÈ,SÊYÒ(ýUý?þ§õ_=b*xù‚ÖâçŸÏ7zýÿÃ×?eüëÿkžxÚö–Âó\Œ-Ê|ßZJÄó<±/ôº¿"úmÿ^ûéñïÃ,%_ïõëËç…Nóù”O+ou­Þ°iût}2³}…€ NHà°ˆ‘þå0§ã”È·ºS2‰pÕªÂ3ORN©¿Udz­ns–3r/å /h÷¾¯#é”Ô{[[­`Êe™/Ý´µ¦á¹”‡KÙ÷ÝÁA$DLñ­ˆRwwµÄ°\mÞ;ˆ´wÀÔµ)Jaá°¼ÐTrI½µµ¡öi1$`÷h÷æ3Ás’%°ßññI~zxÊAÛ÷{-wWÜ÷Û,9Ô[Õ…¨÷Ð@Ì3>}ú9ƒY‘;áVŸû74Luo’™9Ï9MÌ Áæþ|ï1cI¹g¯ÝšŠL©Ü¾öB‚2øD©ŸÏ+RÁ|=Cr­]Ê’¦“D\¥ÜÖªrv¯}ÛV¡YÐc4àjŽl®šdJ2 aêmï½j'žXx8xèÉÅ ®]Ú 4]»”R"af3R±ô hÑ‹éìä!p Ë—íž·®–™3ø]°À,9aØp t9g „ÇÛ)³HJ ·ã› J ·ËÛ$ü>%2ŠWGÛ·œ§"‰$fQ—^Õ‚ IDAT³ÎA$‰™˜#%sëÚ©÷48´ÚU[C \ƒ8Á…œI<œ¬WÅžX2û [‡“QŒVu!Z˜û p˜™’G UDY(‡Å8߸5dˆBÌÌc.A d 9¸ räßuî >èÛÃTÍÆG?p`µA句ù;Éþªy?M·“þJòó›jûÑ 9·¾ü‹ØÛÛÿýÕøwÓ¡gfJÁ©¶ÜEÈl ᆴ`žiZʼ”Ëå|}\æB½ik¬õ"aŒËeúãÿnÛï$Hibæ:ˇ§’nûºu¥ç‡ëË·—¯_cßqªëÆA—‡ëÇÉãû¯¿~ÿü}µõ4çézu‰–üîèaÌè½oIæóåœ!7]£ë¾í_Î3ç˹–¾®«»???÷ff&)].§Ëºïë^{G)ÌYäëýÅZ­m7Cÿ~[NµL¹ä¼ï†Ä#×Bº}¯ªøöuÍ9L_o÷ÿì®ëZµãtzàiyÝõÛ}wr5hµº*… ÜH8 ®ÈÑÃ󹄸ëýåv[o¯{oøúááözÿþíYÊNukê–sžOåû÷×"øýïþðpõЗÛË·—/øÃ¶Øw[¿[_¶¯çóÕM4´ù‹WýÓçÿïË·²Ýî›Ý](Ò¾ös\J*ÙÝk­èDlfã„¥ƒïʦ¡­Ižü7æ4>hé)]?}âûý•œ€Ô:Ê4Muí¥”ýöíæ·\J÷¼Áz{ÿ©¡‰“îÊó$)%sT³ê¨D!ï€ øÑèr 1 €a€I"LA†vš©y'±ÖÇè!Ÿ%J’&’¬zO‘yç¸÷ºŠõ g3SWÆwʉ"íþ¥B’‰irZJá€Ô{7oá*‰¨›©z¼Ñá" á]æ$ÂN¤©Áp‡0CN"e*…|Ž8i5x‡uôMü{´•L™¶¶;X®Sž§}4Õ^<æ%“‹Ù°ïFÊ!“D¦p'ç3-O9L\¤–$kﯵ)X™4<•k§äÛbÞ­¬i´ŒÃÃÃ̘ሡžÌ‘rŒC‰î­ÖÈ™-´¯`ZJž‚¯ÆOÓù'ºœMk%Ü„:¡÷Þ=º¢›#§”Ò«ª3ó$ÉXÒÀHÞïÿîßüÛÿðïÿïÓÀ [  þpN×ÌøÓÒñïÿŸ¿ÿ8ãi^ cùp)”ÿ럿<¾<«_ñwüô‡õïÿ¾n¡«6ho5•|NÜá’Óõáát½$|yy¾{³]×¶µótþøôi½Õ¶v%³2ƒuPÂt^¦T‚i¿ïÚ@ŒœÒ¨ÞóTÌ: MçiZБվ»ÅýÕ¦ÜôN§eY×õþºNYž_^òrZ«íþ>?œM¦¯·­;ßžW bRxkÞÝ=Ðàp0³¹ï:Bµ½F´n‡ðÚCœ „€š…ÄÂMì–dwcz·Öú¸Võ=ȃ‰xíÞ›ÍÀ$¥dJLÛº‡ V¤3®×錹©þnJV¨,—išÖº?SÍ󙋽ìÞ*m:5œNò½ë4ãÿø×ÿ'²tõ×Ûíùù[1üÝãÓ§óûç×þºsǺ:%œʧ<)x¡òÜv¶è}Êyž:ÈSj‰>¯÷óÇœ<¬ª5ÄsÛü¿ô‡éï.§,ûüôXÕîªUèûíÛEfòñTê½oŸ¿sš¦Óò²n½n#eتbÛ–,¥ä¾WaéVÃÍ(I¦L€öªš yðÑL¤ˆ°êÃ&",í="¥”Œ`rÚ÷D—ÓZ+#$É® ™KIÓeq¢{ÛZmœÒlh’åt9»û·ççn:Ï37ePžgn­™yb,;1'&Nˆc!IR„Aâ€HJ¥æØš‘EDïÔG/Éyš f‚FpædfÈErNï­ÖÖ–)›vƒGʧi’\ZÛ­wß·Ó”—eŠÑ “ižÎ§ÛmUwõØÂB+q„šÛ™d┉“¿²ÅÔÉ™O’]š¶V7m’$1ÇxT)ì0§ºŒÐ2òÕ€G4×0E JCÉ€x½¶Ñ€5v7a$Ù j…( NPÇñÁÈI0„>F4<þ×ñOÈšûŸGÕý5ÂÝ=ÄœD=’&òˆëcùøôp:—œ©LùrÉד<]CïëÚÝÓ4‹y2Ûï¯ÿužçœ%ØLƒIÏùñüPíôŸÿ æS–¶AÕvŠÂ„”8³pp¨…1; Ñ4-?ýüIst®E_W_ ¦á{ßó”K)–›©9ÓT¦r™ÊMnpÏ9‘™µÖžžžRJ½w"šç)O>åB%U̅˜"%–œ†.c)g µà7Ï=3M,Ù`uÓ¶¯9©Çæ®`—{ÃÚ´µÖ­a¬Í+M8±‡zI8QJ©Hæ@ïíÞûÚZÓ}¯ÚQx‘2q$8YǘÒöÞG1çÜs_NËO??-Sùó¯¿|ûöÙ)ž›7.|ž—Óyš¦Ò6­ÕŸæ{R«©Ï~J)¥9¸îµ©Ü(£ ò¶H8 ìÀ`_2KDx×ÏsJò·žrsRgcBDèAa„ÈEÌÂ1ZµªÚ)Ü„b¾d[.”ÄÔ=ê`)kR‘DlžCRÊ f†“™yWw§àIØTTõ¾ßÄD©…ŒÈÖ¸ÇIfÉ…‚µG@Á$ ÎÈH‰‘ ¹—9-§Kâ<~µ¬Éˆhì¿¶9%p8E"Ä¥8#…¢…²¢Sh7S0Œ$ÊDN{¹oE·hØW]«ÞyÎ\R9¡eÎÖ½í=vÇ—¸ˆ4‰ª¤(”ç98É1›MűÞn½:šsdY¸$—={Åj±wpNSš’ͦÉêÔ…X8M%™÷PÏœƒÝÉ"ÂÂiÊ#†­ïÍ(?ZDfª:fJÌì9 –÷EffwŽ#±òVäÔÙØÙái*¥P ”’(‰<uïÈïßàÞþ½™Ü!á£0†K#zxvP€c$D4~ƒ“³02yba »Äê…½qhîý€ˆSb4o™8èÃtzJxŒy’²é¾zqܼ$ñ1­Š ·èÞÍ1’çU§Dœ˜1̃ˆœàe8”¿wýü;Åÿ 1\E(ømâÅCªAQk¢xLøtæŸ?œ¦Ë´Ñþ-êͱ;YC3f&¦`t5m½ïci¸‹ˆäR¦´\“d2öèšwíÛ×^ÿéžëÚצk I"ù±“ö[@Ñ[Q˜ÇÛ1¢Š CÛæq pB#(ƒ¦œò’²[BðØF2:a¾h\×  ¥$¼²ïa¦°$dC.2ö» ¤ž‚&μmÛýuÜïð„t…ò|çhÞŸ+8 yÂ<Ïæõ{«ÓÄv?¿tvhà½d¹><œrÕðzk2‘yP‘œxêÕ¿ÕçºVXwÕÆŽ4s¡Ì‹ü×?œ|"6f6%¼¶m^¦4§‰æÔæa®êp˜v"°{ì{«Zkï´†—¸O… ɾ™÷.{´ºy ɱ™ßZWíÏÍBX ä hÀFa1Ö$`ðppÀ5à:Ð9€ Ä 8ò?8l,ï¨ ØPÑßc#žää‘ÌÁÇ6ƒáØoà‚œ‘2JãÙä”RÉT>\öìÍ£†í ÎñÒöØÛÄú Ó1€J˜ÒFþËçϵVmà_ûë#Íe"»;Ó f´uÇ÷9•™Óô"؈¸y÷P–Rg" mNŒ)ƒÛ`¨Úq~œÉù®UA«÷=@½ÇÞ/4“Q XT€9ó!—³¤#]üƒ-&Dîd®º¹AYb‘dDañÛ|½{°»‹ŠA臕ù`Ò…Jc„… ‰Ê”/g.SZÓ×ç—ýu J ëêî‰9ÞšFcYŸâm[’ˆ®Fq :R„SŒ†SFDÈÐŒc¬ìŽ€1 1KœÜÙÝâXŽ S9îÆLÇÞ~[à¨"BM@™$nS Ì¥Hë‹'éŠP¸¹¢v¦”°haì–쉻Ä=¨¼$ÉN2r”‡‘QqY8G„%@):³"”F›F Ø€Ž@ÁaÄdbA(!"Ë€¿áóÇ›ÉèH~‡ ïê°: z,ˆoùñ錃DñOÊšû_TE„{D` a‘`‘M)X.¹LôôÓåw¿Z.9 V&/ÅKÎ!B’Êr*Më¶UI•³æypI×ËcJym^nMARR™M`i·\„òI³$m½nm»muq”ÒoÛ$§s¾N–|©ÞÖu]_ëV÷ 3õðVëz·|J®]·ž¬÷¶‡)#3" Eây)Û~oU·}ãÄJ%¥ej¢œ„)"R)¥³v»ßïÌyÊ“i¸G0L£i'-9U’4•eßÖ×ûkYfB¦JnÖ»QÊT¦”3NÁZ[¯µ¶¶sßïû~b™p>`£ZÓæˆ¤)åIˆµÖ¾o LAA"I8ÏóÜ{/¥”R¬ûvß"OX{UÒ4ÉršN¥”:u’ÔõVœ4Á!s*Ó<ïÕ­®—§4ŸÝV%MÞ¹¾öº…wh‡:˜cë™èüÏÝÄúßÃò AcØZ†2Å#AAnÚ+BYpšæå2Ü´§ QÀ‘‘L.2gÀY ºLÊ´m[DHNЦ„¸èW'Œ½„°¦”s&Üa6΢®€³é$¥¤RR 0‰HÉ¢J}d¸cžYÄjfJÊ@J 290HˆNæjpPJ’Ã\w=¢}mõ2Ÿœ™H(E­URP"!áÂÌœ(õÕ¼:c¤Ä”gY˜É³fJ¹Ì981MnÉUZ¥†Þ;ª¡3{ÊœO4S‡¡Õ *Z’,#%PAÜÜ‚¼Ì”’@¼‡‰¤ ±Bî„Þ B·m?HåÄ„AûÑf6GÈàÁ\ 0Yø[„€~Üïˆh­Q Ì8gG˜¹™T-e ŠÚ›.)ð6#¢ÁfòIP˜äÓÝá[P„fw÷°pô¤ÁµVg€B”@ãÐ=l\Æ Îx7oê=†ÇáŽpˆ.‰ÚDJÊLÌ&Òs"ÖœA,L†"ŒÍàa úÈ#ÉÄ<1'wÜï`±p#²÷ ß31f>æ]aop ˜<ˆhDøÜ>qÎyé-7Prë­3ïS´Ì•½÷%\ÜÍŒ¦ZRŽÜ9Û8bPsQDD1Éé¬4ïVvŠÍêî·nwxK…’ùN¼ƒeÇßDÆ q$I˜˜bD7ëð7À;{ŒR ’H Kv–k Í‘¦ ãBÂLœÂO§åªZÇ-¡\ÂÒ 2gPfËëóíõõΊÞñáåtúõ%>owž€‚GÉ©ök9çËkû¶÷Üý4ñ‡WN¼¿ø×}Ës5â`©k=Í”RÑŸpxwíûmß—e>=^·×ÛËKŸ¶ë½¿‚©ú­.)qËKÂýÙ§¾fNiɬ{SÓ0„¹ ç,"ÖšjWl/“眶º#‚kó¦ÀÝâV}oû­bsÈ D2ì›<¹'¨TÀ YèH²à¸0žÇèkÓ›·Œ~ `˜s‚âý~w³šf‹ðÁ01„€ # rÀîºÇwj§óÒ·õ;ë´§(s¦^ÚÌK®{]]€%¥4Õïíþu{ésᦶ®÷XðáTÖ¯6–E$°Þ÷F:ó‡…ÊE`ÀRÒeZÌÌömó 2›ÉªN’@ uGU¨£ñDkÛ4I'@„ËâÛÝC1"B¢4ÖE˜D$³€$ÂÇ 7QPoÝ[÷Ð<çRõh¼8ÆÏÏñŒðÃÒ% !ØÌÂÒP妓„c½^ˇr%vfßz”kš–©kÏÁŒ®4MåtâZïû×—ùÑZw#o‰%Ï–2ŒhY.¦¨µ®ëÖ{wƒ*Öû^ýRú|É×ù²”뜠Fè-î/·Òö¨ÛÞ[Ô ½+ço”|9Ÿ#\ÂÉ4 ËYzm÷m­µZÐè¯sNóiº\¯¯µµ½Z0s&»YÝÊ2•”¬÷ÞT{muó~ÓiZê~“bmÁZo÷;ˆº0;.,R2¦‚R˜£jt5ššrŽ}w.á:YD¸ÂUL©{nWèÖš™IN’ "’Òð:ç,ªúë—_…Ð{=_h>ŸZt0ñ$Ói)çiJ‰$òùÏ_Sáœ%!Á ¹”ù´pí«óõéÃ"K¿)õ‚Jß~}þüËó~S3°s1ÁÿÈZøÏ)5ç[EÄÉY˜ÄŽ4þˆÜÎ>ìãýÐÙ(aâÄ9GXï=àËiÉ*™uk Ë Ö« «Oy ˜‡2IÊ 'xÏËäj½5t˜YrÎ"Ib³†4ˆ8 X¦ —®A@pðªdVkþW[ #³Ï’Ú½W×Ä„¡DfGtD  ‘°“µŠ® @ k5)šˆD(çÔ—‚Ñ"ØUæ£håD S&"âDœYfñI%JP¥py»h8B](@¤"ÊD u7ã,ÎîPˆ‹8 ¦IcLhBͺ s8ù`\þfAÿà§ Ó¡ÅÀ_™Xi,1ÆAß>Z>ª òæêy³¢ó!º}û*?>[ÛW†¹yg­ivøÓÍ2" 𨸜Ao\ #$ÜÀŽp„1AMÍ]æ2’€0­M0òe¤03ÅÏÁS c™…9b  Žð` Yõ””b…5)9› #œÑK ±GœaN ‡ É¢æ¢䡎cV'(ÂéHŸ¿ï¶ ÈFe ¸¿Uf:”Nã&Â`BP»-)M,èì[‰:‘œ$O0A¹»6‹0m;uÓfB’ˆ“!BàM5ƒ$Òìéd´ôXjLÊ]£­ˆUÐ ##áN,Dì Ž#Pé”}³v¡ýmHdDQáŠàxˆc ÷Æãƒ4e™J€¬³Å4ͧœ/=··z´…"B‚] ÷ï/èh®güþ÷¿kN¯ú%È?þüáéãù)]/ñ²,g¼{0)hkûõ§TÒꟷЗºQ(ZOºµ."æör[›¶ÏóI·nÖƒÑZ«ºåœ—·ÝAÉ{€gÌ2yÛžµ³eÎÂ)™e „"ÊÄDÈ,êŽLèžáÌÛ)…Ö-ü »7½7Œ™$Š tçØª &vq ¦±ÔoG tl¥¼»q%³l#åøŽŽÁ×zÛ»{*Ëa\t «»’±×x¸aQ„9INDð¾ö¶ötÁòaß}ë%0q*9-SI°Kí«Îs¦ReÛÝë¶Õ¶‹ÈÚì]±ï8ÚežoŽ\Ða¦0wÕ½²ðÌ’³L¹\Ó´¡ÁÑ~R"ªÎ¥ÔTW…fH!8¢¹n°l4zv pÚjc x„©m͵¨ù b2K*R‚2ƹ¨c'Nbb fb ò¥ªŸ±=Øvbæ!:ÔÌ4Ï'" Nâ¨Õ¼«öàh­u·½í^-)DàµV¥’E¤öÎ k„½¸€0üØrç8èEŠÖ=QÕ1+t6ç7 O3KaY"³ ¢¦º{‘8ùcޝP˜$ˆÃÉ|Ø–„ˆ%±[uâ` 0]8—±`Ç)D ûލ Ò $…% ­¦lJ 0q–áD6 áÃŒ¬ƒÇ!”1=Fœ€‘:£l î.¸‡€7b€SPŠÈƒ @ãàƒ û‡‡¼™(ÁÄŠ bh@!c,]cHq<Þ=na¶ÄaÊø4#Ì:æUóØîã˧k¹>ÌO?]§rŽ2E™Oš²§L"–’/‰çN ”xšeŽ“ò,”2§±»œ–s.…í[~ûÝÇóý¥éfÏ/à\ó îõ¶oO—sÝúºuS›çÓåf` C:¨;ªkѽm­n- µ5ÚC §EµZk?=<^/GlÛÖÝöÛ­›æ©¨f³N%ç±æ[æ<Ÿg9ɸJkë¦QWóÞ·[ë2K¡I Ýµ×Z·­o±P¦Ú¨î¦ák\&9ÿ”¯¿~þFnBÈÁÞšùÞ±Xx×® ‹q"'öÚ˜ÄÍàJ¡‚Èq¿U%å±(9˜"Ð{7×”’¶þË/¿$¦e*×ë5ÍiS—$¹”²Ìļ÷½í­5]®šBelÚIçói¹œy»o öXŠ”ÌÜvñvzýú]üÖlç·âÿ_À¯¿©‚qòqsÁ)R ™PzC8""1€–î xí¯Ó41³šçœOÓ‰ˆ×ê®ä 9 3‹^ÕA˜FÔ9I))´ƒ¢÷f8†®f"ñ”/ª­w qfv"5W;„6 Dôj­õ4I뻵îjÉÇ#C E21«LÃø±6ƒãƙƚ;yl»O,ˆdÊ™Å*¨n{Àœ™$,È!‰$çqvD&mW4gI¨öÞ›k™D°¸ÍÝ’F6 ÃГR)“2,¸St èAêBìP¢D2:Ê€@ÔzæÌ”,ÐjqW‡ìÔ¿zljdˆ•Æ5'ÞÉ  ¢ù Z)ç1“y¿Ôаˆ¨Ê§ۆÇHEŽWÑGÎ&€×òŒæw$ã{ë pBH€8È#xÿFêL|ßÂ=ãÆÇ¡>¤JÄŒ#„§‹0 ãèp‡V°yK‘T9_§¥¤¼›¾ôý»ê+°©M,älDˆÄ<©'GgA`Œ7?8XCͬ»)܉¤ˆ‘d|¹Á‚ÛÉ~Ä’@~úƼeIJqP¦Æ¨â@í3ñ§súù锟¦Û©Ý¤>‡åe™gV"a˜{¾1v0¡•¬!‰s¦’Ó¸‘OFy<·þµñ7Ž–jà&q'ÚÅ€)$±Çà‚}´»Ç' ½§1G•éîJa£¨c‚‡ Ñr·º Ô¤ Á9jlV@™Ãº¶ÞݺÊQ'§É¨¨æÞ„ÕrràÑñ« †íu- |züxÎÿå×/õÓ Xð,%ÊͿ߿¯÷-Ÿ=½Íç¹LÓrJ,<ÏN=H½b×~¿ïTøz~ì½Þ¾ku\>È—ç•Ë¤æœ 9‘$†ä)Ÿ3©·œ‘2‡x:Mœ&j[Û0gx¢0ˆL©$dðv«ÔTˆ¤”fÎÔÌð€:©ÁD`e]»ÙkEkÈ@n½…y`LcÉŽ»Å@aþND=2rÇ";ή7>PøßõÞXXǯó˜<DC(qÀT«Y¥i»›¬VNÓÌ…î)Ì÷¾­ÕnÏMt³Øa¿<ôËioûs×»¢â”yÎ|ul/`EN”zm©³;׿¼‘))`%’)JæäÙLvÓÕ',×ë){â­©}GëmOëö²JB¢2XSÓîo¡Ï\'r&ö”\È‘eN‰‚Cw &8H‰GwÀ‰lë•#!cd  ƒ&Ç¿D"nQ·mYÊòp]¯Êø~{]{·­Š&‚ÀÍ[µ€‚ØzÏ©ˆ‰}p¢ALLáœd´¶ð> $rò¦n@¡ã3Jb¤Á´”¢ªS÷:‰'–Dl–4 ·øéI„ÝÙƒÍRP^„ %Ã5¬§@Jœ8 (› èM¯=zaPÒF4%J#N¸‡‡†ÃˆÅm¤¦¤Háp„‹poW8…yDò8lÐÝCA (Sõèæèpá^²‘`#ß 8a&¦À™\B£À‰1oMÌæpv’÷™9±»1¦ýŒ‡G-9ºæï»Ü¿…)ü‹™ý"þ<Ñï2ò„ǧŸ®Ÿ–Ÿ~¾\?–ÓY«Æ=h êêfðæ:_ÏwÚÂúi™?ýáwË5í57ÛË’ö¶ÕÞ„YN…Òž³?¤ÌšÒLõ¹~ù‚2!O§Þç—{ýüå—ÛGh IDATÝtI–sZÒ© 9´÷ÞxÓþ¼µh¶¡‰ïµ‡º8k3ª8çå|¾¶e_÷û4§ËršKQÕ B·0…GbIŒœ…™!dîYx·¶ß5-y`šz7íu{ÙŸ¿½ºá~ª×sšÒ¶¯Ï¯¯ûŽÈÉÐûÔól§I®O§¼ÌêöÕµ7ôÖÉvf1ˆŠ”T”$œbˆˆHMÞÂöë}:’,§i.%DÆ¡ê"ä’V(B2ƒcÝ÷.¼pNË"Eº·×—çõv·fŸ~Þ7Û^û¾ÞÜ@§åYfgwŸúöüÒëjFM¼IŒ ‹q;¸»»3ÿíÙË?¶øÑŒÈ qJ<’EŠHˆŒ(ÚràRH Ôq¿Õ“ʼ¤”2tTkû¶•’ &JND⬨ f[ëa¤0S3ƒ{ÔW0C -³ˆ03«û<ÏÝ" CÇ‚13Oi1fæ°ˆÞ«jmï¨ìâì1f&ñ`€„‰‰öÛí@%£# L 2dï f7¯Ý\¡Jár @š—rçÁ©O¢áÍÐF²,Œ:X-S”À:<ŒƒÜƒ”I  „Nº6T‡Olõ' 8¹Ì€œKæ"©gžhÖ­I³Cƒ Œe-~ÝüÀ ŽõÍJt̑☷ŒòI ‘s6³ñÙÍ,Ì<$Ý>~Æb”š‰y Ø¢Õs˜E˜þÿÔ½I“%É•¥wî jö&÷rÀPÕ%¶7.¸á’[þrþ²›MDȈŒp÷7˜™ê¸Ðç‘PÂiJ£c•ñÒýù3sµ;œó³Œ K"ýú ðë)Ë_¢ãN÷0øB¬Œ;áÎ'r}]r’HŽw2ìUHFê®°ŠH&g†çˆA¥ÉÄ4ÚˆH±“ˆˆˆŽEv" _l}éë-aŽ(" Î`šûb¸F˜9ƒûpw»ÓôÌ™ŒÓ2-RAœàÑ ¼Æº2Ó+ÄèÞŽŽq(WG\éý3"A@;Ñ|"¤Y»öu©æ;P&¥â*ªêNb™‡Ö¼£w4C›„Jj&bЀñâtiqîvƒ7^#±!ÉSØ1 ̯Ÿ•¡”#šö+7Ô¸ 9ò¡|ÜxIIˆ[ËU[÷á豘“A,9©SXx¤y'v–Í6@ éLt ^A´wJgʱ³@àöra§Â˜Hž?üüÓï_РF×ÏÏ×õñÛz»\¬ù²˜uìvHK»à¹_=£·^އ,²­ëÖ–ë†u]ú†ýC™DkÈ­;ƒ” ƒ$dØKˆ’­­yÔi†–J*ˆÄNÊ´U.âuj‘*à"ŠHáA…̱Ñb #S%é>X µ:8”ìÄ’™"pf)Éé-< Dbà)ÂÌ™wD»qAE‚fVdMLœœA ’û!™”àLÝÍTbd’"œ#(‚©aJ3WÑLòL·œ™ux€éÌeA9SDZÃ`äX A)(ˆ ¢À†hw(9h,+aH4ï¶¾SS@É#Ý.dlôÁÃ1ÄÉ„}%¥€8É2š¢„ŒØódP~‹úš‡ŽÿÊ|D"_©P¾pÄ Ô=Þ¼Ù¿{zxœ'˜wtz#É5²{Z÷æÙˆ"Åso91ä1§oäðvâ6Sïîë–Ñuš¨öJ¼9Úç8ŽËT?|¸NªSy@ìÏ·ö¿ÿ‡gkDåŒ3dsꮑÂѱ®«õôTçR÷‡ÝËåe8êDÊTwÄ,ÓL´åv½^—ue•y*TêñáÄ"lº.ÛÚ›‡GҺƒ‹kßÛžRn·e»xtÙ.ýz‰4Øv)¤¥.”¨“þöø~y~¢ÊY7äöí›oÞÿíŸ~þXþ›ß<}>þtÛ®næ×ÕjAÎÌ%*):ô/i«yl¨âSQ–ÊÅÑÝ»5f“¢&d©…ÈUõp˜”AD­µÕºœŽ`N¢î¶­×óõ%ݵÖãÃA¸Ûf׫w7î¸,h´­¹-·æ›ßN²3ïÛ­WßkT¡DÌ›™Âÿk¹Ÿÿjƒ–€§xÜØK¤Œ3†NKd »C2#”]´Úº^×ÈŒL-ŠDDD”‰,ˆJô ΘgP´¾¶¾Ê!•Rt¨¶Â#[7O@ ÌÈ´G:‚D+3QPgN¤ÀÙ>z»»kBïÊ£zcU!Öû †^“i!`p¬i1fÿÙÚ7PN»ê>º  %.µ–©2³{÷梅I ’CÎ#Á•éA§£Ð9;&ç’­wÊ¢®N¾ö\<»ã:€ûJ%Ý£;šÙÖ¢ÜrÌg3ÍÌ$Ìœl晡¥LÓdäNý>µá»ò?ொ7º/Íâ5˜5¿xY^Oç±² ¢ŽïCD$‘éáîþšYŽ«¦_‚ª)Gĉ{ßZ¤À™Ê]E- 'çkvÍÝœ _òUA !.ªB>ÂO3ÈnÈòÅ|” â{ærªUCõrOõtåð=Ø=‰FŽßغ0³àÁ$„™!Çnm½\!Ê‚-2Й|¸4ÒÓF_œ™)ñ½³" óèÖ{·tSŠH'DÂ3e¨Êﯡo—)i`»ïñv™‰Oá`˜S2öu7[×ßÚõÚÎìË tÐŽ!M)êëréñtê­ÙÖzä–#Mɹ6W3M­ŽÅy:¶f¸+5¡Î)‰ PÂæáäw> ~y–¿: î Ú¯xôœ;|&‰†ìa{:Çéðn¿s¶s_¹–Ç·o¦y¾=ßR »²çZ–hk_ÍŒ‘J‘93[‡Å6íäA1ïóΪlÝ5©»­Ö[UœæVðÔ—åÒ,ÛÒÈP;¨Y7ñÕ-©:T¯á@‡Ž¨ˆHïÖšùÚ.Ü)éÖn$…“JJOC˜1±Z³Éq”@ß{“N" 戰@0º¿LІø;=Èãz¾\¯g|V+ÜÈ`ð~ÚsŽp´Yó®K®*½»ðv%'‹"ûà Œ‹E9H3üõ‚~Øâ39~¹·0±è=æÀ"hô¯› Ïžδ¾Šªp!h‚Ü‚X¢•™NÌÄÂm¸‰’ðnHurDó†¤0Œ¤´¢Kr¸Ï "$‡IQÒŽ@X&'¹pa•€H÷ˆp ÏÔÌd$«•"¹d„÷@:"F°ŒLÈ]Íà÷P‡ûÎ~ ‰Æ ?TbÜÇ@'JMÔ1#‡ª€clÕéËÇL_ôr_ðc¬ð÷ÞñëÖXD"ÂîÊé{0Pìöx|«ohžnœŽV²Wkµ°?0j1šRI&”IãñÍ›RµT¢£6éQZQln*e¿? |]®pŸ¹j‘ê¡•~„»hrˆ2iB+*ÏS™Óèf[kM̾?½áBŽ†Þ±‘ìø¸?NÓ¾ò° Ò ª„’i/uB[—Ûzm[Ê\çý4χéL:­·§@ïÝB–}ë(að¼}Þ¶s2®„y_Dñ°/ß¿{ˆ¬³nDùë‡wÿËÿô?ÿî?þÇŸ_~úùåO+ü¿ûw¿ýïÿÇÿáÃç§ŸŸ^~øÃÇßýßøÓŸžŸ–ÍàžÖ˜ÀT‹”išužµT~~ú‰xGu5'(ˆ“…Uº£õÞ{g•ïj-":ïæu»%°;˜³ÛÖ»¹bÚ+W²Ü®k.׫Óñý›w»zä¹Ù.ûšoÚÖÞzw8{x­r|x¼Æúòr#öÜ -A!á`Z‘HxÓ+Væ/di~×"Ðkžk2(þKŹþUÖ\à€S`ä`N˜0SŒ„Lr0‚ö‡oG,çÖZ¬+¢cžëqžÊÌÞzt$qðݹŸm>Ì[»d`ÒREŒ¯Œáv7»7–,ÔÖÛ@"Ó}¨†= Éw»9ÈII0É}¸ÉÀæd³ÎÄÊXY‡¬š¤q’%¡÷"}Ck‰,SeQJ†rxmφàÓ fÑR7Ckñ`’BT3k'po ÏL§Ò%­»€Ôuvf®Ã>ð4§[Ë[COÐTgUÕF} ÷Þ·mƒ3L¸ýfXlƒ0IÆÈ OUꎢ¯¸)AœwñZƘâ:ƒAñ%öà.ÖÊä±—í{€FRDÃ/[ D„wCwˆŒtÉLrò‹€d•Êñ3z¨˜K)[s`|߇FŒë=J±!¼Q@“¢RÊ Dwt80f‰ŠaV¥Êp3¤Î½2{Ü iÞîñxDË0Ï»ø™bÀR9¤„¬ qwÇJ¼¹½Ÿ7B#xŒzqLŒ”@n /R(„P…³r²ÐÖÛ_à+БŽ{JSB†Àî.&º#ˆðË–ìžíD@f £ÖQ$U\oEøpÚÞÛoQ^¶Ì›™%2‚+IáÝzïÛÖ `áyRe˜€æZ¦BÛÊAÒSWÒEòŠvA.X‰6!SMu"P—dpßÂØé¾Í#IÎDCOO<Â#¤1 Áâ#rÊAæ{Š|°'Át0P¥L¶öó¶¢9¢Ø·†k‡k«¤T*!V cÈÄiæf¸ƒRJkÖ;  µªîÞ{dýæ³µF·_}÷&Ò@„Ó~O‡Óq"¶¼ÜpýåþpôiœHS—ó¥­ž—ÏMÛü°WæËºáv³Ý„ݤiÑRŠx·}Y—sDZ¬ÊI„7§cýùyJÚ…îY‹'K²¼ÝúßS·¾ZHUžÅ@¬Ó²õ¥ÙŒº­íåió‰ž8±G:±š÷ÍzR9ƒ0`žàL‡Ü5f$1SR·»¶‘™¾h^FÚ±¿î[3¿f þY´Ôý‘E¿Ä–ŒBèË4í´’‰ÈnáÖ:¥WT¦I¨ÔiÞ×îgî)"¼#”ZN§Ó®N/Ï×)t-tš¦]ÔååÅôË:Ÿ÷Ľò$‡Ý~]oO~²çþO‡Ãt<–-/?~¼®à:JW[À‚Ð"R µ oÀv[nk/§i:L×´ë˦$¥ÌÖIŒÐÓ=á”IÛšQG¡Oà ‡¡é&q‹X͹›n̈Ûf©¡\fh€{2…0«öî™pÀAä€'@4¬#ÂD™Ž©ŒãôÌp(920Ie"ªÇƒìç-ý¼Ül3؈ŠL÷°žB’žªýÈ”¤àL¸ß¹˜cÄ9TÈJlLO“D†‹È¶® `ÈPK&%¹“Û$JpMÊôtïœ,@´FÂUtⱨ72Ï.Zj™´DXÉUÎÛ‚¢ÌÄÌ™paG3àaîî”ÄŒ*õ.Y¬Œ£Ì‘4‚:˜ ±¥‘;¢‹„Y [ë‘èi-Ý“œTªª"a0’È‘œ’ ŒeW 8RB‰Œ3뮊fœKÀ»'ˆèH7ÂHÍ“ŒHRb•!ÌYظ‡FЕʜ÷)Òßîˆþ–zío©þöëÿ-R¢WUôˆUPÕ»W7Æ©‹:×¯Ý e>ñ|l¿úõþ7ß?¼{dÍ—ëù³çÓ·oßwítd}£Vq“–“Óq®4­è²¶øðÏ?ì'<ž€\Ö9Y—fyë¾Äå‚E¦]9Iõýûæù‡¥÷m}ùŒfß<èñðþ°{·µøñ§Ÿ¾].W ÇœÀ™t¾ÚÓGà§þÝ÷ý»oÓ_.ëõ¼¦?ןþøð¸ûæÛÇýIçÖ®»‡©´².Ù-úfŸ~þÃéíñÓ§Ÿ èfáhÖ_ž}?i­õýþû>•ëáPö?ÿüóí¶–ŠôþÝwß¾ÑÿÏO}6}þüôm9~üßþדùËóâãú›ÜWêõO:?}ºÞÛ^¶öòt[n ,¼a¾ž-—už&VêtpÊ‚›Ÿ|¿œ¯­YEaèbv½œ 7[ž¥zk à0ë¨çöûý~¿¯»º¬×ËrIxÝMÓ~oÜ6¾YÞú~žw}-²oòùÃ6ÃçOë‡?|~~:ïw»÷ïßMólÍl3^WžÉt¾™©¼ù§ßìê©ýþçy^ûO×~‹#ÍßïßÚ5Î×ËK¿8 $¥T¤¼Æ{É[̨w’†7øß&¨£ÿ,¿/î}E‘8‚ÎÙÀ[À`=t7"œ)‰ƒ@ ª ìêq]o½­ )཯Þ&‘¢ûyöÌÖ¬7À ôv›…[Æv[(1ïEÑ®·.ºßïªjkkoë°ó˜;tƒˆy‡Ñ$s­‡ÞûÚnå8³J5oi ‚ªTÉèp‡ª–ÊÌf–½Á,À”¬ªwn³ v‡µuâ™Ë>y§µ¦÷åóÏ0©xz˜2‹m-™-Hª* eœ`¬Y1?àØ’Û³=•“ÇÖûÇ(–ǃmÇ€`ÑòÔÄÀîÝ©?Ö /]º–˜}Ù^®ÑæÃ]6oVÝÒìrƒ5Ü Ö]YO²íq3öäæž÷¶š=½GU=>>\Ï7ó0w8 f…21u÷SÕÌ ï`’R¼ûk•32‚¢"\J©ZkÝ:“jQ‡TC+A\ L +”c¢]pOKaQï>“Y{t,m›[ð˜U¶ 0ÀIJRQe0{ ™{ú(ø “Dìî=E E<ú$¥Ñ$d3W¥t¡ÙÝØ]•,FÞº3’îÜ6 ðé`Óq7ÍÍâ'[èÛO‰KAgNb ªLs2½¥¥\à ê”BY9N…*—Ìæ Õ‚¼K‹0 œ¥”?Χ}Ñõfÿü‡Å;Në4ÏÛš™(À?¾‡T¶—sžQÍߦùNäxÐkÆóó­1dš¶æ»ynÍ>Ý^*ÕÓÚÚoŸnj w±;ÌW^¼ÚC‰_¿švßÿûòŸ^¶ŸžÅƒ‚µO¬;áXÚÞuJÒ› ©?¿\û~÷a{z²¾DäæiáõœYÉ·†H€Ý-3‰¹¹‰h ÓÇ;Æ^8 'DfBˆR$zE2f&îEÎØпt ¼bâýÏ$Ê_æ~¯ª™ €ÛÖ A„)S¹!vn/Û›7»ù0mä×mûþÝ{y¨×¾¼Ü®üa¹=áW¼ûæØž›a¹´øgzÜíN~þ°]ÖÇÇÇëÒ-ð“Ý>Ÿ¯ßOíÀ}‰Ñ®N õXŠ’™­/áìyYâl^‰7o`<žvØÕÛù¶½…¼Ý½¿>]¶e¤šQ³ôëÊuš Y ­Ø¬ÛæîCSÈBåMx¥œëä’-ÜË”ªd>h³™«u·µÊ„¡éÎð‹ôaãôNwŠ$!.\JåÓ4Ñý\ÉÍ|k™Ó¾N»Ìkx»l¦z(‡­ËÀ[tõØB$E×Ö½[†sR8¡¤Óôpm7)ÄZécþÌ$fF:Gp8‹`tà™¹¨ˆ˜{X¯*ûý¼]$ibf–Z8„,Ù|'å 2%‹%ÛÆ•iª:xÖÃgED=²»oKãy7´pÉ!¢ ßÜ–¥ ³QF¸ùk-¢ªÊ ö”dMbÊ„‡„hê$¨:DàVvÓα‘]ÜVÏFpΩ› hŽû`É^‘ éI<|ÒNnàîiÁS’æˆz`P$\•2ÉL¡±*OÉla…²Õ 9_ *“{ qx°™eªjÏ‘³ðw©š™ Q`Êxtzo–Ñît|ÿÝéñ›øæÛòþ]ýæfq{»Í{üúÞ>üêqSÛva;¿òêî]nfë¥äaɰ[,Ï—3ùmç„íÍÛS’DUÎ S2ª'Å­ßd{ê Æ %ûÖ­÷tûõ·ß0á¹.ËÖ7žøá ûi¿ß=VåÄê“ÕÃRvõpz ¤©ÌKêd=œ¦ãÃnÐRQdê½…“9–›!·ZÓ=JÙ(¤N5ú²,›uP‡Öéýþ¬ÏÛºtÞ•}Ùíß!kmt£Ì§¿›„óþôÛ7‡o§ÿçÿѯýé‚]Á›ãÉ·üðÃO¿ÿðãyÛ>ž/Ÿ>]½A"sojk/ÉÔ†H•úÖ^>}Þ^ ¯OŸÓ<"‚ЖÈÊk»øîíá×ÿð–Hlk//—ÛËÕÝw»³ˆÎÓ”'¦Í½Yë±îžÖÍ–e{yºˆ‹æ-W¦ ©ÌÇ}*3<ÃBP.Ï …*Ø2JÕéTºu“Ç’ÛâS²C„*)[«kÒêééÞpßÃ(—HOþË{,ñK¤ñ߉_NFú ÀH¡¶;Ò-cìRˆBœ‚’ƒh½Zkiž,$¬Q %tÒÛåL*,ÊRRÑIH9›û›'hCÏ\"µ¦ç¶5ï½÷-Èr¬NPÖ:ܬ!­mmP"V0I-¥Ô 3³Þü¶%I”HC °ù=R‚HD’0×ÂÁSr HB’Lˆ,3i| ðbÐKŽœ¡áI‰p²6:_F2²gÉùA!{îݺí…AŠ-ð©ûerÙ¤YÄ^DT@Ú#¶-SÂÄÛ¨ƒ8QeOU÷3Žq£õ©Ç­Ãà‚dàŽºLÌ/è;q'y—¦y"eȘ#ÂÃãÞܼ2´ó—m~Û¶LŒ6’™ ÷ ˆCC.ÉAAÄ@»m ÒJÍD€AJœ’ýŽtO¦äØi&H€#)ÃÓR†):#90ò`ø¾¬ @#žoXºàdz:(Ã=R()šØ'NŽ{°RÌðºH‚JdAFD ?GÜD:yV¢R‘qÏéH<é‚Ðô!Laµf$%6§òŠXáMRá¸[¹†çæNò"ÂôEYþê|Ó$uŠÈ~·?sÔÈ™ò¡–]U.â%¬°M%ªmsx—€X5³Ø|YÖ‰KaNN*J³@¸÷ÍzNÞšYû<ç§ÏN7ʬ!hížds·8”)¸ à2å5—oPöEðžt’pÑ(±´ t£Ö2áð†Ó!±ˆŽ\@3^Cæ™A.¸£Òî’raÅ}`› J08rÜ*üfΈf$:¾z AžlÉ‘Qˆ•X‰É$ÂT™TÄZ@¸³D‰‰‰t[7„Ž“˜Áªu¦tÊûBƒ™¾ É„0óÝ9Kœá|'—"Ãa¼ã3^ÇJ Œ–îÑÂàQÕ9ž@A"â-=¤á#‘Ɉ$i,÷ ÄÇʇbä8¤B2H‰œÈN¦ã×÷v_Ì"ƒ`ã´DB 8ùï¾ýKrà]:{ß"«JÀ=aãýïðÍ·§ßþ»÷Çoãô€Ã ¬ˆŠLº3Ÿb÷Ýž§Ð‹¬K‚ÿG¯ IDATs]zïp IŽçóåö¹oÏ §Ÿ%™Ðß9ˆÊÎo}~`ÊŽµcËPߌó$û²Üpk›{?ß^2¶mÁçóí¼l`ÚíæÓq¯Àñ8ƒ¨_ξäËr9_nÇÃÛr%•T•ãq~|³?w»]_nÖÅ{³ë­[÷Rܽzz&Æé­k»]ï"¥{k×mëË4×ýQênwÜ—eýüÛßþãÛ‡‰s}ùôqÚöÓDÉ—ëùÜ»'°Çt˜[Lÿ×ï?>Ýn?Ÿ>_Ïç%Ï pœEŽ·-Í<’d’Þì²]T” “N•½wa>ìwõ¸§]\ò‰®k[—¶Þn/Ï-Þ|_/RE*+ ‚²G8Å0ü1W-BêÝ×[F³löî!NûÓa·WÕËóËÇš[6ßñ¡–9)[ïÂe/Õ}YŽS[êzº’R’ôHwФ¸3éL‹jë¿ÜUù¯¯{þˇn½R–)™ÙéîsÀ}ÉÃg‹ÌÈhm3o6¢ËDDXF¢{XÛ $ %î³R7ÎP çåÖÁÄ,‘ðæ™žÄÂ"}~’é úvV¢îff"8‰çœ›y"1Äq‘0ë#DÏ#æП£Å¤‘ÇÊBLéw¨2âUÂ@’ÞóÖ†u•{ý<"ó¾"—ÄA)‘,A¸:'–¥‹­¡óÄU5©™»õÞ{?=Ã2jö)²gt„!—µ ‘Pr‡eºBá–ñ%‡%E@­u¦$œ Á+ tD‘RŒ®(É#I.Äzw*&'Á4®«¨ˆ d(‡ …dê1Ža˜U"ÉÂ=#H„ ÂÉÄÌñ4MmYÃ}(\YîN#wO"g4ÂPukÞ£òF_#"<–íæÅ²ë0 RJÆÆ£Qf¡g|¡Ï#8•ùÑõJôêïRä¤{èv"((œî g'"IþÚ¼;Áî˧©4ÁBÉ»‹4‰F’Àxšþ[$ÿ3½þ_›Ó ÷Ëè)GgØýÞV AÇÇòî]yó®Ðþ&5"­õ^°ylÝ7lyÀ›¨b-é iQl©¶­E—õùÇþò1¸‘xÞ ”8ÿpaÞÛ›ïì›_ŽßdÙ)K×¢æQY÷k§Ïç§¼üz¹‰8éîpÚ×ã^æ:ös™‹ãW߽׉ÊÇüøÙ>P€ÖW·Õ£S ²FL‰ŽœnWo·ì-·5—›o«‹XDvC$ÖÖzG8j…®—åéùiW1ÍÓ·ß¾=<œN§ÝûwûóY›Å¦Ù–íé;9X_àüùéóûïUËÜS>½\ÿÓŸ^ÖîDÁòãÇìŽæ‰ v%¦š1Ó¼ÛaÝ–ÍzçØº-=E°ŸPY&¦4Ûš×J§ÃéÝ7ßð‰òøÍš×§OÏçóyDÞ·†§O=ìÃî0χ@³eªÓþ0Êña~wzÏËþº-6b?þøãípÛM³»OS™¦ÒÜÚuãˆAUîÞ_^ž‚Å"ë\§ŸÞï°B»·å¼ÉêsøòjÔ.\3aÑ_%׌ÿ_¶BÿÖûÿo3__À`æW§-ÁƒHîfˆqúÃïÃm»#ÏLx%Mµ®}3ëiZÃm+‘IZvÓ4yƺÞ“ÎÓÜ{ww„…f%åv;¢2 QA +?%þXšÃ-Â…Y‰˜•”ÔØÓÂ3(@*ˆ„û=Yh¤!¸#l›V3ƒ° Ü2¹Êm„ˆŽÃ21Ø« I”Dt8”0i©µjQ­°KÈ(ƒ)YL²!»Š@™0‹eÅõ–ÌØ€¹àô SíW±‹¢×a2ÏôÁP.BS¤Ö~k—Ï/8ß`‰Pxrå/ÔÀˆè½ÃÏèkAÖvG0T±ûk(*!"qÜoª/yä_j¥L¤ƒÊý#âQ¢ù(¥ˆ*GÂ2ÙïMV~áz “e"ÂÀ_A½KF4¸Ð=9ÔrèÝqÏSºú_Ë{¯:i‘1L¿"]{ï–ð §tßwS0E Œ™0'fÒ*ÚÌ^ÚrÛÖ‘=»{î¸â‹²ˆ@!#3äË.ø—2”Zz2Ϟľ÷Tñ CâËX$¿¨X¿„U ¯å ‚Ј̪c°ÛWï7ï-s;rž«V©ÍÝ"Ê©tJ˜Ã:²Yq«‡®˜”妅n[„åpä÷ £‘׃ªÈñ‘Ì{Çœ¯5~I.§W˜á¿Œ5ÿº#Jä¶mʱj‚5îmô¨Ql‹ØzD°HQ.*N‰˜úF²ºÙ¨*ƒ=à(2 a>¶~)œ¥œ»sÁ¤pÂÖž´4.zš‡“€žH‹ó˲l/eÖæ$l‹]7H‹ÁÑiÍ@(3Ù¨ÖZ¦.X2Ò0‚ˆ‚dA&}|xxC½ÝúK§[³x洆ݡÎ|}¬»nqÅ¢S5Z·•â†Í½ŠF¶xõrÇp®Å=Ì$2ïÑË÷{œ{á>~e“ÿªÿÅÃý¯78ƒÿ×;"úמ#_ÿOùÕw!‘03H‚ˆ)ÏgË líáÀsD”Ræã®÷ž[ ò¾•I«Šì“åörÉÞÑ,¤¦ê=Áæ¿®H·¾²ÓxØ&8 Vfb$Ü=@ʤfý|Ù¤ˆî&wo[±éÏaÒ‡ þG"žˆñKšÉ &RF!JÏ]ç8 uŒ8Á´?iîžhá6˜ž™ªâî÷ÙÇ0Ý%s£trDrjff8š÷‘ Zxw³ s·HÈN‘£´ÌŽ"Düš¿–  G*ÃA*-bJî”æDƒ :Fã'"ÉLIâD5U‚&fÍÝ$ŒV½_ f$Iá Dh)fÖÍ(€OòÈî,ŒÃ=2Ã]Uk‘èæ9³£t dô*5@°HÎpï ²ä3U.uªL sÜ\5ƒ„™ çìhžð„* 1g2î4ú"f2××øƒd’{–¥…¶7MØ]æ<£<žCš9º_ ( 'xF+R0Âð\Saºdbâ-:gÐß玈rউ×ñ¶¤ÐŠ:£îéñM݃ä*eã) åNqÜÍ$éûEÞÉçü\ƒËyÝn×¶=Ûú)Ö—uÛ ‰ËGøoæ2>ÿüÙ7Œ(]­·ö“ËI§OVíÜ6 +Énšd¦g¹ Ä(UTUQR„ç9…Ý{ô~¹~æ­/ó\uªæé~[ok éØÖëíšs‰v“¶ùróë¥]oÈÄ4XèÍŽ?}zŽö;*:ŸÛ²m[1už§é@E›*N§ÃþxÜnÙvœoÞì>x¾ž·å¶Õ_ýv·ì×ö§ßÿüŸ~¹5Ȩ?}>Z$´eXl¶A oÞ>>elkkÍàÖÓã›™ݳÛnÞÿý¯ß½Å·é¼×ýq÷&"”ôÓÇÏ¿ûÝÿóü9¼m};ff.Ûoß¾ÝÏ»NUÍŠ ‚zØdbôTN¶ÞÝ­”¢ÊÛy»Ý¶ÇrâýéPû—õò§§kúþp"õùAk}@Ë~n×O·nƬ·g_/ažžé™„€ùî¯ß9׿û?¯¹n£” Õ1÷ˆq†'œ(‰‡¥Ä™éÖzC3dB*©0+DÜhb*„)s(•Zu ƒј2þšÊÌT&ÝUªáˆèDbÞ`Äݪ"-S)×¶(‹Heb‹ÌˆŒ€¬"Ì÷ OD.Ë-2iÁ3ŒXhœ{–¡5ADô p Á‰:uŒpõS)Ç¹ŠÆµG¿úÒù>&Ú$“¼…C*$DÖÃÄŠì K,†Køêý™°Ì…êÝ:R'…вK¾Æõ銗-A¬°àdOÿ…äc"ˆ¿ôUfÀ="ú(°˜4‘ÃVä÷§àh7È#ôÌÝ"‚YD„¤˜<Ÿ‘rÏ Ê!¦”à–£~èá 2@Áå.å#=ÛøF~ϸ'!V¡B4‹–QÂ3;âk0!ÃŒdÐA†‚‹ ß—™¯š"Î4·Lû™{óæH’äÊ󩪙¹Ç ªêª&¹³;³²2³ûý?Ë egÉf7Ù]gâˆw73=æs ²ºÙ!‡Rª$% dînz¼÷{á*0@9<Â9W‰0'É…D -°½îr݇Ž(C;4êþ}r(€3 ( eìöüuÑ¿3†Ôp´©Ï×":¯kcLJFDAAâ–M Ib”$N®î7okh%êÂ&[Ë$”iàÄ)瑪v×ÑëGÓÁ(|šÐê½a iU¨‡yùx%ʼnâ @ÿù­”ÑÛÿÑCã­5zÛZŒÏPD¨YǾÌ$a¢{há0Ñ™DJb tO áï$áÔV B4OOÇwïd¢ë·ÛL(鈩£ ñ¶EO2Í'ñºuwœ'U|î[WšJvCt4B3Lãöå®^«…nIMJ>äÄÞ0b‡9$ „äˆ[ëßýôîxüß§Ÿ×Ô4²Úв™,˜~î¸ÛâyÙŽ )Oš64FC´QveIDyÌ,Ü,lx]DN{;´o~cßòúÀtø>åxM¡ä‘þg&hþ'± ûÆIøÏåÚýLÍ‚«qï(L ŠNÖŒ &?¥³)`:¦¡r˜!XëfäiΘûr[X5Átww·Ö—ë‚u]K)9OÏ/Û1ªî"HR ff6V.D޽ðG„‡³‰6ݶ¶tÜy>ZÕma2Î1‚ýÜ×yÀ: %ì–ˆ…8 ˆ9<‰çH,À½ Àqš <Ô­™'#u3„‰£(î1v°!Ü…kŒ¬§Ýp¼×tskÚ{o¦ãMqøºue e¸ˆŽÝ$44¦N 81»—Ç}0)yð:¤!Ì ¢½ ^`#¥€qâT˜f1K ¤@OÌ…eàrÆÕeMîæÝí|< &Þ¾qp"#·}šá‰`î*"ªeDÇ2313Åk½4þÒ½.nÐÁ !Ê9çWOÉ!F &‘*EÐ<”(ƒ; ncßí<¼tNêcìà”x-rº;lmëºÄfæ¡ëª¸Ïs©v½]È.pµO?>z÷Cš\ãåéy4/§SþË¿ú‹¯¾úBUŸžÿðÿ}›)·óÃÇr-?½<±Z.’Šä)åw“8-Ï·È==ðÁOe{øôûõ»ßÿ´^T½ ’€™Ä£ÑÛŽˆÀ¯ýÿïˆþ¹÷Ë/?þšºNĈØ×Dã^ Auú«]Kº›:yŒLt@x¤&NCØuÙº70•išçÉ]C ¢7&H§ÄsÉñÚáFJI9H(qòZ»¹$×îì#F‚§žÙ`W1ñƳw…0 †¸€©?'§ÔxÐ9@ä=(ˆ$X †ƒàaÊïK:ä€ßŸ+]15þX2ŽDIL‚DÈAlÁŠl4#Î"Áìeâ-j¯xì´¤‚dÙöÂ1˜@ Yz]íeAµa{Hp¼ºzb¥Íl¼ã"À9ÂLCèÿvIøkêêˆãˆØ£´ø³«Å}‹ìH€YrÎ$ÙÝ›šïÈ1Š‘&èˆ0á4JÛpu_(à@f¸¹+”cc$I&A™(eÐi >ÜÎæÔ81§a½B„n‘Æêi¥@ÁcYä (…”öwtHàs ™ƒ&Hb°2¿^¿…Ì;ý‰{*P„ûnõòB”R 퇦¤Ið+LÅÉ`vÞ—NØ)€o©ò:ÜÓ~3%DrÏcf­S4&Ž,”ižYÉPí›v7ø`éŠ%!‘€©ö¹Yºvzt{V_œŒƒÙ™;CÇ@‚^“a9hÔ†´Dâá3FãÏ’ú>w¦ì²ºá(b²!pµ"Â"$ÌI˜œMàjØS|ÓLR„Aƒ¬Ï]°WŠJ^ %R/,–FqIas%U˨„C&>ÝŸ»ÂpiÕ/ÛË<æRHàìh­‚3êÚ‰xJ%æ6&9‘Ð ”³ˆ4Û¶GdmÒûÝÝ]ÉDžR.8ry8g».¾¡=áqý4Ý_¾8ž 9}üÕ—·éš,õãZ$½;ÎǠޤ¢n!ä)n½7·Êè­;%¼å8cÜoí¡Ä±O7oòž?’Ê|̈âúlGô?ƒKý‹¦fŸ >ið†S)æaf ”äÚh¨µÇÖT¾×ŽÇÙ[-(E¤'ßÑ[†Ñqº›Ï·rÑ $Dåp¬ó–‚È`ò¬¦0ônþ¦à—áÈ¥S²nc×rBDkz] ”’h«!9‘ÇZ-“ndƒ` · ïTÌÁ懸°¸wk)xؾˆ¢7òàˆÎYÄA0ÓÈcØÇN‚°ðî¡nHL™‡²€!âî=œL{X0$”„²¤’òaN‡ÂÝZ7}~¾ŒmX¸ƒŒ'J{0N‰˜iÇ©3ÅÏ+’ÔÄhý”‰3ážÀ‰ÀLAßæC_AÂ{@ÂoÚÍM)ˆãoç$€´7‡‡83«‡†õÌ‘˜^cÛÁDC8ÚU"{–ݶ[¸‹ja‘ áÄä;Ó-È}PÓ€ É~Â<à:²Œƒœ 9Lèx°íüE§ÑEb tä¶"œÆ•¾O²º»P0¨ƒrP E&J"Ë4J»?Æ®I‰BðuG´ÏE‚ã•_ŽùüáðþÃñp¦<ùñ$ww|¼çÓ ÷'>¦Ð’@…è(~¢í Q|YÛ§Ëóúdéå”oÞÚDúáápàÝ}ùîËz[£m|}\ž?Ý^—XC¯%I%P=€‘¸€cë} ˜æœ¦‰ÎÇwªåù²qï`—"Â7M´­XW”‚V½n†"s%q*t:ÎçSJÜjßn·—çu½j7¤”¦ûûïÞ¿›çùòûë¶µ,TÊ<•âîÇyúúë¿þõ¯ õ»ïÿp»=ßf-/OPüîo—»Ó¤uë[ÿôíËË£õ†ßo½ýþ»Çßý®=¾ ËðdÆAv8¥Þ;ˆ@ÅÁÚº’é÷ëÚ=aºã_}ùõúõéá^(~øûïnÏ·[ ¥ê}»ÔÖÚ5¢^ñþöôp÷2¥Ìž®Ï—õR3sï‹ymD$žÖžõ™–&9àåØÃìòÔá0wëzœf 3kÛ꟮¦Ø¶íùǧvk9¦å²…WÑhùÌÌш‰lwh»EXÅc¤]&†* (,sä¢fVÑ×Ñ¡„„8Ã%0§LHÇ)¥¦u{Yš–ù^‚°ºewJY@ke*<*s I®ý¶n½¶î(ZAÒçÑؤSZÉ{b%0ƒYØÜQšD²xôf=•<æÿú_o—‹¿\gµS0=]ú¦¶aºÿàsÙn=²…G6̹\É[½¸õfŽHXÕ6x(XÍM:àåY>ÜÍ1‚VF·ô¶ÕÙ½èð7Qì>¢ÿ§UpJVø³‡—ÇÒw8dÆÜ §nè‰at¹X:!ÒafV—5EDsÕÞ£Ë43ñ˜Áüî`S™¬öéxzwºk×-±Ï2)T[h(Ucöª½+4³ð@[:&æÄð°îcFâŽÓ Ë­n×uqÇ<µ›.Æi¿ÄI8‘„D„îK0¢Ä£°fÙv‘sr;ö5Þû0Ym2ïLy4iÌ»©†ÉSrÞeÏDÃÊ"ÝÜ÷ð86Gq‘L’,%;Â]7WõÈ£M„ĨÊÝÁÑÔšEUm†nc¦äpg Xx4<";+p´IÂã‚pލ0ÊŽLžýÁèx S3…@êÁÌig;d!E·1ÌNbÃ.¬GlÖ#BJfIƒyãÄ]]x±$ÌÃÁ‰ f;•ŠÈ)tJ&rÕÖzï½>p9ÏÄN„”ÀÔ"ªY S„E$OwöxÉë ˆFþº”U8½æMƒvéµG"cç#SèuZ,D=B™R@‰Ss$pအ# |LÞÜÂLˆÿ‘É ãçw@ c£BéÀ’,°y0IšÊÜ×›çɉމ¥ÐtÜ—g,Õ°mÛíÅêïútÂ}Êùx÷òÕW•ãä8çvz wïžç ¶ª»Fãh5ƒèÃé]”€ÍµÂÍ!"9Ë^ÙíY¿’2³H¸æù ÔKîªöò\o×J))e3³ê…‹[\/Ëí²Í9×2OI&!öËåééÉ×uݪQ™Ýn·ívcñ»ï¾ÿs<>>†Å7_}>Šð–EŸ~ú)Ó»ååy¹¶ßþ2cJ¸»{‚Öïê ¨Õœòéx7Íó²^U»LSb ªPSs1ä™0ŸîÞ¿ÿøÅ—¿šŽ‡m[nkýñ§Ç§ooÅpÈ f9MNâ}ó§úBAi½mËÅí4åÞº’Ïó\RŠÝÂ?Õ84ZUoWx›ô®ëe­âº.Zëv}ܦNÙO?¾´Ÿ¯m[c㹬¢·zuXžóýéì¡•»W¶Þ/µ¯Í7ˆÜÈÜ 0ù¹FÿV†¢ÿußÑk÷›¤ IDATæ ±\ÇîŠýÌÛÍëc—:`4LÞG2§Ã ª H‰ s¶07bbÔº"M’†ï•J"«µ™Y„ ‰óÎÁaJìbáîNÝÍ›¶µº+r`YqL¥™$ç\EÀ!BîsõöZñï9ÙœÒ^ö>:"pÎL8 ;¢‡!ˆ 5L#0dp§s0afœ“Ügº£&µµ+ú 44ÆÒ09&ÃCâ|8Lpßz¯È‰Î%O™éhÜù0ßKº»=v\W<-xŒ`Š9ë831]Œ:{3¯-à É£·ˆ(‡¼m}°ž†q¯jš±ùÙE ŸÏ_}½°ˆ‘™í‹ ~>¾~2‹ñ+R fæ½÷QR€¯:;òPQt¸Å€3'Üoo»DD>«ºöˈ|ÓÒ!IJt¸Á†hä"D„ypŒ™0v¼SEPq0$¦3³éžB;œé:È÷-à í²=D͆·% '§aZã·ñâz€F€Èp´òšaA tDsWbgræDL;’úVB¾)Ÿb+†ø-£uL2 Q!*)h ˆÔ»ÂVèB¾:CF¸^—$4qâ b*ÉÁAÚºX$„˜—N÷˜“©ªzSï DÔ€Ëþ³s(Y ñk¼l쌰oHñTÕû•ÿ .¨C5˜[Ï’ƒb€èˆÝ1£"!ìl-lƒµÀš¢˜`"FzÎež¸”2†TR9sÚÖÖµ+R˜m+žž1áÕóäÇéÎÖ5Àç3jE­ öã‘D <•ƒœSdq5µÈÞÃÝ:jÅóÓ–3&c6jj›a:(r\—¤m3çÓ\µÞ¶ºŽßüá·ÝiYC’=Ÿ§“8*Ì}Û˜˜…ë¦ Fɽ÷¥Zgtp‹W¥è~düÒÖ÷6ãˆ?Y±ÃÉÞãÍìCN‡L5gø§4oßMŒðO@=lܶŠH ׈ÈfL™eÎÈ"œÜZ»Ý–˲̉%‘ßZ]m.È…·«sw[*mv˜n×Û)œÕ×BùÀeC];B•*DÄ|¿¥éç îh 9„ÉÝš…0G9+c¹-×¥@r2sy„õ3â¸B !&ö!¹eYßð}1 ·áä‘Fâü^DrD¸ b©-}gpÊ039{cö´+…ÙÀÄE¨Hw«–Ä2Ë”|â˜sB’“–ã!ÜCKlf›ÒºÙUíaFW ,€Ñ0 3ŒÆÓ-‚A ÊBìƒç±Ó9ÆKSx7îËû=Z 08ƒ29Á™ç0"¦ð0™£‡©©tÓÛ¶ œBØÆËl8ù…0ÂA"‘D]ã'"Á›ùÚªi¡ŒDibâŽˆŠØÂ7ÞÁ§6OŽä>ÜÆYF<öZÁêƒDG…e¬©â5§Ç_v{6q¸"|ß™Óî·V!NCbA‚‰XÆŠÐ#;q”‚ñϧoÿk|,'úÙ:8æ=åâaê&9ƒœ3ïj«úÚ, sâæˆÚÐ×]›4†¯}(_õ%Ÿ§®/t'Ûe«W{ùúrø9¥ûãÓÓ–…äÇëµ>˜áÓ»¯ÎÄççËõÛß/÷»ï¤\sùâ?ý·/·ééÚ¯®()gŽVUÕótÐ&/Ï×—[M)§éàîµ58¹E@ˆ™e˜ïX=qɽ…5fN°¼^­Öz¹ÔÖ¬$Ë¡ªµVOwwAúããwÚýñÓ§Ã1ëÖ¿ûîñË/_|q_rÚ–ççkûÍï¾×†o¾–õºòñxœ‰6¡üÛßüŠã,áv:Ó_~ó_¾ùú›Þ×o?HÜê KÃÒôt_ïßxÿÅǼ”ËåeÙnÞÕÕ4”‡s˜ÁZ¿<]þþ·ÿPæ)¾ÿÃ÷õ¶eF ´Þâ0ét8~|˜6Þ¶¥ Y»Y_1g¨œY(*\)’ˆ™Ú¢­š^ˆÃSkÕs>¾¼Ü"2æœÎpq3Bûô“ç/C¯zë›2T¤Ö†µ)ûtžg–õ™(D)®Ûòé»ïÐrŽè!ììñ/P»ýûÜUuG)%¥t«•覥Ìöï)ˆ¶5¯$"‰%"B„ev58qJ)%˜·ÖÁÂUÔ5À-4QÊ%éÚ™Aî ¸Û¶l‡Ãäï±õ-öŠÉŒïîÒAD¤ÖÚZ™nÛí6ÃÌÌn7p>Üß3§eYŽÇâî,”" XÕ`–ÊœŠ€y>&í=Zg ߆Hj†›9B˜“äégÖ‡Bï9Ψ¹öc@%a`>SÂé„ì¶-·+IÃH®±©`zÇÓýCéž *¶mÃmEstM¼j‘Ìa¶mÎW.½´[‡œ $ò,ì03±W˜œ È5Ñ00sJÉ]%±HF÷Ú(¹ÃÕ4™I²H¨n;@ÕºA ˆ‰xDÖ`&bðÈÌ!HDhï$¥2¥êËd`‚²p¢Ökž\­q íî|"’Ü„eOÉEaB¸¹¶Öj@œRâÔuÐÂÙ«Drâ bJãé­´'¿< ”…Á ìx E £êØíZfÌÓT$)ÈD|.D 3N<çd õp@#<^ÁZ ‚ÁÁ™KÎÂÜ´/M¯ŠHi˜\Æ„‰¢ÚÈ#¤5{øŒÕÝ^‰ãCÄž+L°qÕeÐâ$tw,ïN†ê%èXòIÒ0'*)OœÉ¼·Ûmí›Ûr²Ej”€ŒSÉ%ƒÅŒÔK'Ù°~Ún**‡Ö±™#ñ¦›¥W”Åš¶±"Ü,"„X˜Gûº*»‚×À}Ôý Ö ‹PN˜ó”$7íÍz Â’å ]n4¼ÜêÚƒMXYº[s0#h(j$‹$Fë]Ò¬Íz3€·ÚË™Ôíãûw^ðòiMRÒ4-Ûcj=,Ëv:_–:—C)sÛjÀ†kŽ‘Îç»­×ÇçK­˜ÞîÇóÃ}Kµ¯[&3PAβ´^fe­ÍØ—h.V·íátÀ4õzá‚Zñw î?ò÷«Ñ„9ñËía>TëÔœß×:®m^9C³ ³€ïW\ìÐÍ]„Ø·CÀÐkÐq3{{_˜é~.П´:¯ÓñÏ¥woêox–·wyÀm—  ,P'1J‰´Ýœ©–y‚j¸–™ï?¢ ZÕ…úTQJœˆÓœ$e‘׺l×¾iàý‡óéîPk_×[­}Ýâ݃ȉìW_~üÏÿÇ_Y½ÿõßü÷’ "…Á‰KIYXhî…$§t>½»>þíÝñÃ7¿þ‹ÿû¿þ?¿ù›¿þꋯþê׿Ÿ§úé¹áþǯ¿þúüpŸ¦dÑ»oÍUR:ȱ€yim]–Žõq¹Øß—§O,‚°åzµ«sGÙ•/€QßšhNótžJ¨[÷h5*Ü‘OË> f–`2‚‰b Å$‰ˆkЇw_´¾™©vY®V&2K‰Oï¬U|z~ÞÔó)•Ó4OYuT#OB™ƒÍÝI¢¡›kä%dª#Üî¨ÿù:ÿWÐÓýkÝ/ÆAâ¡”E8™‰jƒÇ ΑGP¸# ôŠ›^ë¦Ô­í܃æÆîF Î’”¤äðhÚ„S°; ÌÌàØ/6ô¾J"rã=0ûl9IrÏ p}KïFfžçÙÌFŸ$¿aj<§iæÌƒš{wkÐa\!sÛ}2 µ°E äÓTÞ1½OÌ©Ûä嘈CsÄ$R„RfÚZp0 ÜÃÁç©jÐRUTQ+Yâ”R9š@Œ[ €;¥œ,\ÂmT‹$R2ƒŒ¡Î +æöÊ!bÙŸGc¹¼ÿJp¹+œ˜D„ d6¢2³ËÚ•ÔÌÆ ’IŒBv˜)!0Îr§ Ì2”ÐΤp¯î`øØ|§D9Éa’C™(E¡c6ÍŽI6²ÆúÔ.‘‘&‰,G#íD^âá‹ïÞoÛöé‡O½³L‡S"ŽÛí¶¤j‡¸öÖü9§H&ÉœŠ‡#À‘§¢ª  Ûáþœœ9‚ÆÔjð¦k#Ô@‰ÁÄÝc3kÚsΔ3ëàÙ¨f{€¸C)àÁDyž˜fmk÷ꈔÒ<Ï`eFPx„#ˆ¢r0ÁÂF¯BP=àæá`J„È„€Àp  )ÎÁ`B0±#„~!ÞI´£¥ˆk¢ ¡¥!Ú­Ä  é&ö<abÀ˜2`ðüKvDÿv "z¦”Ü»i’ã]9¿?¼ûbÎužKÎéx—“dV×Ú¶þë/¿üp*“=Ý––—ŸôÈ\pÔðdúˆ~A@O‡‰²úmí­ëfsŸ© Ý:À1u¤HÄ”(À¦èÝ–ž¦s²n?µ—g÷È ¼öåùñSïÙº5½.·ÛÕ{Ç»‡C«¾m‰3sB@½“%ÐV mnÜ× ÖL yÆùîx<ÎK]z´`<¼+ÞhÛº^Ÿ–ÛåùéÓrñËrùÃ?üøé P°Rïíz{,¡ýv:rÉüÅ÷§ã}žŽµéwßÿx<üî»o|üññå©Þnh ½cY/?ýôýÖ–çåå§ÇŸT àþ̇Ãé|?/BËí¶5èsßÖçq°"Ä E&ÏŠ 0†òÄ%OÉ%ªI]ê$ì­çi"¢m«f:M‡Xé0Qp7ÛÕ¸R8'À§rbšZ_á¾Õè¦ e©)§rœ%Í,Ì™Gö¥/Z}š§iJê}óùÃ]µ~»nH€A½#ðô™Áÿæý2è—V[q ÔÑPÏrI,@äTv/ûè9˜‡§ÿu\¹ ªA$´?H$¹°dw톒'RuëüóÍØÂͺªZ´A•qÀɽ·6~Kd:$ZŒ€0÷®P $usb¤<]¯Wfaæ CDxžö‚~Ô$b¯A áAJB) Š¡rXFL"w˜y¦S|È0ë]Ï$S@ŒÐ™â¤ÚÑ(œ¼šÊT—îWõÖÇV”(͇i*‡Ê uëKÃ¥ÅÕÚBÇ8YP\m„è’03ƒƒ-4"˜XDqi˜ vœºÙþUÃÜ¥¶ƒvÃ×wØ…h¨Çä2†Þ0ø3½Ó[•°Ž€8 ÀÁ@ÒY*SGNDná w!f ³ žÑèT™y¸u‰ð£ÈA¤0ÇŽsC0ÞHVP’&ySŸYø(`Äj¡L rb…뫳u"ô·"4IÜ äˆêº„]´]á›G„Tùç¼ffˆ¼šg`F&ÈØ»+¡zDç=¼ŽÃ9Æa§3ÿ|wÑŸõ²îž ãÀ舦LEâÆ±±-â+!²ÈœK™4ÅÖ»‹ m!ç4!y@+ Ádfn=ÔPÍVé ·Õ{Ãx 7§æÞ)œÿØp¿¿†¯ÁŽ{>ÎëÓâÍ^¿g N±U ¡î‰ÉÝÍÌ &hê«ùÄ”9ƒ8˜ÔÍ 5°:^`jtqûöLÑ…Ìw}¨…·CÈp‹Ýe#"`öÖ¯/Ûùý]Ûz]{ßà¾i¥|ÀÃÃCmc9Ù{O}¥ÊT[ÔûPŒ<™”R)9{¯Šf˜2˜!‚ÃéøîÝýóÓãËÓVTSaNüððp8õ———Sà›ã„ë²,ËZÝNg?Þ·­Aû¹Ì“PoÐIJti¡…)s¥ž™²Ã]!>¼>>ˆ%¼+,Gpôä}Üö™wh_ÖýìéúsØŸëx>×ÞýQ_»MèÔzŸO“G˜1M“3Áö‰Ø°gFp:MG“xi·Êð ˜`UËt2¸ˆÏ'檞hšó1iÔ¶Xõé<ÏS©¦=½6õìÝÉ÷ïAÏ¡‘ß{š$‡É¦®P‚L)‚™ÄÈ›YˆÃ=ÞZ}!ÂØ{½å&ÿ‰~cOß4U‚$J"Ì1N8u÷"p$Æ×µ°…O%Óþ-ïðÉ7Û¥ ÆãØE,aŽ8Í“ õD r¸Âà½|f>LwÇû—v;½?ã|~Øz[× rIDNV³pN”ùRë7_ß}ñõ¯~üñ“Þžz3dòñË_I"ýöÛ”åt|èŸØCïÒyùí³f0yÒ­­}1 A„ÃáêÝ<§–S™ØÃ­‡Ôê$½YºrŒÂ5BáVÊÄ̦½1s"nÖNébb2·rJ\¦) *nº&P.Ó”ÄÝõÕ<7 ˜j¸Y`$ixelA•¸{˜[¸R˜¦Ø ÐŸ ™Ço¸¡Æ¨÷õÚ8 @`ÇÈ|dòÆžH°OĆ/ÔL˜$Æ¥ ¡H€3‘!8âßoGDñù}þö–”Y$˜’O„¢-–éH§»òp> )¹$ɉÎ?\¦Ì‡ðƒ`&=E“àà™ïúñù‡ß\®ßbÞ•Si©MÓa]oëz‹XÑÁ˜3DÒemëM/k5§RŽåp˜çy*‡—åûæ½ÕöéÓöøhëU®7î ,¹@ù¶ÖËåörñZáŽg¬¸ñXDe)Y$¢˜×ÄAm­}s¼­V·°†óïnøôéÓãÓãVµ”òáÝWçù| ¬——ÇOϺ]‰,ñõéx¸qàãû÷ïîïN‡)t{ynÞc>ßæ³ÈTJM׺þõßü÷ÇïüýwOtÃ<ÄÖu]þáNwÇn­®+p$`’yJrKy:ºYSO’sNÌõiqu baÔ«s ‡…!…L¹ød%¥¶õt̲ùbÊ5\šZJÌdP g¢œ2ç`jM™åx¸Y„©5S…»ÕJãù$Ót[–mm'‘c¹s±uÛÌ](•|辚%Ééá‹ãU—ËK]_f#¶í'PN¯Fñ|ö§]ú¿ËŽÈwæU`hƒUáÔÝ4Qñ™£LÙÌ8½%6¾n™ÆÂÁiÿ?˜†A‚x¤j:ˆÀ)ˆ=˜PR* dÑÂa¦r”è®aŠpû(ŒŽDÐPöá1‡1^ &ô3”ÌÚÌm›¦yÊ‹4¦ðDÁœ‚ÕaN4´Ià‚_$QŒ±?s #E“—Z½ûb4K>œR:–"´ièJÅQÈ|kµž„‚‡£È¡ 8ª6ÎöÓ†O+¥d.§óœ»ª†šêhL‘àëÐ03¢!²NÜMÍ,\{DzM¯‡*¥‰™…dDZôÞ#˜„Öû­ÉI)QÊQký|î¿?"#LÇ,Lˆ€ ˆ„È-\áîfÄ4Puaã|1!0HÀ$:T¯mÃŽNp‡€ q LDG)§\’P… ým2¶t±‡1‘€CÏ?GŒJ¡Aá6xw#}p„«‚$¨ÄБ‘x”ãj[Dg‰[XxX8ºƒ£“{Í%çW¬±£Hšyè58ÂlÏ4…"ŒÄ4Z5·áúÄ«O#~¹)zíú‚ßz¡ Ø#bðB˜SÊ…Á±x½±-@ËÀ$”“{„ ©GïME‰™Ó”¹LˆN™“›Š9{pר^ªÍ»bÜͽïÙRC)xí…ŒþžåU@õæ$Øÿ'ú`¦×ìàNP3ÇXÿA„’“…wÕÎaŽ \SÄâýbú þD±!;¥ È=ÔááxWr&/i’œ˜#2Ù@æÚ{]aª}¹u®aì9gw°@vˆÈþS´f$ã‹ÁÀÊåRî©o"LóðIr‡L²5¤ê3#1Nó霈Ußæ‰›Ña®·õ§GÊ˯>~ñíoŸŠ,SšŽé°YdïÞ«žO^ˆ¸…ƒ8Í]{dǨ±üugûÇGÃçÛ˜Ï?Ïý³óá?ú·MÔŸ1C÷õ˼£Ñ%‚‰ ÞÜC9ÁIr!©¡dÈÀt̉S!É™g90ûÖ×ZõÖž—Û¥‡ ”"Ó´ÜÚ¶Uá @݉@ …à.ûFÙ0ž6ä ]«QØ0ÉÂá° ‹$TÀ6L4fdH‰TÂ9À´ï~Ç1âø‚Äo¯–€H@˜eðR)ÆB”&1ï“#‰03DFÆ„c°vdG€"| ˜P8ÁÙ íÖŠLYÊñ =Ÿ 1$•vy oƬkêd‘"%Ž„Vìø«‡ôáøôýo_â:r(fvúË{I)Çsšòß|ÉÏSWýÕñãïëßJ7#wÚZ³Þ'!'N,É AðV÷ÿÁÜ›5I’d×™çÞ«ªfæî±dÖ†j Í‘‘yàPdþÿß‘yRˆF£ÕU™±øb¦ªw™µˆÊÐà`éO!ž’)’á®jw9ç;" £àÀûŽ3H%W³M­5õAâ‘V·T21µæfVJr5#³’öe¼s€" ù”BJ»RWÏ‚D ažQ6ë#|î"0„[÷=ƒbd€„ä!L¨eRÕ†h® ï/@šcÊ+ÃŒJ4‚‘EH°…Èi‡›Ç;Þ#œ@aäì.Ĉ`@€X„ˆ\â4YáËûâ] kÝ<0pÿa™³ÉÚ£§r÷¸Üß­®×—+©çå¸ÌÐmë°Þûb8b:Ð kÛÎÓóú翽®?až Ód“W^£ZÛª©2ÀT„9àær»ðË“=2]ñpÌIJJ©$¾¿¬Öº Ì"©^·õõk£œó’rQ“+5Š G¶Š© gQPt ‡ä”$E0K¸«†ió®½uŽÀT–ÓñÔüñ“úCÚÛ¡4ÝÎÞû²Ü-I™ëãÝügß ÂËÄÚbΫ{T7A ž@Ó±,™KG 03 IDAT‡ §G8|Cÿå_ˆßÜߦõÁ̾‡z»«*$Å—¾fw'ì\³·ñ(@¨ ¿‘*‚Y'æ=J=à&ðͽm°nLƒSbfsï½Ã,(Ô”zÝ1Ùjð`æLœ)&àd!Šnÿ™ÏH±ïL߃ûM,ß§ÓØý¬'(Â#ú°ý¿%61ˆ)|l«HÌ$áîhæ]ÈHƒGjÇÛ8ˆœ~û‰~êí¶ò!—Ìzsïæ„P&&b5^·­¸ó;ÞV³”d/{†0NT”ºY·Bwóðë¤ák«9$3Qxx¸6¥õ:sVº²KÓì(œ“H¶‰YÁï;öÞ͈C(x ä$á>>µÁ¾ˆÀ€¨É0 Z¸r802-x_$ƒƒÒÛ=1j8ô¿Ýœ²çÀ:ƒ¢'„ƒïHH …ið6è_ŸGôo¨úòØÿ<äPçÌKÁýWÇo¿ÿ8=Jµ¤´¦âåÀ©ðz­¯ç+uã)Mß~üž§¶â§zšBRï¶zËÛúY±–b*@zÑåϯ¯Þz!És^JbÀºêF½æmµºªmÔš×Ú·zë}®ÖÏ­Ö 9—C*иÕÖÛ†tâe9Mª0{"jµb¹ÃápÈtX/¦·àýWÓÖ44 ½c½i×D$ßÿÅ_¤Y^ÏŸÖͦC¾¿;\×z~­?ýô, º?fJ‰¢—R>~øðõ¯Ïçëy»ž·íÚz­mkmÅí¼©:SR³×«õøñr½ÞVºúáxúxøØ??ß”(•”'1ë‰ÒÄ) ÍÔ¶¾Úmåó|Ÿh ʉ)‘5ר͘û©Ì¹y«µ›ƒH$—”…3üÖl[7OÞ-Çef •,Bè"H‚P‡+‡Œà ËäŽÖaÖ{¯æ"Xpÿp¨zI-ÇS™çTJž§ççgdhë<‘µ®µ!EbIÂ'9<,ÖÚÚ»õh½9…ìDôîËx™ˆ›oú¿ÕyyÏe†$Ê‘…Š9YÕðq´H|@·"|<3vÏÖ¡.D’çäîÌ$"2Óñþ`ÑܸêæÞ¨I&.Øe/)\G„åA1)‘Ë(§Hr`P|†ÝX‰±D9ƒ$çLÄî:Œ¶g³1þV©Úâ2Oœ†Ýd7 EX8ˆ2H8139íŒ`Ã+fÂã<}Cùǽö¼õ0Då!LÍÙSFr¨i«Ž”F8Þäyò¥t]Ïf?^ðª¨Ì˜2¥é81•^Øš{†U‚ E¦£œ)ƒ0 …©+º[žffvNãú"êaÖ#Æ9“Cqí1&ùî> á1Z©7¥1âñøF΂cÄÓñº'ßííÔ(ÂXxšò”2çÂ\P£Þ:ÜœÌÝ,ÆIpD¼Å³Â2x"),s³=-2ƒ|’o’.ffãZ~¯N†¤ÎÇ£ˆ°‘PÁþ1º#ö½Ñr’vCUk.=Eðž&‚&&‚º9JF#BÃÛFκËÇaƒÁ'Â,ÕÿêñŒÞ@z7ªÈÛŒ˜„J`N¹$aæ-&`œ K2aGx7#}~}1Øä\„……ˆœÛÜ /9hbãµkJ1¢YïMÏ "(5Ý»Ùþ ”Â{+þËuÁøÕ½qé<˜0¾:»±-g¡ª†7CX`#ºj>û+âqM´‚ííKiÄFá "œ« yMZzw3€&)œ2{dq¸pFJév¹¶ÖÈafH?«zsfLgAÝk]ïî…±õ^;<2RÉŽØ´çóÌf­f¸¼¬>%;7µ‚û?—éôøúzýøÈOON×Ö/(³9QŒÍ hë½®Z;ÌÉI1°‹{P/Q„voÌ?ÍWý‚ ùåö†þ…]ÐuGô˾èÄ…/ÿ*Æ^ãý\JÕÞáλàÍÀm]½ò„„Dеk´è½»VxkI‘€ÒÀT’E‘êzkíÖàÀ”R7ÛÂÈ•)\<ȃä‹&ð&Âx[2“3BŠ`[+!¥ i€•) L<¬ä ß• ï ì+ç_ìBG‚¹»ùÀmÓ×Fä1D4ÒñÞZ&Œ¸¡éçpÀàîûE= šƒe·ÿÓìjªX–9Ÿ2e,žX2|Šå\×|œN§Çî/õ"¯çþü²^ýý_ÙÌ/ç畵|XÒÃä™d™ò7K¯+}ÈéqÑ{òÂ’2²¤Ó¤¯ .K™ ¸¾&[ëÄi{½½á4ξ4‰ö낉GBøP{®­:1IÎSfU5×&9[x˜‚„=\,<¨ºº"af7"²ÍÝë6õ¸›NyI†Ö_Â,G‚Gz‹ˆqÑ»'mfN¾·­ƒ%GD­ ƒENPD§èƒ~.'ßÁëæÄLƒA H „FàsÊ‘ÀFÐÈØíä#?y_°¬>D=œ1r þ‡Z&Þb×ñþ¼”r—ïއCáÆÃ5æêíVq»Ýj­ÙY›]/Û§ÐMe{;ÝåôáÓ_çøáé§ÖÏœƒ§RÒ<á`±à`)õ.ÄìM©wØ*hQ$¯Þt½¬Û­÷~¼Ün/ëõù¹m‰|<œîÇôùé%(sš§ia ×`J§e]ÛšYæ#4[«Ñ”Áª½ÕjziÍX'¨Vëj‡Ã H½YožÓ²,SÎE¦Iô怘ùzë)¨~FýÛlÍŸs–©µðí¥·¦}«½ã|>ÿîw¿_Ûm>LwwDÂ×õúéóã!O<>´¦’Kíöúûg炜rÛêv|”Tˆ™»ÕTäáÃãDöÚoOõÍÌMÞ‡v_äEø›õó²—QÜ|ñ3±ï¡•oá6;ÂÔDBẨ™=öµò>ìHD̪nŽ@ï¼ñPÒ8¡^ ÎDÌɽ SÊÙÞd¹"’ ßt 7À†Ô!!†zGÊ2f’TœGî»ÅˆvÛ40w˜òq¶÷˜‰÷ÏÈ-xL¾>œ’áñH_ñÃwéø=ËW­Þ]Ï¥Uê`û æC æAˆ¸,40·µáµ]^5¡ …C˜JéÄ]{vEøk0Ü”(Um®3ì¤Ö@ ²®sJ"<²YGS9kw¸Œ9Éhì-ÍÕw‘ììWÕ”§/Ê ÀNIbp"Î"™ÆCjO;ÀàôVE1HXHwo’(•$Ä)MfÛ×/g«Ìo>¢C„HÈà„Ðp×îfãã{% †Ô^c½Õæ£É‚Œ8F; QL C€ì$°#'NÁž¿ä@oîi =@c–ÇŽ )Å;>jtn,D#Y~Á…cÈàȱ'‘`"ýSµ¨íµ[ŒÒ D@"JB(î ȉs'ï¦tL²DZDf–œBxJ )ÿ´^œÝf°HB VFÆ›ŠÃNÞz_½vïŽC´A<ÐvåÎÀ¾U9FÃÔð³“d¤ýŽãô…Ëÿ½©#ÕîîDIX„iW’x ªêD2`ñf¨$+‹ 8_U¸Z@˜ì ô!Ԏ䨽/ï9½o+ű”ûС=ubä&"/¯«6­Ú±$Ï< š®ªD‰…%' â]ísN91QM@^ RînÏŸ¯’q8Æ&„ˆêºMÌ^P Ý@mI¾ˆ§tæèÏÛ¯¿~´ß}¦·V¤”b€¥®«±A›í<—1çö¨±s"Þ×kîñºšò÷Å›Nï"Ò?¹"ú|DÿL;ôùúÖðÄ{D,Þ[¡ =oœÊ¿÷Ø­½üÂÜ¢G@0°ÝÖ5èr Î ^¦Cñl×­{K‰‘¤‡W8M`@!ÔG‘ R ƒ3E"vËàC}f!c¬†á tD‘™Ûf©p H‚#Ø 'Ó@XX˜9@à™Jú™ŠôF\J¡ ê„wÈsÚ¥Ú×9­(pO)÷aâ$1œ‚Üɇ$nÿŸaç:zÄqšaÄ`Ôðèfå4ñݼi¿{8Uö4—u½¥¹È!çÓTîæd‚N²Vš²wž?]_žž?§»ùp8Üz[ϯé”7}õ…pâ3n¯q›òüâ·5*‘§)ï²CÛæj¥Ì×—+Â,b&"r û8ω:…Á#N4b¶Úœ‰…h„y8Á‡ÃÁµGç$uë¦'…u6’õèͱ&ÿæ»o¿ûöWr©OÝq^)RôÎi˜ff@˜Y<@P½%úŽ£4šRÌ£ÁU`@ó¤DJUº"ƒä„ä {ÃÊ6:m‡“%Y1“ƒl¤zÐ "ÀAA<(Û´÷h8³ÝÒ|ñ/¨æþ{íˆÞî‰÷DŽ7œËð¶…’“XÎ3 ¶mS_7{AêÇS©kóÕÖµ$99t막2'>©`5¾ÝÖþ¹¿þt{ú‡Z„*¾É‡ãTåZûíûo~m¯íúüZ·KÜZ§èNª3¸äå¸htBÓÖ»f£<Ý}ÈNëöùóñpؾúðm[ä{~~yÏ}ÓVuÛšuÝ£ŠXÜ]{íõ¦-b\¶Û-'´ŠiÂrwdà,g/%ÿîwÿEJ tNhk;?Ÿ·Ótœ—Ô‹Õ¼Îsž$êùÓëßý—×_ý%ýͯÿýR–mQK†ifÂåzû?ÿá¹LÏÿî7 9/§£ùuž­Ûò|Þ^/Ÿ»ù4χÉA½U ³æý¦í¦¶™[J„H~-S,næ5bƒRŠ×í2Mœ¹(yЦj•»¤Y»/à`FÓN5À 3—9ø‡¾yXëùVo-9>Î>ÞmMk_ŸŸVN „$Dy€…ŽO/kÌ^/çÏ/¯Ë²Ìy¦ðíU'–’£FM‰)g?__fóÝü°È*vµM7öÔ»íÞ‰·5àcæjo3­/»£­-èßê¼0ƒë*ÂÌTÉH]E81‚l€2I@ääL ‰‹lB”„I¤_/à€ŠÊ•&1J\}Ûš)rbÆ4¬¡7D7Xƒn€Y ¹3Rb–4:F‘.ÂÎGx°æ$#Ðó„[sK)%!ÓÄD´Ïd}0T͉ԚzÈÉ!eb\Ì6ìÆê\!E±´ò7wümðŸíqïqpbIP‚ œ o½›@åDªPÕÖ·!Æ Œ@w Fƒ«é1Ó1†wÀxd–×µÕZÑ;\иÄLƒÓùÀ±Gë•„Þ;aô3… ÂÇ>yP0ĆÝß¿ôgÛ®– €g‘Â{üªí8°QN4v "ˆõ@ Ex†09¡wk[eÁHŒ}&'‘4È !$cîOäà^É6F”)xo‚†«%!†Ì`'¼ytC ±8DÝ‘w!­oî•`Cr`vš˜³:o„+`) C›E1røFʼÃäÜG!Èq°*A‚Ù€hAmŸ)‡§±mÃÂ&&ëô6/|—Îe(Çu$Aœ=„ˆ‘:Í ’(uî+ù ô•pj„:SÎIŠ|{7ÕºÚeíU{íDÀ+X¦…LÁ¨Ž5âÅõÙÑI=,‚‚¡%cÚóÞéÝr»Kh#– ù…Yñ³XŽ0ƨ4¸õËHËJ’˜;†‘·Û[­µ3çH”ˆ™ £_ (‚˜äF¡DÎ2¸û¸9$`JEƒ‡8A$׿·Í«¯Ë×åpº÷¸­·êÝ©5 {å½·¯>fpÒ’¦œ$q 9›öü©=>&)9Q‚!m«Ï/Ú _}ŧy±ÎaÚ×öú\N^^ëkÂÃWw~*¯¯¯î¶¤tÿðÕ§åó™˜zm‰‹®õv¾…ÝnšCS´ÐÖ‚R "G Šô;?í]yùÞ¨¼ù‹øgKø/”Ïñß&øô…·JÊv4âµúí]Ý[Ë0”ÎF¬Àj=‡ZB–4FõÊÈY›Ì¥Ð /÷ó)ní|»}ºÅ²ØÌ‰sžælµ›ªÉäìE ùmøÒõÄ1\ïàÝÁhác î"TaY<ÄY$åìaª¶³ HIˆÓ!Š™Ÿ ¡”bælaݤ² «SâAþ$)»fÆ jî´ÜIÌ”0u ‡š±Ì)('.™ G–:8ÈÝRŸuÆ´¾^¢ëËËÅ q*ÎT½µj}­Ú:E.i^žn/çÛõôx÷xÿðÛßþöéåéîëÇ˶þôúü´]£N®Ûy=Ÿâ¤µm~åÔæyî’õx}ö`/DHp€¡Uï[^$ÈÔÉŒ-2qÊ,%M ïfÑ…MÈAr9Ìõn–rQ¯½‡‘ˆd b P]+¡|}ÿø×¿òËú´žkЍnf¥Ó(Ùè€í,A0 c6¼éíc×AŒ!§zÔ°Î¡ÎÆèð-¸†77¥ bÚåÂ$ï¦1rsœ'·DÄ ;6x{öád#vŠ ’÷‡l€¦[@ NBpùÓÑN¬úoÏÚÃá4¾\<<ö ZáÓÐçve4l‡²€¹mÝMIaYúE»Fß$<—»¼œÌÚ­OóÃD¬,S)óÓÓåÇ¿{nç. p|8LÂíõY¯k_ŸÿlÕöùõ§Ï7³;,_ýÙëåµÍ²|B3° =¶xÔtë²ÍÓáÃRKåúûÏåÆýøõç¤O×úé§ÐîmÛĹ”ò²®ÇÃÝP̆oÚ½W´ Cc ef=’|¼“—çóçOOÇ©Û*r¶+$èãr¸»¸ÿð÷ÿ÷ÌiÍLß}½$7˜®/xù}ü½ÿpº¿W÷yž]£¶ÏõÛðôŒÇãú¿ÿÿ¡E]o¿}8=|úiª7½ÜÖÈ.Emòp@}žÒë몫‘çÈ2=ΧÇ[L²ÜÚ÷‡çxýôÒ«SÀUüÓu;,¸*>ï¢Ê"Kr¥¥ÜÙ¯¯¯µ;µ#Ä…¨¤”¥^›ºó¿ýûçúûk;~z}z:¿¶×ísc$ Üϳ™¹“ï>|øð‡ßýa™æ§óºØV¦iÛ¶¶nÔôëãRráN¾IBOÛÅ›ŸC }]OI¾ûxºþðôºéTHݨLá a’¹Q èx€½£K~I³ýE¿` ý›P¶‰˜#bwëLÎ É戱W @ò$ ;ÍŸ˜(åd]™œÓ[mäÖÛÕ ³“§äÉa=0i/LS°YoaP‡îK§œ%•¤J½v")eÙjô5º—T–™$añ< ™Dã¶b×0£@„ÃzˆxI`2³yºÛ¶Íšƒ„9SÊS.1O}QÏîNÑ nD=b‹‡»ÇËåµ{“Á±#]pRü™Ð¸ø7ßMý[¡{S tÊ]’MýêÇ| ¡õv)Ç,y©ç`1)siÞo¹ÙD5Z»m…NåH³÷pJó|\®—gœ€†X$ËrJ7yþñ¹_º5ƒš¢¼$žJJ·~Qm %Ifæ #‚Ô—3ͳ¤É4ÜSbWÝ“C 24„1ž?ûûï¶‚!«’ª«Ž9f$€w!cc7 7ã@3¨œ&樴¹º«F^ RÒ¶f&go’98–¹°uK‡\’P·8›}R{Ié’yE1ƒ Ñ»&‘IxNƒ¶sh·ÁÍGY¨v OŠ*ADÈ@až•ŽNGâ™Sâ\Ý_u{V»$Ü›na!NB‰˜ƒvŃ˜SBÌ@r q_<& cïŒø Ü€æj¢G„˜¡£F5Ï$Q„Õ»9$À@ $GŠ‘HÎdLÎð«*;PNœ%è ~Iô”é:QÌBS!umMM1{™\(ŸèÎuÑÍêÖ€µ®µ­³á«ÈGܰB«Ð¹þñµ!&ÉènÝÕRÐáÊäÈ %¥änfn9%NDÝÍÌbÈKöíÆ¾æ²€™GD6 t³áæ’gpFÌsCñ°bˆP¦Xæ]¸ê¾Ehf o¡n#2“‰Z´È£¤rN ¶Ï<]®ÕñrZ$"¨à¸,Íòº®V‘ ZAŽëVË’‰`ÝZ"¨8y F°}|¸_·Ûíy5 e`[ÕQ _?P¦tûôìÖa΄»  ¡+¾ÿëûÃòáï~ü‡í\áXŸð©>-eÒ3üêý ¸.e¹¸z)­{c§É’Á‚ƒH`ï[ ±Ôv!¥¼;¹~É|ëæ±Sцђbìõ@ÿª-‘ÿ“™í¨¼ïƒÞŠvŒ ß/U”Ä!›C€÷A;%°°¯ÛF³§” ¯ÚôIå÷³Ï).] 3Ó$Æ­]âôñàKÿ¿ÿóíÔÛßüÍ£¨êËK"‘’3’Þ#RJèÁÂDêxC¹Þø1;M{_iñbѳxx¬kËSò Íjí0`Õ‹*ºA;˜qH""»¬À j­5Ub±-Æùv½>NÑüz=G¡fš‹g«êd9ça¯²pfÖp¥$A0îÆ,9çËz‘œ’Ö­wƒ!Qšez]¯"SšÊm5+÷wý«©|wx¶ÕW_ú|ÿz÷üÇíÃÝ׿ùtú‹Ç»¯ïýºõm-ž·O—õSûÕ_þåå¼=û¥”œ%½~~Š®§»ºnDòÓç§kkç§ç—óí¶Ì-„¾]®Rí>é_Þýî?ÿ.ÿùÌŒ¿ûýÓ‡ån‘Å#´¯9ù!!ÚívmÿéõžINœR¦`ê®ÕJJdä:j™:E65J‰˜7U‡ƒ‰æŽŠˆl‰¡˜ V!ÍõÕϰ§ò0÷ÿåãÓÔ¶?<ñÖ~ýðÁojk'57Fƒoá•̘9K‚{o=q.ó„T:\=ÜP½7r0wâ³·Æ)HF—ÀJ b¦ÄŒ³íb ŸKb‹ñæˆB&F$NˆÍ"(Œ ¢€9Zk»ˆtd‡QûŸîˆÌì_9Ûæöí±ÃýrA4Îõ˜±’ïÊSw'¨éO°èç”SÉ!ÉH…¢Vµä2OËéTNw}ÛnÇSÊ {D7ˆåEޝÞн¯¸Ù´ úºmçÃM+¡_SÔÃÌí\P½ò$q­Ú7ª-Ùʾ0ÍN³§¾^/·ö ŽZx%ê¦usµZ·[‹ÞŠ wÝŽww0´Þà1å4½~œg‚Ìóq*€KÒeî)·4•†š«…ã0çÇûùþñØ}…¿Šø‡Çé7þõoþêkîçíVçééóóõþðÚÿš&<Ü?Î¥I«(‚‰”,9…ÇVW»µy›|šP¦´µ£`ƒŒèì@°ïÞÕ]sû6výGjïÛŽèO±éÜÕ}d!0§ ¦±‡AZ1à#•ÍßFÆïà²q %œ©‹—‰ÕMµ{k@ ¥i*¥Ì­©VÖ‡>½dáÂÛõ†€[2ÈЯ…Eï=§S‹©5·€Â\vŠ©ï`ðQD™‘9 %b@ºC(H¬ÁzÝàá”(8à0ëÊž¸”’:T[õÂ2M)§÷Þ, “úÔqê8¾›Ê_ú^ýkÕD‚V3ê‚tÄB*Å-ÎÚZ3ë­;OÌ:y[õ²vïÆŽˆmÐ6&G5ó-¨É"I$'ÉiÐ:º‚)•eŽ9õä¯×Wh MH@%t¢àá·Ø™ >~-.îC$ƒ‹N SåÏ ƒat7cûÂØõrAäÌ Ž $4RÜÙß©mœX@Ì'K‘m'e“kÀ%:‰Hy×AÜ IDAT†_ÈPKE¤±¥a‹ww¢…!Р­nn•ecÚH*¯Q¤0ŠàðBÈ@&²¦7ðûÞò;j‚0Œ!äpöJƒõT€žÀj$ÎÒ“4wãx)ÅÎó€!dÄðÁ…ÀNB\سØ£{t zTP÷èäI G„ÓЩuêpè’bˆJvŽ89$Š´{û%ˆÀ††"OL)@§¨Â[¦-&b¦”H²P’¾n0÷æÃ'–§\–ù4Å+{ä ´YÔÞ¯AŸ´¿(YR„9±‡;ÂØ{ÆÈ û Ä…„S8Ó¾„ Á[¢"¿q¶éççîî– ØhÔÇá†pÆœv—Ä»)ŽÄÈ,cçæÝFºàF 8”(XBÂcS*)™ÕUG’Y¸V ´nÌ{ý‘„KŒq»XÞ{ï*‚´Ö{ï"IÆ‹óÓóY„–eÊSa†ZÛjeF´pïó2Žw‚h[½ÞjÛpxÀ‡S¶U_|žSÙ|;Æ´âÿúá§oECº^Ïóé§§KW4æ°7ñŠ€òÁ-ô/þÆ´‰]ÿû?DW½Ë㾘¸¿m¥vû¾ˆóÏ–zêáÕÂ;#%”TRž­ðo~ó««×µn×ëu»zª( TÎé€éÔZëjÂ&yÒPw—ý)æ@0‹Ð>ù¦À?% ï+£½Y“SŒŒŒ±± †¤ä™3’\¯«ønÜ’ád|ªfË"œˆ‰‚!xK¸a'H°HŠ6¤Ø“Ü" ÑUƒi¸òÕ,"ŒÍ]¦”Á<ö–¦#H4ñ>1HD¤¡«÷•ÃÅ4˺½"å~¾Õ?žëSܬë7'Lnfçë jÍðTÒýãt3ó§Ÿ~ZÓuâ䥒»ã©—ùþt¹\H2e?žî dw‡Yý™~¼¤Ö§¾=~(FŠ™èP¬g;óBÜ!>II™ŸÖ®†­™›ùÒD,"0 "#R»£Q*‚AFØËžØ‘ÛW1\VLŽæª[¯7m¾d¿›éÃ)ÖÕ¶þÚ¶;cÄn´£PrƒG Ï:v0ˆ<¬k–äÉC8Ø 0g1Jh$%0(aWÑpFÁ)ØAÌÀßÝØŒpÆ4tÎîJïùu `}ùMNê#ËaC¤!èOt8ÿŸ}çû®÷ggİ=$`Ñÿãø™!3KeðDœRâœçb×µ©Î2ŽËããñî¾×-¦9ƒ©{ïMý\±­m3ßÝÝéñb/Ma2É Ö¦çö|ÓÞ½Þ/”ïƦÂ^°^Û늗*‚ô™œa­¯·vY+šâ=‹”EÅqÙ˜àQkÍ‹d8Mi¹^×í¶ÌÄNnÎôtÞT‘èZÊg³¸^M)c‰”K†º6f|ýaþæÛe>ÄOÏÌ-eä œ5Ø\Hfùþ¯¿=¼n¿ÿÃçOŸ×m£óë3Ž3 ‘G×þŸÿÓß®F/·¤wÇeÄ_hß•÷y&æ2•ã²ioj-z‚:V·hê=õ¦Ñ ‘¦ûæã÷.–ò¹·hùÌ‚Áu½5¯aŽÈ’–2#¬ö­j¸âbm[[ëôóÛ¦·rßÓ"„ì7²+ÕWmçðm7"w¯‘” Ö“Õ¸ýú»¿èZ™œÄ×v]×µzCâ›f ð­ßV¯~F:Bæt:Ý %„õªØ¶”x9pÀ!@louš…óøI|îy-ˆð×Ñ?ÿ(bwÀˆ¯ ٕ逻"rãŠð0ä]Gࣄˆ0ß@ÀLȲ,K«ÝšFk¨ °Y“7\UDhïe6‚GtŠaèiC¾œ³ø(‡lü †pqzˆpt÷ ½j p’œˆáÚAIRÎnÄÎè h€!Ì"¼Õé(3áÈø¸<þÅÃñ¯öm×ãD·ëår~EÝPæe>ÞîƒÒóõ¥½¼"¡×"™óT´„…’’€B9>zl\áìa¸‹zéÆ=?ÎýêPdB)½DDo†k…N,Îw£®ñV™ Î+½™"8çw‡°0s„9Q¼mÆß®øñÉÒ?·08 dN2{×{ Ž·hÂÏO 0ØÂU$‰@¡Ž±4‰aC"BÞR>™É…Ôm5»ö®B¼cè­#àÁàñíÚM1ê»Gl˜£ÞÒQ†z?V´ ㋸½H.w¨‡šy‹ÐA+o2¤xL À Ä”@Sáa°¥½x}ÓÂÙX‘ÄHA w8ƒAIxçÒ›¾é‚‡Á"ÚûS€E1;&æ”'1 EûÈ>ôpSMÄ ¡C8±q.) –\¼÷ä}n '­U{³ö½ñT ‘ÁµKîßÀb˜$2²¥~öQì"À_îâí{Ùàd–`q„9;RŽ@ôÍêN6¤‚ÄB"æ¡îMM)\ćî~”™Œ9‡ÝLšà1ÜIH)ÉÄ­²»÷Ž’Ü=ÌÕ|—Šr¾ºØY–Þpúùøª‘­Å|äišÊKfäd‹¤¯î?Õ×§Ÿ® èa:)”Ž †›Þ–¹L“E˜ãxJKén××›äÄÞ—e‰ˆëåõ¸,Ø6¡4•¥ÌK^Ëã‘Bã%¸eõÖ-ÀÂìNÞAK>ܵ®f5j5m¯‚")e¡àLRXÄQ4²9{D„¤U5†S¸“¢‡ß »D™I„˜Sw«¶—Û,ËŸçc×Côç'SŽ=”e<™b(á{x3g7¨jN ÌDâ¡ð´ gN ¢x ~nì)|{^9€Æ(i‚ÜUÆxù‹¸êý<~ l„Œð"Éw[ÙÞ¢ÌÈ‚÷¬ð¯ÍWñ/£Ë~Ñ Ñ» üç¦è­H¸!åD¢øðõ,™–SÊ)’)OžK>>,—ëÕªæB9Ë”óq‘Ó‚R²¥á½mÛ¥" õi.'¹ŸüAüùåvmZƒm:¦¥±ÚÅüæ¡”–ûû;"‰×¶Ý4magÓ—Ê7¤#–‚’j-žî€:€U>Äf'ñÃñøøø1­×U7¯—m[•î݉¸ÌËŸó¸^nmëЪ˜}™§ÇÇÏçM@]²~ÿõñ7ÿî»»ûy­×ís)8ž²>_üÛß_3Å<—ï~õÝÝ·åîA~÷ôÓ?œüáÅý_ÈüÿëÝiÒvûíïøíïŸÿøŒk…ûëé„Ëív­Ð@0lƒ"Œ$©Ì‡SIÚuík»üñsÇÕoÜC‘+JËÒ2*‚L³“ÚÐNfÛ`‡X]7Ã(‘y¹?ž§€ç–ä:®2–¶mþùómÝ~›&”)ý?Ľy$I’å÷DDUÍÌÝãÊ«ª{zgË!~ÿoC\œžÎ:22w;Tåàj™ÕÓÝà,›3‰B!Q…ˆÈŒ°CEÞ{¿'¦X×5RãÄi»Ô.jUÝŒæ¶]ôuxýú/?;ëbëÃ÷ÃXîîã$RɺøZiõ¤!x}YdÌã†yÛ6u òu݆‰¶­w;›5 Hú¦8þBø·û?ϼþÿ:u z1CtýG'ßšZÀ´ÇˆI˜¨[)éŠÉêùóÓ‰0#wCâ4N!H%K¢õyéÖD¤ xX«æQ†¡÷ÿô¿{f13«ëÒC?ÁB½å¨¿ƒ\¯´ž-Æ gFX7)¢Û·s°¡‘;‹qOAc‰uYABÜC[[W³È†0Œ†S—CúåëdT@Az>/8/˜b½Íw?ê²ârÁ8¡5£tøp’;QšÊèLªš‰OãÁ½(·†¦êÁáÙ› Y8J,sÎkjskçÖ^.0¢ & AȵRöm+Ûžýà9wWóðè5©¾1ké H×Ó°ãÛ¹ö:À$QX˜ȼã`ê,sÀ½“˜È÷QÖä –ˆ@(úJ7Œ™ƒù:oX„¹+@$ ¢-bUÛÌŒ’¦>q}£ýzx!êÛY!¦uµp³à$AÜ_§¤}Ì£ëéÖƒLíNÒC¶ðÍZ5Ó7µ“ö/IDÞ1ü\Ápì¤ †QxƒÂ#p%¼Â-|ï£@Ï«ï£ÚŽºò‡@tE(âZÉ!L Nð)ø~Li2qi*î‰CàìÎk ¦®AÌ9%K*™NäˆPKY2$MBz‹‘ÅwˆgúmS3 ÑûŒ÷[mg\[6ð6¬Fôoê÷çq”‚Z #†pv—Ödn„&d½ØyhÆ@!N‰#êÞ•àBî@P¿JÑÕIG´¾ÞyOÈ]Cíãp¨ëÙ¬ó­nð’Çf b¦"Ý»BÌÔ4®)»·ÖÌB Ì}^—ÍZ//†aä†r~}næ—9ª2Uôª_§m]—ZŸUW‡; c d'«º5§›Ãá”W#óÄo…^ >Ü:!¹²›G0¹ÅwÑw{½XºäÀ÷$¾ñ8Hz6± G‚hg©ÑÞÓµoF®â]Gχ;)$¼¹‡á[§'Eì·3C8®;¸´™zçç›2° jçA’™¹{ÎÃápÃôt>ß¿SñzO˜‹{a†®Ûy<nßø—§‹Žî¼ —mUÄÝÉ [fs¯õ¡Ø|]Ö@”!QŒ< ÍÔ¶°J¸„SØ4Q"ƒT·¬ Âpí}×'§ IÌàÄ9Û¶íq~ä_Ú¹M§S²œ ¬±«-×lS"iÞ]ÈÝû@)% WSUU†íȘ‡!¼¿=÷æoï¶PC‘°ôU~ÛD|+èí0œýÕ{WüþÞb1“ôš©«Ôóíî¾~Áþøü«‘ê¿×5GKã ÙoöWÁבÝÎì)ƒ †SïËt88bmK£uùx;N7e‡¡$«­Œ<Ü%#Šç0#8•ô_þË?><<ܤ֔y<¿âå 5 ÎóùÅN8ŽÈ…(oæfç6·NÏ5xs°m0”OÀ‚um´¶âC¢âŽ/¿¾@‚ Lmó¦k5­"ý $Ho¡Jçù•Ã0¤!•qÌyY–íò‚œ°½ &Ìä%µˆFätà11ÃI½msÓªm] —üîbîµÍ«…¼ž_Ïçs]õæxKFB‰q¡Ö[Næç%™¨hÕù²pC.PÃáX~}ÜÜÁD}ÍÇ99ܽ}hâëuܯŽËù;ÙþÊý’R!3ÔZ[k’Sb ްèä `ˆÈ9ís]FqE•¨»…ƒ)ãéökÝÖuÍ)yÀ<¬7±‚(àaÑ3õݳÔaapm0G8\:{º?‘¬…Ãá}ƒ—ÐÛ3™!™÷7¥ÌyHÄ®:V«ªê¾„S&R-V45f˜F¸šÂ*Ÿ p¼ãÃïKú½à‡XË+½äÈC›h%\ Οò0´³¹L÷Üqe8cÍnd ™‘¡nsܳ-ÜJ„d šHDêy“M4¦”©ñ:oÛy‹‹ er$Î:(Y*uÈ+÷: ï5öýè0ЛXo§„·?Àq5ؽµW“÷ žº£¯{{'ÂÆu÷»›»¾3~ ÷±Ù®B=ƒ€RrÎYdG5wÝ&Ìûú>²xJêÖ(” OÀxc ÷Z ¨HºrAŽ”;Á;?9ö‹Rx/°$õÆ+Pˆˆ°Dbc´ð°¿)Àª3É•~»Ã)$Ù¨ix…+…õtÀYûtJ;£ØÃM-ÂlW“º?Á»ÖÆÔçûÞ}AˆqOt¾‘4 ™2oìU< #—Œ!03 ]çJB‰³äÄ`afÈ}QjžV¸E]j›ÛºÀÂnáWcàVÜë©üøÇ_¾¶ˆß\›¢ºmstY â[)×7-†¯{è7ÜðoÕ¡xKÑÄÀô݈Fí9"¢}Zío1w8Œ)ˆx§M½®:»6 Šà(¸IàLµÂ-”½šn5Oƒƒ9‰x{*‘Q4 Ö` áÐþfÂUvý[+DÂíê!(ÜÚ6íH£oœì ÈÄ}ÃqUzÂÂ@N{5…"z2{%þVŠÍÄ>ÕïÛ¨7î±™¹Ë.ÄË.wÀ¡]v—î{f§ét:ñXf;óÒüüŠu–a<”™œýx(mœ~øøðÃ^>?¯ŸÏ4M?~sZ–m{YÚ²åÛÂÜ[vHJ¦ÄÄqy=Ã\ÂÛåB5¢ÆéáæÌöøôuYæwïNé~ª—†÷êpÒÆN2ôÇ­ú¹Œ¥ÏÞ^u«ªµ)%3 Ÿœ§@aN©³ù•¹»â˜÷%Rßa™…·0‹ðÐNŸ'÷®¶<¾þ|þå|{s*#]6,z¹6ï[º]ïpµ~‹xX!"SHU·D-àDAì,ÌèVE¯:vÞ @S&¢žRF:Hihò5•cÄL½¶–À qísØ·O× N¯"à=ø74¢¿ËÎ{ÿÏ»E雂Y2vüˆœ2òÒQó‘‡Ût8¦¶^ÀâåTnÆ”ƒ²§B ì®—ùu9ç$…8†c†“!œØ4Z5×P(Ïçm[¶Ë¹n¯•HŠPsssäxº½½¿ óTJÒX-n¦évšjʾ, –É™îÆtw_¦òé§ÏœÏó¡àãÇ÷ü3ÿúÓÏ«¾Vªóò:×…ŠÞ¾›ŽÓáR)ü¯ÿú/E<¾>¾\Î0Ã0Ü&ëóQŽyº9”ã„mÖ¦úòr¶ªÃ0Hárà››ôþÇ÷Ó]qÑZõüÓò¨¯ÛÕµ9ÌÂÉmºzUòl~Ñ1ÉĬdµ­óxkõõ¹åa"ÒP’ ˆZ—àÎH9†"¯Zk[µÚAƃ œykk´€º!BâË_dBc ‡ùt¸»¿¿çœ^žÏáØZõ¶–’.Ó0L§RÆqy¶¨Po­µf8<¼¿u m|¹lê–yUÌɬ…Ó›Çþ·….Qü=5¢¿nVD2ƒ6WUïq¡ÃqŒª^aZw{7ò¨×?XpÀÉ÷JïÎ)e”’Æ©47_[Û¦tëfÖj3€„Xˆu«)%í6ƒ:1ç’»ßDÔsÖ®Á‹é{ù 3˜…(!â™G“¤’y í éñ·pè: ÷á-Ð*¢"1 §C 1Þqù!ÿ0”`gõnóÁTÀ«Ôµa&, œ°@«o<#9 N0HdßÜÖí¹h¡›ù¹6£eàÂ$”h °Öd-o”špR»$L)’¥YÝæÅæÆšS… @A×Óx ÿ¬f>â›fNDA´3¡ƒûëW‚Â:(‰ÞØûgØ«ƒBµÙ5NB!=bÓ¯Å},̉‚;dÉÑã6!Ô;o»!I¦i,Ösë³ýÅ@ìò讹 I…¨Wæuõ¡Û*@NÐîÍF¾óz’¹ëÕùhA=çÖ¹v' $ @Bq)E Ĭˆê±{ú„¢lÀ éZ $û‹ö…ƒ"„‚˜kX5»˜^L¦(X÷ÎyïSA¼ÿ†-lbí‡6 ¸‡3̃‰äÚ6›€Áã^ä1‰¤$ʶ¢-0AdHIœS„e÷îœ×ÕÂçV½VH†.7‡RF“јm±mEmp¦+jvôúrcOïìៈ@¢·n;w÷@àjPñpÚ‘JßtïrC opxä #r0©ªÂ”¡ƒPv>*‹ÄJÔödœk_ß2ZtšnøÞ9F;ŠšBÎháÑ[Dš©.5IDµ_Ñh ®íæî䡵VU7³QÆñ›pÊÌ)¥”U7õÖcôêhóvQ˜Ck¦B) ‘³‡j‹Ë«Ë-¶—e¼_]ù—Ï_DðþþA·Ú.ÛÕxuWWy¹â¥þÉd°@‹Ž]î0,Áö[äϺ€úÑù»î7gã–Lô õâÏ^SW,^ÐÖ’€åЇ»~øÝ ;‚…%#É)³×K%ó:¯µÖ”Ò ¹… gws·fˆ`îBEk•ØÏ”ßU3íƒY_ÂsöZMí—”’t¦I÷GN¥Å¢+š î õ¿š%r q÷Q‰\Ì[¨[gSSÓŽÇ  g‡'dæ½ùš9¥dfÍ­?©÷=_Jý®vw3¹’„XÆq,¥èf˜|^ëy&u*mJº=ð­_bþÝý‡OÆ) !;eœn‡‘ò<·íõ²××:rÎïÞ¿)]ÚVJY×ù ùn:®/çI(Må¸`^[‰•c>ÿzDˆ2N0j5RmE0¦!§H”eÑVÝFn›&ñ!s!õ%‰¹lK[篵*Z”4y0ŽË<7Ô$¥”DO¯O—ùìnÓ4 àí²AÛýúÓÿ{ªŸîH0ÊèÛ|yÂÓãEøÉ?ýôsµóO›Vóa<•ÄßMP—××—m‰d^‚‡cNwîîÛV Çãáö¦Œ‡¦ö¼ÎÍfmæ”x˜ÒPŽ÷ïOÿðO¿¿ûp³úe]ê¯xœŸçzQ2‚‘…9¡™3CM‡‰ÃÈÌjBQSÛ.‹«‘ ¹Ý2ga7&“’Ò4˜m—.CÇ›iºmÍf¯nè|£”ÒPQ4o&‰ ñî&ñË¢KÓZËi$æmÛŠ Ž×°ª–cx|8Ü¿<½ÖÚܦcº{8Ài¾´qˆ‹Lõòê b6÷½cò» Þ¯Æÿ„ÑžBé÷|/¢Œ€<%qW˜#vr¥‡…¹Cö÷_¯!s»ÞVôvcš™yë_q9_Pµ]_-Ô]C¡Ú=+ý0Äýebg†‡té xpJ½…³ó© ÁÁ;¶.œà®ðmƒšjhÊ¥Œ"B)±‡­uquÀz…&© p ‚8ŽÀGáäï­ÞkÜ{»©éDm«í«ÙZÑ< Ãé8<ÐEGÁñ€³<汫ÿ”sÒM·×—FË|šòÀ’Š¥PÚàk(4e@Õ¤Y¢¶µ­Ùº¡¬ØªI9q„ÂÌ”ˆ2¥žbŽäì×FÀŒû7<àêÚ;ÓE$ÜÝàfÚY ÂWšÔw½Õ˜o`"–ÍŽ€í{×”8 ÂÌÝKv=W2…õž’Ü/fë¨qo¶Ã;H Sêè^&e(¼ÂC¶ç‚z±#1£cº­?Ü`A`ÉÖjŒÈz«¼0w…ƒ¾u;t;„¢,|S]µ®ÖªÀ˜½¯ãJ𥽉Q„KJ‰Ì³[&*$YÒf¾ªÍ­-î+£ Äî&IŽP²ˆHWªµ$ôd¿mzñmt£I$Ç`~Gr2ÏáÁ±’¾ú¶ÂÁ¸c$ÂàL.ÄÄ4ŽÜàlVÃܵ¬zwRCÔÓF±º®nŠ X„rÿA_o÷½´DAÜi¶û÷BˆK‹ "ŽÝÔèêN IDAT%°±ÇZ¾Ùºr‚¼™ª1 F,2CîŒ>c BFp¹»)Þ¬õìP Ô0%yƒKk8‚\À`jaP8 w°¤Ú6f‘®4{œsRóeS‰ °ƒk-‚"(†a|ó}u+Ý^{Ï$iHC1³Z·ÖÂ*<ðôÔ¦ e0péx8„Ú|Y]Œ¯?ÿºŸ_  {ùú0åüÝå§gQ†A×TéuþrF:Á!ÎFoy 7·+†ô*н=·¯>Ò+YÁ¯ãzÐÿ×ÑÈÿÝÌÒx;Æ®S]~›©ÑQÔÔ·\{ªyôÊíDþûßÿ¡µÖÖMçº^êº\xƒÀâ‹nçum8Ý6ŒÔZ ƒ9Ožïd}6Ÿ~uëY\ÃE*¢ DƒwYœ˜„˜Ü‹qY"BÝvKV·Ï1œÙ‰U°¹ŒÖ8"±5oáP4s*ÉÐñ7Pw$ì1Â`êõý™œs®­QÝðæaÞëÔ˜8(‚E8§žaë‹ 3[çúøòüèzy|"§µÕl¹ö¨þ»ŸNÇay=“Û»‡»Z dìÍIÃñÆ2Ïs <ÞW²mÛJ)Þt‡a|úü ó$ ºªRnJJhºl˹09’:Úfb~â óu«®•(&ç)øHE…Cá纼®k%ý\‚„ÙìžJ‰ÈàL @p ‹¤à„H„¤úT< ””!“ÊШDp$ s÷&J"„¦¦­…SJ €ZÝÂ2”%9!d7:·0Chxì3«9úZ­óNºÅ2º‚Ð/af„ÑÞ©Âýj%¦7!7П“üí¯æDdèÐÑ»Æ÷ýΞdÃß`ÍýûîÍ¿¨)ù·>]ìmÔë™ÁN]1‹2Ññnxøxsó)ß}’|“sIÜBs6Êi  UçIà ¥Œˆ¨­mçùrow9Sh¢Û›ãâ›yuª[4R˜ñzÿ|7ŒƒLïËøîÆsY•×µÆv®’Ê8¦ÃMn@“­¼žu±ÃÒRõårþzYmVË|Á¼jkÎ.lÛ¶,ËašÆ±L›é‚¦p³e½,ó¹µe”|<Ž*³‡­­-¯tCÓä©HÌx~\þ·õÿøåO§qšæêçGÄ+Ì>ÿé»l:ðåy£„»»ÎóæãÝû÷Ÿþ€-ýï_>??náX]fToÊ/­m‡ÜTC[ñÍ‚#”uµmÙ"ˆ„òÀÃ4 i)©$ÉBå0¥D¯Ç”&– ²`H›E„m¦^5ªÊÚRÛ­IK ˜ÂPÕ[ÎB„­)µ¦ Œã2Æîóx¸›¦iº¹¹—T¶íµ¶fὯŒ2M#‰oÈBaIôôõUF<ÏȆá¡>üðþx{N¿|þ’R‘Õå¼1sÂZhÐåIë&!Ô`ª-9$ÉC)ãÀ O"ô—È ¿=þǹæÜ÷Ê‹·Ó »Z€\«[‹0êæ8‡ã1œ°×j9,‚½m–…UݶÍɃiÊöå‘ ’rbòÐÖÌ Bü6‘3§pAÇÙNH"¥Ñ»1L$ ˜=<1 ƒ+ bªfH¹Œƒ SJ™×unªÁÊDÍšÀ)_IIƒ#9¸Å$¸?°ŸlÔsCñÑêÕÈ7‡ÛûO¿ûtûÃé—øl‹òQD¤©(’kÔ~n µ:7<ÏXÎÁzn6ÞŒ%•È´Ó !'0ÁI«Ñ¦Z ÍÑÂÕ°yN,,hQ¡ÌÈûüüç5%€ïs÷ž8wïnø·àܱ—Îì°î£óëôzAè.ÐIOeQ÷ÛÙ^EÛ÷ÔiÑÙgLN½ˆ—„(‰n[Àl]7¨F€ %%'ÉÔëÍa„F±ÈzaàÑg'â€8 Ý­µlDYW7‚‚œ{5*±˜=´;0Å èÿD†˜(Z`Q›k][@á‘e¯Zÿ­f›$‰P!ʄ䞂2Sfiá5b ¯œÉ‰Þ§þ}ëŸQöã¬íY]¢>£ZtFOhà ˆ#ŠÛÑä` ¸R[¤]`#uˆ™µænD@ J fVSÊ2L㘓“{h´-·jçj+¢¹6Ð+ÚªUa€‚:ÿ7èÛi˜® òØ‚Ý(ÒÓµm†‰(:V~=Ž÷³EÇxßò47U cvI@î}+ý‚ugGR*N‰-zŒQJpDó0†Åu\ u4q8Õ^Ã"‹PÕÖbHÌ̪Æ$)•*ÍBÏËê0­ÚˆvÈ ªÊÌ)Iç‘ÔZ­i³ðŒ2É0ä~rÈËK–ºn8ŸQgØ]ÜL(Ãh­¦Lé|y]^7 ºá¢ø§w7Ëy±j§áFù#¶2?ÍÏ—_ž?|úÃå²|}¹Tç¦öúz†M¦áê¬ïÞ=(û×/甥†&Nçå|©óÖÖ¡¤)èvyYl›uƒJƒ-FZ·×hžÑRòþŸÿ)©ýôßÿ/=Ç6ãÿ~<§|æñ+‡D6­/+%;NòéáŽs-z÷ñîùùiüÇaŽ÷ýòÇKCuÁ2CM'DÕàåáýt~\s¢$ίçç—×ó²ª3ª¹’9k­KYøòúº¬/ZÖjõéåµ¢Nw|sWpX/Ûç?ý|¼›Ê@Ûº¡øqbJ>LðŸIŸc^"'ÜÞŽdy:&Äe™uk"Ôš­Oç’óííÍííiòáxäœæ¶)ڪͣåq¬QSˆçÈGa"²ìË×ùáÿëCè—Ÿ~þòåK*ãû‡w¿þüu¾œ1MÓ4¦"à¯_¾BÓ˜Ku3­ÃJ0öûww®1$­.ew¼^Î)%w} V^¯ÿïbEÿF#ò¿Ÿ?âÏ^¢»‹)%f j­m>c6_Z6luœFª­¥TîfH¹µÖ7Þ“ˆ] `–ã±¹BÍ2¶Z9‰H†±œnmV´¦FÌÄy,ÓJ«Yø¦"i €ææ…s7çtœ;‘HJ©Iä½f!Ì”%IîØç.;PׯSI’/çóó×'ÊR ØÌ´WWcãÁ2¦˜Èó6¾;ê©éØŽÓvc•Ï|È‘©! Êaœè¯xžùœ² U½âŽàõÜ^ÇÃr—q0>­PE$4Gb7 çPF`†¢¶Ãø`‹“ÑÀÃ8”çlî+– È6ÏMõ(ÇRŠ5úÃ>"ºÎ}5Õ7ܦ¡µ ‘4tî\¸[5ßs"" é¸%o­7Q˜ C'ÂL«•$™²¸@ÄŒ `p")IUcSPJC‰¦jZÆQDZƒ»QfsÎÙëÞ5'Äì‘’’ˆÔ°Yëb^™lWÔAfÎ fóD<%åá².ªNY@´Ô†Ôcf;,;Ü<¬·8áÂR8³ìÈ $<…X¬é²,‹Cœ„„ÕÜͲ{8Õs§¹™I`Ê勈ô ·[ JLÌnÑÌCû~×98ìÚ’þæ÷„……vÜYN‰<“×fcfÒæŽƒpnúp{ûËè‹-m$: )È™¹”œÆ!¥Ä¨ªµmóšÆÁ˜ƒš³gáû›ÛûTÚç_oÇt æ™–Kmk˜ÃH<¢…_Sb÷v/„ZG{Ó5ÒïñjUÝZ˜º;±14\ ¤=vÌľÆ0š›‰È0Œ£!Ì$ˆcÏöEݤo®­¨›® ½û }’õ «6eb),! KYGŠH_0!ÂöµQ’l ‹ânãÔÞkºÃAA¤ÿ0 JĹo,hï;rK†…ÍõµšLµXÝšjZµÉÙÔ[D3Iæç—¯zΟÞM7S h)Ùš¯óFKÈ °Âk.vÿaJꤗâ5",ÒAŸ¿pËâñ ÞŸ1°Âé–~wš~ãŽôh½-pÇrÙ.çmÝ0¯¾ÍÛ¼A*æ¹é”&Î\‚tÌ©…?=gŸqsu`0&¢ðºžÅ} ¯ë¢—¶©Xìý»‘ù,Â>Þá _:?A€Ñ|†ß½ÿÇÆúøô§Dü0¸ùX¬úZ SÁx0æ3§›wÓtwóüôúxŽ­*K/Ý©j6H×øúø(|fÏ[U«UáiJáØêl/˲F«KaáÁWz®Qç @nÒxäD‰é×¾¯Á8âý§»t¸±¼._6ñÅVÅó¼¦Â·÷ww·÷ÎÏÏôrÞ´™Â\RÞ¶-Ès­91%âA°6 ¼,«Æ:l9•,My ‰eðˆ2âx{8> mºmõò:*Ûy#ƒ«·­mÄÉH·¦ÚDd† Þd(§‡›w÷|Ñ_úryZ—eÛ6x—r þ§uJü5÷iwð\ß,r"3;V»÷× ½õ†‰ôå3ÃiÏa]ãþìWè¶Q£.Î̽õ±ë áfŽà`tƒ5Ä‚©¯1ˆ™È˜˜‰Ç!«ªª,ÂŽ ¯ ˜Ñ¥s!3§` D²'žH(BÂ):ƒ—º=…ᜈ§’†DCxÞ,Í@†’Ëû‘¹Œ¯‡Ì© U¥úÐT6§™é&!ˆTn2JX¹ôí¨œkÍ"Sá”*DL£z¡´&n,“˧%)PaއiènÞ÷Þ©N¿1…ôËiìÃßí˜DXz`Ý=üÊf'¢^AØsXÒ2à "I”jU¸{YK‚AHÀ§,à¨!`âDf´W\úŒö-éÕÞÜcãÔúKÂÂ׈´€‚:'œ…8ˆIf?¤<ô!­áÆ.ì,®Þ°ƒàüûÀÀNyrRP†$…öÔr 7¡PNH)ö̇;¤#ÃÜ6SohŠ aÒ»ª°Ã{t;‰™‰ÄÔ BÌjÝ¿£Æ ;#É{Çt`Ç »…Âß&-¢®U @ &ˆ À N¬$¹:„IˆXÀ²—õì ën' '0StƒíôØþS_וÌÙ!&r@56Õm6M)í!ÁýÏ&’{X(¾sšá‡N—å\7̳ Œâ«×­¶Uü™OãñøÃD¦cÖåbë¦ÂÈœDðîþ€ûÃ}éó×ÏC¦P±f h[]öQ¯;]¯‡ôèî¬øs²ù÷Пç|zôëïHâÝÇKô}À(nÝåepJâÆ"BF0˜bƒZõ”Ê[áXÎà‚¾òO)ÊHIIBp3÷·÷V„Áß EÁDñÛ­¢÷ö•~ÁY§Î;!‚p!s{CÎTŠ” H8I$ŽÄ&¡ÜC€J‰Ww¥!{ÆÅ›2æu òè6¹ëÖÍ,眨oô¼órJÜ9+¶OýqMmJJ`РĉˆZkžœ¦épº¯FåfÀXZ ˵êvÞ¶×íåóóãÏ¿Ž)Ÿno¦ñ„:oRwÇq7™Z^‡\ãôù_y|üÚÖ”Ç`Òxüåq}™ÿÛþ9r¾xûúå—åRŽH¹:µ¹¤” ¨ºµ@<~0°Í·æ¯ëÂ.‡CÖ­ŽDÌ‘²äøÞøº‚/M‰ ¶‘zbJ)³d8ª5é.2êÔ '.ÔëÔ×mm+Ù˜Ýõ8Œçy©uc¡Ä²˜aÔm‰«q²Ï*N=ëFaW– w½ɵïÀv¨ýÎ íÏ™è%.Ðð¾$²Àþjg!8­+æôF×åté6d‡<ØÚ;ŽÁ‰ö'‰þƒ|otHw ²

ÅxHåÑoßZšiH i’a¤\ b;ÝŒóâ_¾\ž. Ù†ª¯e—¹¦ ¦w9ÂÝ£I‰tp9YZÙ£Ñip×`"¬©]Ìr`ƒÍ+µ6¬8žp(x÷ãáÃ{~7m·O0¤dËmÖu±>êÄI†œêÝáÎV°“ªŠˆº- 9¹H©îNã?|ú˜2^_‹Öm[gk Û¶ H‡Þ=Œ@-©¼ûô1VÔó¿ÄÜNt{sÿîöÇUÏ­¼N#Êtô“é1Dù¼ž_¾ž}}Pò;s S¤Ù8Éííp÷ñøpw{yšùúõ—ÕëšÙD$K"jœR¯]‹V¡ê¢œ†òz®ç'T…{ÍüuJ‘8ßÞL†1•Óñùçÿiú,o—/ëÏt^Ÿ?§º0‚ïß=|üø1Hjm;Yµ·ÚLÁ0_ç­ÅS^ËÜõ¦Ô{qPa ´hçKÓ ètwûûüÝý7/í¼Ú²ÍK»h„¢¢02)tk¢êmY=ç Wo)‹Lƒ‚^ίÇ4™YS« ÍÐÙ`Æ{iC|½ýOœ‘öqq@`H"5bÞÉ "Bˆð ‘ZDr•t#¢y_AöÒtÉ`jQQ[¨ R’BDðýÈîA Ù‹[¬—¢€ˆIRX?£öZ†k¹²¤\’op«aÀ›B Tº')%8“@­³³{8ÜaAAÌÌ)DX\ ͪú€Í€H)‡Q"§QLÛæÛ‚ Mî^ )27ß¼Yïº53VOÄú™pqßsžŠªQPæÇ–ÖÄ‹`áìéîpËw<¿¾ÆË éfâëK¿H®|¿ß 4{‚ȯßÑݵ$‘þ‚îW3sJÌ)×v™ßŒÇäÄÂýVêãë^ÑÙcAá0E(0ô€rï«#7³P„w ·™±ñ›AÔŒªBÐêV-j§( 7Ë; C@™P˜y(,ÍÑ¡oÖÍD-à=)M@ø~¶Û©ÖáÑPQHŠp&Šj¶¹ƒr–’sÀƒ‚ö‰À·yðöéj^t—jÞ¿´]ÿÝï¦î†5÷îí×îì@éƒ,ÉÚÙ©¾,ŒD4rS:å’2-¢«Ø"hcÄÀ’yâÑY´š™yEÝ48pF'83 \†©LM‡ªÛóÅ´Ä\ì¬mVSræàâFWßS¼!L]të~¹7!Ài_mƵyi§_Ó5㿳AoN($––hëŠ “nªÿqoÚ$É‘œi¾ªjfîyÔ…F£‰á1²²ûÿÍŠÌìl6U¨#8ÜÝLý`Y ¹ì‘Ù&KJê¨ÌDDº»š¾ïó 8R4r—”#ÒÆŠB‡3§°ímÏ]âAøîì ¢omZólÈ©ë39‚[DsK9#I˜U×¥µ¶¬&b­¡¯¾àNDªÚÉ„i,6 3¢¤<Ïóó±éü~¾ ÑÃýÍnÏÏÏOOK­¸£*€V7s¹ç¶®_NÛ\É0òØÔÖY…ŠjµÕÓÙ-àä[f±*k¼$B#^ÒôâUü7Èrýc¾¹пg´¿Þh~›Ðþ_¹a°ÕòúËZfSƒzq‚»né R÷Å<R–BB c#×°q8±™g‘j=ô‹RÀ…¨ê,²è Wf¹Gw‹A¾éSu}ÓoRâ/‡ð+®ñ¿þC °D5‚H½íÍ_´ÏŒ`'6 ƒk˜Ye8×Z§±ù¥­`¦~Å`Ú~_ÛUá —ëªw C03 Næn¦}bïTˆÖš‘¡pDÌó̔ǻý´¿ùüôœ†’§ññás{””•¥þòþc 9~:Õ§y¸I)„=–õ‚ÌC¨®Ãnbð,üÝë7ó<ßîHý~wاòé_ÞgäUײ緕­9àÔÃüWgñv $ßþz"ê 9òëçbòm\'xÀ ¤áDÄÿ!;¢¾ÉuéúÕNH-ƒ¼}w·MÃ{¾¹ÍÏ«² §„Ä4Ñ0Ò0QJÌÕ¢žÒEum—‹­ Òa•’†ý¸o2§ŒaG(•‹¶4Ï„ìDBBC™.§•„ÄZGöÝß½Îw7ñÝß?êxNÄÈyoÇñ°ž@ƒÐº¡Ö¥*íw·™‡Z/k­§óé|^© ¼yûFœ—ËÑt¹Ý?¼{}{˜Nç=#ΗãåxªµšF­ZkUh]ÖðØC*™ƒoïï¿ÿA–•Vs½•LNL4 c ^[ݺ!>G$1Jk‹.¾þ\C9çEÉyâq?íp°ódЀ‡zE08$zèì_?NVÕmóÍ)áÅ.O"‚ëK‡~KŽ-ºyИ»5Ž!Üf¼ÆÒ«[ä0s‡)qŠ0ì”9‘ ñÚ@ré æèyêÙ ,£ä jf Pt"ªN„ ïÀÎŽ" £¾•ˆ ôtâÞDêGªtÍžjb÷€C‰‰ÃÝ«¶¹Õ)»ˆ¡Š}£ðçõUÏÈèMab ÷ànÞYgp÷nIK,BéŠø ò딀m(ÚÆ¡€ôSG&w# (`bšD’„Â.nGÔ‹4„2‘PIâ,‘ÊÊaÖÔkõŠK»£™v™1î†DD‚—g,¬—µÍM†äœ‚5}Ö£_gt;Y›‚¸o¯'¬áݧt%Pô] ®ˆ—KYŸ©281 qeCÿ IDAT«ÐŒ05*IL‡†T‘™!‰ "Cx ŒŽ—‡ P0Â(6JÙåñoô!Aß@ÌN6p "s÷˜† ºatîˆaN)Gƒ¹ã0ŽcÀXV÷Ù³ª?>Î9¥A¸µÊI8Ÿ,%øêËŒe?ŸžŸO±œñî^0P]Z=·ë꥙‚),èš!ì“ w=ñ7³ m#(ÿ«³Ëv¿øõí"~í úÍDß¼^ß¶Wÿò;LÐVgúÖôo»_PÌpap€Â%$åR†ˆE'˜™76"&S,Q»ŽYRÂÙMüØ=B­š%‹Üe_Ñߊ_á /_Ë·ßì¦pm¨æNh÷¯wØNÍÜð1×9ßz½ÐÁÖÔÌÄ#8Ü]a™L nûig¾®sK%g6ziR½œ9æœK)9ç¾–Ü`†ª’ù¥Bb¡`ÆÆÐœƒsAD­-œR"óñº^Ÿ®©T«™Ëem—kz:„<M¯¦RÆçǧu©¯¦œRºÔºž.O_ž¿vã$i’¦IDÆ2©ÎSoý~µ`p&J⎦\ˆÝ.vú óz®ß »ãi'¼çÄ ?8hHˆ³.çª^›Cj!œK’IáæÍÜ]6h/Í G$†¤~¬iJÎû’‡Ok5%PP @䪔`¢Ð~z#Ü-~= êç{¼#ÁÛ(›[Ϧùå †‰ú¹Ll¶A7½²qð7?P`ÔID@„]qùLd@‚Àb¢¿úDÔ¹Y «I Ô•,0C*|ÿfÿ»ÁÓŹÍõ¸.ç ÇËÅ÷·¸ójY…[á=ÉÎq¶u©t‰/ŸŸr?~~<]–~U2k€IiH÷¯v4ò¼^T«ÎX.ñùüT²¤R‘ñý»Ýïÿæe?}üòþŸ?œžgŸ1ŠáTÏúolÿ2kYÛbOz©¬m=]Žàx>=-µ®mu5!"r™Êd­F¶Tgð†œ(iZ…;JÁþæðû¿ù’vÅãýÓ#Žëòéñ)†`æÃ~_O—Çy!+XˆBÃ# ¥”éÝëÃR¹H…—ýäÌ‹êyi6?® 7å‚XÃ+C´9oIµ fðŸ¢#"À‰ Â)±3œ)%†«»v‚Sxx¹!ç¼¥R» a»åôÎýu¶`I9Êëö—^±ü=¥@ÂîÖ]ýþ×3TnkòN „°Nj^êá$NÔ‰A™(==Óó÷Ds?¨Ã d›²'Äœ\‰@á@Üaj&mU3áRØÙ¼B^›–´Æf”yw ¹µç‹Y‡;@¢Œ$y¿ÛOYœDÇ]¦%ÚE™³y F;Y‚C+ëÓ›ÔíÒ`B½æŽ§âÀµÝ|5g»+¥Ä/-Í^Ò¹À]Æó~ýâëúüúÀD›P#Ö'˜ë`Ú'R€œ´9_¹À%CƒI$—AM›^‚Ì"¥eMÆ”3KíâÓkà*6(õ/aÌ!á¦Ê¼}‘@³hØjÐAÚú/9× =LCŒmÆwk­­U½¡€¬žz¶¦ó‰âEÛÚa`Œ ¤ ˜y m›#â:ùôvP"¶ëèÇñõL£8ºÿt{7s0ƒœÂ%Xñ$‰Mt¦˜IëÀ>åx ­-+äåõu»Y¶·ݳo-Š Qðfíòª~Ó1¶5.ˆ˜˜ƒ ŽpRçÎÊ' …Ù•K0™‡#6¡ªÑVG¼ š¼Ô‡®\„¹š’¤—«xD¸YÐFe@åÈLÄÄ"2”bóªçóÚLç¡•¤¢ýíùQUŸšFÄe™—ÓýîÝý÷ï¤L`™uikÍCJÚêóüþ§?óPÞܽ>nÄx&‚”i—³~÷ªÜ«ÕãùìMolٌ̋CT4U‹HL”ÈÈBm”Ñ5„) Ó!»d¬­º}Z×CyŒÄ;¡¼£’A»iä8òòéi­ ˆp#~>sÎÓ0fîùj„˜r6‹Öí>’`hÇå¤ô“ Ëimî’…#/j9õì @7s HÀ`x7®J@;R7ˆAöÎqúÕäßõ!LÔ¿ã (¨k!z¾Àá9z'-ÐDàÞ÷è;îÞ·Mô’–íÕÚÜ~ÿ=¢ ôS.º^Ù»1¹È4 ‡Ã¸Ä\ÛñËÃã´óœò4†¼"U8R⡪šÉÍþÕ0JŠ–ÒšrÎA +ÏÏ|X†Wœ4MÉ¿¿&Ä„ÌZkU+¹kÓ"ZŒw4M’ÿáoßýý›éÕ]’[Õ[?•ËS\žl®+3å¨|üåáéóüø¬ó¦¼ïã~8/ëû?þ¹ÔÔ.u¼½†²?Ì·÷ûépãÕÌ+Ès\?¾Žz~~²ù‰(^½yýûï^ݼzýáã/>}ˆˆ§ 9-™Ïõrþ/?üþ‡¿ù"Ö‡ñ¤»½ïÇHÚê²ò‚IOx¬Ÿ×6¡yÿwӻÿþ:Öåár:7cH¾ÌÏOÿr<>¹êæØ°pKò<ææýøfX/F‰¦›2 òf|ûf÷JÆÜ¦:G”Óåè…©8ÏÇåçúó§õ¹ ÔqŸÆÃ}N)EÐéùR?}¸[gë ÖÌXߘ‡™«-ÇÕ«TxÈãaä,j˺ÎJÕ fX×UU÷‡ñõë·U) Çs]ÿñO\ãÍ›··ûiwIYDÁÍE­™{´fÄt>ŸÜjþðø¤þÄeœPm˜êÍÍMDðº˜0·5ÑtùÐܾ1¸]¿Ix³#úë.‰èÚMef–Í/DDðf–É{íÇ=Ø̱,õ×Û-bNcf£Ò¹Ú<Äœ2‡°vµå0¿Ýù5$îê¶~ŠaÛYçv‡nÁàÚæ-©G0$%áÍS0s'd’3¼­N ðöNÎt$Jî€@ˆŒ@ª æDðµ¶,.±Ì™Á‹Xi6­H ‹û¢Icð†4#2dJR á õ@Q«ŠZ Mëjìðn_/~F›5]?/þeòÏŠ5Ö“@*yÙ%k\— é>A!'7Q|óîØ~Y«$Òoºß¸‰,`ýy}˹{¯€ö­o[ öfÆ)IλqH¼ÀÆtž‘LàkT†å¥%C"‰EˆkU’\LKÎ¥„©ôÏŸX$åH@®¦ÞUT=r³‘ñØ!¦ÈÄ™‰®Öÿ5m:r7Bod}kôÚæ·¾cdFJ`Q@M«º:\à ¦ª]4ÛI¨ß,:ú;°¾ÝÌá‰$1àa¦Õk{Ð÷Û|L”ÀÚuMñõÁ²Ëû$@`Dx"G©F&ŒœJ–œyMº²-b:H L™J yxS`f)$B)kk¨Îª×Òp‹µÙõR­¡—Ç,`¡~=Ÿ -=ÁâH)±Er$Pê ‡{Çà"ü —Û6E¿Y5ôPFD·/´’]"-¼jµ[Ø«,o¦Ã-§Ô\k[]Í[â]QN¸ÎŠÞy_MíÌoU°[ʯãÎ=®=hO)…«4 fÁY‰ŒóP«šsp戞QòëŽÔÌ<`‰Xç磪îv»!O!.0fb†ª² ÌÃÂÝ='iM_¿Úq€‰ gRÊ(w;ÂZ£aÕ uEu f°UE·wøÿ×™¤k ñ5ÍE×úÖ¿kSøK&¢í)üׯÚÿ/‡øú²™Ù.ò2¹7u‰à ]k8>< Š]$ŸÕÏ(#eð!.î`¡”S–Ø¢È9ç”þóóù'ż¢Õ|(y<œQŸü¾·Ö(ÑííôúÍ«T†ùáRa)ñ”†œh9=µK]ÏøóúiPÖó›fõO?ýñãÇ÷Kói˜2î̇e}81×£ ë8RÚ-7÷Ø,ñ,°»]I¯5Ú£/¬Õ b>œŸ3ýñØ>?=çy68¡ ©È„(ë¢k52„8ÁRfóuâÒ¯ÌÒ Y”2 \âóÏŸüt:é¥Jó‰p#ûC>HC±„ ¬€yÊãÛ["Z–ꮵêÓñ™Á륪"%Œã$Zk]棺_Ô’!eRbA„Øîµ.ªöôð þ—Ãó­9bº=?Î_NœµéeÊ|9B(R2åÞZ³Ë²¬:Ÿ–€cH4ŽÕýrYÄù&ï ¦”sJ‰ÇB™±œaR \é9}…#ã?¦úr„ }„{÷Fúƕ۫­]ˆ»a˜Y8õry3…z­*ÍܶâJï@ ˜‰*àÕ´süݶ)Mˆ(61Š‚ÅɃÂ{‰ÝɹyØvÝIÌÌA±&lÞ4w° ωnf!ÎÂè>% ¡Š©£Â2ººïÀPݘKÎ-'pd£!ÞX‘ ;† IJöÒCÏ) %bÐåy®i¨óLKÛp„fH»œw9;Æú¸êgÅiŸý¢X*P«~FЀ2N“›qs®+Ôƒ˜Ø×ç¦þ[ÑÍ-PÛŠtŒÄ9¥ÔÁ×ÂX|#ùŠ«eæ`;‘ôªÐÖýÍÂWPJ’K€ƒ„ W8©Õp@(xo¤”l­\R†’Q—üò|PX„¸ŸvHÇVi g q¢8 Y&¡1ÄU›†‡;Ü;Ô d¶q™ƒúÝåZˆ‚ x.,ê’Ñ›éX W„؈ð¯²ÎàèǵÌààDœ( 1,­53‰¯·¾oòK=GLpŽþÀþM•ˆút—ùFXíÓq! ÂcΜÙVò•£Q¡º¹µ!åíÛ· ÔBã†K–4fFrd`Üz¼*°÷g¡g[ç³@r˜[TëÕ©¯5˜)QO^#%×{¼#ŒáöÛÇîíä_ŠiÛ€°pÄJ˜5LƒRìBî¸$±5…¹Ã‰½‡î£æ¶}ècÀ¶¤S%v_ìFÚpòØÐ#ô¦ÃB«y3½=ܬméB30¨µV«’[­‘€‡Ø$3Ö¹µ¡¥;1;ìÈyš´®ë«û{a¸Úþ0E<ìoËe-$3Îçã…ÌÇ\ÄkιΑ(I[”’äZWʶq¨ïÖ^R°/'cù¼ò—ä·þÆÿíPÿϬ‡ßŽ%[TÍ2˜]½Y¤€„‘¯®±,Ë#î§y^JʬóÅ=†aD׳3úñ”ôɧ³"úPÔ//Rw§Ä9%¡n#o­Y$ ‰4¨ªB52µÖÎÇS~µ›†T+¥iº¿ŸÎƒ„¤óùY#ʘw»¼ì€}¹xm:¯‹Î^¡õáùÁ›çœim®v¿¿y8žàðº´WoÞ"ÛŪ ‚sÞO{ÙçV"yYHg µk2#[' ‚‚¹°äÄe0÷9ü³·ªz’tHù–òxj;ê 锦}:Ý܎ƵZÔÓ¼œ–Ë# °îEÊv‡ršÆY km‘üîõÝ|š?8Í'¡0nnoïïï™ÓÓÓÃétº,sŠlnÍÔ.JILƒSPfPØz>¶¥==/y—AÜZŠÕÂqþ¼,_R 9n÷)\ÆÝmamuµ¶jÅí„ZQ’¿¹½»Íãããóåù¨ªõ²hæ6æ’e¢Â«^æ¥IO¥pPײã?—;îæîɾ!@í)™ g¸ƒ#œep„;·LDH¸µ& xs«Íg%r²àMuBÂ.h­¹FÊ©?#ÔÌÜ“¿N­«Ì"AAŽ d*Íš‚!EXLÕZJN¦ê±¯Ýð|3…7èÂL¤PWBÕP½û÷Bà®ášóNÓ’df0¸‘0ôîwºÑØGª‰‘ 厇P²%t­L‘2 #´Xƒ9‰ÓNä.㈔XŸ×aÇ·»Cªù´.õÑqÌ¢‹¶óŠª †æ –ót3Úh²7s¥Ä´fƒy´n>x9:~Ùõ×T³/ï’ˆ0gòÞBw%Ôj&ñn î…w­`½ÖQâpw¹†Ý0î&h¨z›ëæÐÐUa!ÖUÑ'¦„ž#ƒÑ_E„ÂW3óþ! (u‚sÄH1ïY¦”Ф¹"\ÕBÝ…C‚Ù]Ý)€;ˆB:1…œÃsÈ€THrÀaZÊP!cw ‚%¦«b˜@½Î¦N ŠÁ1 ú)"5òX#‘ÂAì¼ …htõ0œ@P†(ˆ)„ÀÖ¥yBT#bç˜;İf:S,äÚéªÕ ª§óºS)’¥£[èáL’¸ä”hؽžînŒš¬':8yĪ-Ñ5D$ ¦HALæ0%'G¥^n[˜ìÐÂK³å¥¨ÖÓAA@’Ĉ@y°@ÎÐŒFr j+în‘ERs¸¡Ï«=¦(DB/3Û5=ƈ®k¦GÇ'Fg}ëÆÎÀÉ V«Vm:­&!J¹yXÓÖëD8ØsÉã¸Ïc†áÓ§/ϳ­þ9%š¦aÚ‰s­Ë8ÑTUWÕ;Üì8%w¯ó’s¦ ]—ùv¼Yø<¢¸ÎIÉéˆL\h™U¯ú¦ŽØ6otåþuKäUÜôïJ‡è®û±£_)þ]úöÿ×E½Jþ+¬BüO_’÷ð寸ßXŠ} „2‰•2yŽÈ ¶ˆæÍ¿{]åAQOËZŽª¾¬«Üíêb>¯ª% óPhàrVÚ…pá`"ëЪnVM!„‡|ý_A¿ù^:OlK¼ú¯†»M‚“%¹Ãit˜o¡^2wµ&¤¡êzG 5v"ƒ¤5‡—”ÔÝÜN!LAÄc'„ §ëXê)( jn€$b’dÂÎnÝ´Û‰D\M«cná ‹EN%M7Ó8QYã9Ñ@&—¥.E0dHœ¸Î®SÞ•×ãþnJãx^­ž,ªs­µ•q<¼¹ã›áé|‰ÂOŸÃÀêëéxs÷ SÄ[,Rç¥ê©Ñ€¹1ä2Ïb fêfavL¹”iàDk[j›CÃØ‡²Ï®Öê¥-­éL¼Œ£²ß!Fç t“Ë4–[Iy={h_Â×hµ©"*rá<˜½§G¢j3ÙÚ  $»4˜Ê9™)ÜÜ"Àc`Ö<@R=úš˜™ Æ®±iYe³öĵ¶LüB–7„ì@Hˆb›-à}K‰ˆ KH×ôy0(°9¦âIwÍ5´nxsÿëND ¥” ÷¨#ïÀ·‹îžÎ|Qjt§é¦IÉ…còV.±ó’ -ͳŸTgñ¹­§ ­: éäd¹$† ’Ça Òvž_bòˆ# CÙÝ%G}8׃¶[}ž‘éüö‡7 Z£¥×ãq\¢ã©¿þT—_Ò«Ãë»)ÆõñÓ±}ùùêº÷û»²ÚwXÖãüáÿù(‘X—4Ú÷¸ûñïßþðîê/ÿ÷Ÿ?þÓ\ãÛé”Ï??Ö‚aÀ»·¯}œ-—OëúáüÈÿzûî&í<Á>|A–å‡_^—á÷åf¿~þÇ/å¿J¿/ãMºèŸ>|9=­ñ9v÷·¿ßýíçåñ|þ²Ì櫳Ÿ÷ƒì¦ýÍþæ|z¬³‘a,ÈL e=ưã_N—Åiâ»Ù/6 `ªÎqªóåÓjýÞŽ(eÂX¦ñérÞÝNµâõݱáÕá¾0> Qùx~l‰†¨©Îw²;ÜÎ^OOçd†!g4­ÇÓiÑS’ŒÈ”wë"óLêDV«5>7"ìdøaº[ëéù“©baŒVñ¸ÒÝýÝîÕÛ|H§Sýåã©Ò„ÇŠ»ÛÉÜϧåxg«>ø$’Võ»[i¶Ì»a<>.gWØ ‘ädÛs*,ÖŸnûaµ÷ô¼ýõG"Ê,I&õBœÆáò8#².«„…ûº´€P)kj­yŠ"bÔÖZe(ûÝ!e^—%gòhOaMÀÍ•‰H·ï†“ W+h18¸F£m»ˆÄ/[k*ÂBµÅΫI”qØïÆù²)ØÁ`u[Øùr)C7¬­uqK—1KÚùªjͼa‰¥H±.‘o‡Æó2¬Ó•ôkì !uA] ‘xH.ŠÔVjÈ ÆÆž8À—¸\Ã]kŽ]¦)=ò‘ïm ¼><€XäLíq}ÎëƒâÉq*X¥HŽã¢ Éða93´U©ïß¿óÝïîÞžq:­'d•l• ¿Â“·t|ˆZCÎÄ)š™8­MãhÍœzÜÎMI²…›«±äœ¹SB"$WG˜sDÔE+2!JÒ : œàj ¬hBÄ-´)Lƒž*-dµ5B)ç†õ2œÊ8$D-T"úÈ-,ä…´ µ¡ÅžÓ@A„3žReþð¶¥_¶ÇŸèäo'Ð@ÍÔVp dÁ@TмŒia¿D˜GˆšÏ5—dDF0"#&@ÜÉÛ«\â2³bÜa7î@¼°-š©1uÍŸ#W XÑÎzÆ<‚B rNÉ™E(IK`3eÓÑ1y}]ð®”$þXücX Lœ•e M”Îj”˜Ù[ë¬Q„‡±¬¤Æhnºxi²KãmK»i¦Ó§y}¨ðR†tnha9KSCÅÁ{¤péIyô[þfØPõ%¬¥Ô¸¿P/Vé—×6}M-ÕêÚ¬111´p0áÔð) ±Ùöƒ™4%¤q!8³& „®fH‚L½/c‘”’z%§ÓÓiš†Û››yYÌÛùôo—‡uG¸Mi‚è§§ÝÉê §æŽávwžëi¹è.װƤd4ƒÆ¦*îf\ꕆ،Qááуÿ¿ðl"ÝÙÈËŸ=·ø—î”z )¶qÿ€½O/įæŠènßoVx[qtƈB„)(ÿüùx·—¡),³ŒÃ4ì ÓÞ…Wsu;jã5|LJ±¿½y~x,ãàjçgÝНõÅWoì·Ã®0éóy]Zš!Œ©0€fM-31_Aø½üÖEœ½ G@âmeD.Ñ-켞Õ/–92ûFcTÎ’RJÎddH49çÓùu œÎƸG+TIƒ‚‹„9[HD2KP„µ!nänQëê‚ sJ¨ËêÌi™mmÖ"„y^W5‘ú¼Å8Ž ÞìôãÓЦ§G{Ä#ÿøúi¾¸®táïî4»íË«q˜Žíüå‘|_.|þ<ÿôÿãïÿ˜îoìvüø¸ ÷w:ê~x÷óÿãù8¿~ý&ežEÓTÚùŒS½måÞ3=¯—ϧõ²Œ2€H(„CœaÊæ¸ÄƒåHÄž…3!¥”³r„#rÉãnˆø±-Ÿ0{Ïû–w˜)çÖ-L<ðZõä¶s‹öf˜^§ÑÃb¤”³ÖãOßσ~÷÷?–ûO$©9ÏLuš.¸Ö‹xEpî7JŒ’Zk&qvOê¹Æ®ÁX|TeD¹‘‘˜É‰L ¼ý6èB掟é$ŽHÄŽðèìü p";wl‹Ôh¸Êß¶[V "€‰¯ß¿þ¯Í‹f!Ý*Xö<|ºá´·(®a„lÄ ÄBœÝs5®Ì„T8"D¾„yƒ<Îç‹Ú<îg|7N‡ñ0yZè´Øª-¹õœd—ÊM:Ø.IÐÍÕXg«ïŸç‡§§Ïp¿‰2_¬®óóÓúá—ãåÂ#n—œÖ‡‡vy ¢¨ÕÆ´&>­Km í>/l’lyýÝøêöæo~øÝ÷ß½^?žÎåé³Ò~ÿð·¯þËÿùãçöéË÷ßß ç›$™ï‚Zk||>×WSþ›7ßý<Ñ?ÿÓO‡é¼£Ýa÷fz½/ßs»±¢Ç÷–óúYŽçù¨Ÿ~9?×2€´Æó¥ÖK,3lÂŽ‹AݽŒÈŒ¤5.—µžÖO§³ Y?¤iÀ±( èe8îËb’¨­Õš»¥Óã0Èîfxýæn*»išp¢yñx~ØS™dʹÜnl9ºÑ¼.Í­´ÖªÕ¥HŽp‡Â©Q›g5!”aHR É¥¹{CÙËžóa¼ìñ|oB8rÞ;çÇÓEˆö÷»ÿëûß}9øüíŒ2ìYÇÓã¯m(É›æ×h>«­Ëå´¬Ç-Oa®°ígc[åó·°œ_Õüþƒ~±'ò$ñäî 4&BOØÃú :3±IJ»SXç—:ÀnÖÃvä ±Ûêër=u À)е9Êœèå9}Íœ\Ò›ÙPÌ ¾ÖªêgD ÖþÌ@aÖ—‰#¬6f¤‘SDhõ¤ÄÄ1š½µF“…“:cqÞßXÜxMk\¤.š¹ W16ì˜ÇB;6žýbmUqffhá>Ÿ£ ƒä·Ãp(绡ð Ÿr,Ä@Ê™IRp„x˱÷1ˆ'„¶Öš6,ì«-`¤É2IÚK¹Å°«(,•¢±:«s ¼Ÿ¤÷‚B8Á£·„)‚a}EÓ…?îÂù…æ·Ñé<‚¾2 7”Ö• ID!áY<±Øê´€µœWJ)4ÜÆ‰p‚â«c”#:¡e{óÑ7ž©—jðvøÙ¹`œ®M!.¾eVdÃW Fx§²÷g|ws¿J¢˜ÀˆêÆÞ4¥`‹Põ^V‰2w§ÖtU­ãn*%Óµ °µ¡¡xˆ‡8H ^ÕVÄl¾¸VvejF†>~Gð@ókz5þ•Tý% ¶—?ÿ—Ñ‚þív}ýóeM¿þç/,…ßðú+îý}žáBf^5¬YQ2agœ–s®ÎJœ$·‹z=/ð%çÜZ´µÂ= aÆA¥ŒV›Uµ¾ ôÔÓÃ"ïHDÏ3ýöö×QÉ©7àûPg×’‡Ä‰aç>[:‘M"¬©[¸9‡‹jnue^]Í8`J$Ä,Ó+Ø‘ 3ò.´èðxa鈳.~@Eˆ˜)ˆ“$;àhý€Åè¢~nçödOKxb)­É e?ŠÑ¼ÎuA©Ëº®ÿ/ooÖdG’déU53w¿K€\ªr¦z')Âþÿß@¾ðmDÈ!»§¦z2³2±DĽ×3]ø`~Èê*²«9]D"ܸ‹»™©ê9ß‘­IƒÏ[ªüÈ“¿ùöWo¿Á4¾ <œD¤¯k&¤"IPm™k*$¨P9Ä ì¹®/óívãÂâ&ÌBÂ$‰ÅK °©5VîW µ ê·w2,΢±ŽBÌ&²F!)À öঠ璒 KÀ<<ðq]CN©HI]]Hföüüi8(Æ©ØóRçÅrĘ¡%·P¸×p8)`¦fDÊÔ9 0Ê„ tùCG öõÁ™ˆàL°0ŒwA¦…óžRЙÜ1ÝÝö̱“ó™¦èäáWðÙ¯¡ÆÆIþr>¢ýÚŸOD)åx¢óy<F.fèû*9 8± <4 f²\ȹ¶X…™‰jØz]—›æk==¤éx +¶‰Q I%‰š®K ©DÒ¹~CNåTÔÈšzø˜‡ñ //·ËK%"¸n³š²·4¦Cy Xnõ½¸‰“c@Q¨ŽÕ$"Æq2ß>^®¦jW"Õv•Ûûù‡ÿòÓöñ¦Oó§ß?m·8LvÊÛqB9-óKŽHÙÂ\<[:¯óÚ[Ä­¶¦6·¸UÌëB?>à ÒÇiþ釖Xæµ.Ï·Ë“½¬4CГ…@ƒ7³ª¦ýÄ{Ø;W/v7:ñ9lÇ9ˆH€Ô­šnn*ìÌŸÝø¢:ýƒóeXéïiçp¿E„v'„¸[ ,¼ºnlJ²Wù½Zàœ"1s±¹˜q«p ‡MTZç ¾é¦MU ܇Ñ滨<^§¯- âÄ,àäîAwþ¿ä(üâÌîѳOï!Àœ¹ÛB ÎÔO Î"av„†+öîjÐg#Í—ËíLð€çwŠGg@Å[‰B;`D8'2÷`ºC;î\:D g¤”$ÑÈuvƒ{±ˆ”¢™šœY´(6…Zú®­QÕöx~¥‰·ÐÍaA‘óVÝÜEqFÐî›à~7|†Y¦ZÓ«hð/I‡;oú¿ßÑë>ËÊ „ª6D[3íËÿ²Ô†¬”Á’ ¸©5RXʇqwŸ#&á™Ýšo0€0²;¸‚êµô¦)fùšÙE„±ÛÏÜÝ % žà ïÈfwêF5¢^Ãô!23jbŸƒoû¥ß¯*yêþÚ€››ƒ‰ÈÌúóìÑ ;Õ†¢£†ðÊLŒ=mÉ̈H„"ØÍ;@Mí¥®ëm>äpÏ•Žylk½U%®ô¶”Hr6‹j­]Ö¬y0úöøöDÃåªuÕ0;>œ£†Yð8e°‘WrM1 ‰ÛmÕÛâMKÊÒ9ÕaãÎ"„ÄîrõÁ.„¦f… %I.i,Ó˜²5%ãÆcI%Ú¬UgŠœÓ[ÃÃ?ß.öfóõcÉçó¶Ô ±0É2n®žž·ååùfuÙl†[!>iQÓ8OsfT§䜻 ÕB¬Äx “hD¤Þ>ëÏ™Á}o¥fŸƒÅw+ésÐ^#uŠGçý c÷L"&ƒIÀp·}ÁrìðØÿÑ/,ÀÞѼ”át:ÆÖE]RL÷paJ‘%%–`qvÚš©. -p8fŠCÝèVo–çñ›t<,6 ‡r“"ÔÈX@·Û¼\Vw{óöd׋¯›·­LÓ¤kyþ´Ô 0ŠÆŒÄQ²¤¶>Žç {yÒårÓš¥äÃéx<q[ë“;¼F„ýæíqŸõÇúñç0^}2Leº=½ÌO/¿ùû¯é?ýß¿}ùùCáiŠÇ6ë¶,Ì“§ü4/æKšó±­[þô\¯1–×G¦õðøðöÓíåù¶¾\P7¨C+æ—E7öÁ)aÌãXÆë¶%)ÓxœÆ)qN•mÍ·¦.Hâ!åÌ)·00¤ {EH¤…,|­‹ºÀ œà¤­m·ùªF¾97¨b $j–^¶æ–Aîé®nÁŒó±Ð6ÀÄÔ8dHÎÄäè6ÉSHBFÊSÑdÙÉxÓÍ¡M«Œ„¸®—ˆ@Í–—'ió›wß¼=ýýùöóÿ!é yaæ’øµ/eáÍTR§éx¤Ãð ´Í·öWw7Eç÷êçJèî5S ÈþâÀv‚g…ôº¤[À}O¬Ù¼w_T#Œ£PÑSêZk¸Gúõ5ˆ¨'Ö wÓËÎÞ§C=ìE\r°€¸Ãdv¬?ö|š¢1ó=œ‰‰Ùî†hð $ A;Al@ŸÀÂ¥auoóÍ?4|¬èÅ…ñÊ­³P)yÜH[ùÀf"ð ŽÒåks[Û‘‡U5­V–’¢D±ÄŽ’„¹I„8@)’‘Äm­Ë–§S¡ÂL"x}ç½æéEoñ fNÄbÚ‘¾WQI˜…E””“%GXí'4bUuÃç<”ŽB63ݬ™&Óa™9¥T‹sK¤äîajá‰"/y p5máÖ£ÉÄ)=„‰„,H‰¬$TÙb§ÖÅ/Ç »A7˜ö„8GðkƒàµŒèTXÁ_ ¨Zèó*Ó)Xe iާéx-cëÖjÓeu*BƒŒ8 ½MÐñç–3“I­­5e–a°œ'ÕòñãzÛš”&ÇÀ‘dŽf¤IÄìd1 »$–\‡±^š©±çhi­ÑZ”ë'õ¶}ÿýMÆ’KKI¤"1Ì—m²ôøíÛ!ŇŸ~ÿôrÍt8Ïi(R@Ì$àž‡i·ì)¹Ø­®ë7 +XnóËÖòÿ©_ýÏGΩVŸë¢s˜o7]/ žóµÖõSûéåÓ§§úin—OÍëÆe8|<þãïä0U{š+VíE <Ð*LÜd'±Š`ÊÃi8¥¡œZó N—e‘³¶PÝÈåHÑ‚´Sq9‘Ááã8äÓ(¯µ…#•‡[{¿eÀx éT8“»oW•S(#FÅè$’kl[pÅñ0¾=~µ~´m¶eQFIÂ$¡±™›„Ëš'‘!@RLÛËåF¦ÁÎyN£-UçnÛ¥ É(ºn?}ÿ>ôáp8Býåã'î½F³Z«'î§–œs¸&³a˜ŽÓ4ä|Èn%µ0„]¶s0Áa¯Úºõ^±=éŒ"€ò…ƒ½UæL½eî}¢œ`É=E.ЫâÊÔt„=©uÏíÞ³êà;Kz?僉ï­â]:ØÛ¥‡Ã¨êªjÖT+yµ &:ƒ2Aza|'ã…ts·©º‡™!*È )KÊHên â°ƒ ¼µ6c«­‘¶É-Ù˜Ô(‡K8EnæPJx3’ŒNˆÊ¶ ì$LR8 tµ ÑÖ`$²1PÜ€pJÒ´ÁÍ-ŒàµmpU‹††PÊCiµA{ÍîFI†æîÖÔšSbÎ’˜‚»1"<C¸äAJŽX ÜÉ $÷ŒVºnÝ~¹úÞ³}‚9i˜U57r) æ<ì$Óh µŽùëP†.Y0¨q JÎ[xs[ÜÓfAððD „LQv? w,ò>'ñ°Ø)Rhþ:RèS¦‡ûH("™‰‰-Ð÷Ø”=—Ó=Èú#R‚É9Ø ŒHˆJ@Œ™K)!ìÍ[„‚z*ë0èÓúGÆDÔåæ÷,t»ˆ;ÁÉ“p¦ #Ç8”i“¢mUà‰XÈ™¬›q™rJÆä÷ö#'bçãr7PÕlÿÆ+±c·äˆû–äØ×®ŽëŽÕÍä€Ñ~SÓž÷GÞõÚŒÿ<¢¸‡ïÛ‡$–Lçóáü0C.D Ò—ÖZ»¾dB !>Š$æÞ'ˆªì.»¦$¥ä±”<=¿¼üüá§óÃðÕwç7ÇcÛâãÏ·EfÏ:®@¤åy“à!O%'Zø†_?­óZC#ç¡Õpù(($ƒØÀ®//Ûò²™ÅヸFÝ¢µà×ëËóAªâr›Ãñð0•|J›ãýÅÔìÒ6¯8™Nc:ØÇç5üó?½œßüããWǯOoÞ|×~üçOÏ?~ZoÐRÂÇç—Ëï¶%ëìíüðë㛲^×ùIµ¯1^†‡ãù6?+(O@¥ðäHcbK0²jUÕ‹¤q<†'¡ºy]¯aš O‡œÊX¼ÁC2Q¸{À³N% i™·­!¨Ã‡ÊT¼ÕppB( 9 ”§ÊÇtL¯¶Ç»oοúîÛ4¤Ÿþý<¯ë­n³CÁÓq|ûîñÓr±jÌÜe5­¹UÀi@9cz$ɼÎ~]×õiK‹Ây’q¿~H‡áÓËó÷?ÿT’,‹)ÚW§2 ‡õ²þîùà6ת<eÆZ+àã4¦”8'jL$Œ$J±l›)ñ0æa+fiO@IÕôÎéÝÁ8Nˆè™/þ+„FpÒà•Åx¥…¦Ì¯\ ¥ Á£DKð€3áæ„Ô³¢-˜ä®§÷]”svwBw3Ó°@â/(J{75`]ýa ä’‚X¬~Ù6Þ“Üûd¿}Ìfë,˜L,5Î ¤G˜Aâî¨+–mݰmcld›¡é¾X6UmæÂqŸÇ|xâ½E9¢ŒÞšA›¹: |j“ëÜgPÀà(Šl5;»oغ+¡2™0È*81L`kkŒPN$™qϵòèÔo¿w%)j"õÞ‹êäjêv…{*n0 þ9&7C’€ywYG¢‚ŒeT´Í4\µ9±G3Y8Œ¼¿½îp77˜Zk‚;›±28KZ-°™¯jêgµGvÛJ"))" 4FGâæ²@¯ Ü,^s»ôA02æ,]ˆè Þ! ùœš¢ááDæÔ)ª"¿³¿9±‹cè“NJÜPÑ™¼Ü£^yk„/#Åþ ."‰Näâ€w¤7{!œ¦!S))È6´Å·µ„ÜMÛJÚF¢+\(¨{ÂRÊ,”¨Úš³ä¡ä,ƒÒ°RކZ]Íú;æÔÓc#zRaÿân"¢®ìT\X¸v54±½nÿðº¾~e¾ú¬RÙ‘ “Q$C' ‚˜Û®*d SüÀ—ÖšÏ-ÙÞ'ûbXäîs¿§œ9¼YX4*=oƒâ‹8ÔZ‰HÄEè Ùeu0ómBÀºÖm fmª§ó¡”ñë¯Æz‚ƒ¥N%§ƒYÆ×:WP“é”siîîT”†GGÀ.Vë†L˜ ͇—†Ã›{#;3´ç—#ˆCpân…ïYìjÁòèêÃ^:X³Ïã@Â`¢îS(È#¼+ä˜ÞKšWýý> D)I–È`ru‰oÀ’8^Íà{2wKñ:ß2IOΞÄba-:œ‰!`1jj%"gÁÀ2ˆTA­ÅŽ*¦{o€(@¦¶cÎ^³  ?0ŒA81<}óC±…ï¹³ê¨îæÏ„ÈD™8 Qb!ah ý‚>¼7»yî~ªþeÙö ‹rò êâ`õ .^qB ³×–BL ï¹Iß–Å…À=3’óÞ[p£qH ‰)£™)Üa´·%à =_woOr€ABÁ ”’ˆ'C§jõ9µÝ­>_†Ñý|°WG íÖ§^C‡KD"™œ›Ô …‡0æ‰Â¨‡öIÅ[ç»d.Ïoï—õX„»«kkÜ]f:¨f[Ôˆ˜¸Ëš(ÜÌ"ÌBDÑgÎ_TDaÓÀ$Ä„“º[ ÷5ç¬FM£6\gç—¯¾>><>Žåꛆ’ÂÍšr3NÌ9`AÁB‰ûçïO`wÞ=“­UúJi;Ë—:VüËПø3ˆþ¬:êËéPü[§C`áîó 1±³©±0"ârŠ”a¼ê3ÃÜCJÜ–Zr}¹BR<õº5IFsÉ#™S3vp.޵ÑíFH¾Ç³ÞÉ1ÿâ•RoOPDxð]Yw—¤:G'î< ‘Îè Wö(L)å’벓lz„5|':¸{„;úb Wó!—û>¯™HjaîN,L ÚÌ”…`nîÊÌ)'ŠzüöMzwŒ‚S•Zçùv<²|{nc˜–íòñr½üçy@qC &’$ƒªsÙT&ÓÂ4G­[C-Ç”çVUseÌæõY©Qö'íÞ´PÜ P÷‘¸»‚°XU™ÉY€’!)£¤Ñ`` C"e'öîm= X]/ºœÏG9—gYt­˜øÍq,týC“¥’~x¹~º| [¶ËÈ Ʊ<žñõùº¶õoN’¿ó÷Ûû÷—CþêHÃp(ÛªÛªÚIL&ep1„F_›@æ¦ô^|_|úEyš}^˜™¼³·cç:FXø½ò (vH]†N‹ì£i é>Øp3ïø˜¿Ya×õ1³$”ADhg´’¥LØ ÍÅET¸K»-µ]-m9¶@uvJÈlÊxz¹T É”¯×fù:åA$Ÿ2LêuY¯˜ŽÄIÐø”Ç84ݬ.±Õ ×g}ûp>ßÐmÝHŸªnßápH)¥eöˆÊÞBU‡\†Q¬5U¸ 'É ÊÓf4‡zðð8ßLÖüùú)F¬zÁrÑù©Ù-ÈíÓÏ7Údoß}5 OL _ )m/[¦Z²KÅO+ÚjçÀéx~<\ùŤáhÆ‘ùBXÒ8'}ZÅ l0xs¸ËJÊ­µh­'­h¨»Ó+üxß×ÝÌwÈÎ6@ÿLó8ìa ÌádfîÍÝ…SŸ2í±¤DÞU é®èá/ á\ÒØ6E¦Ä9@ðH‘A”95´½¶£»ÀÁÔ–•F–‰9õ Ä^? Ôc [ÜQÄK°‡'&(ƒ1Q—WÁÜHìȰ®V½÷¾ˆi—Zr`$‚ vC£hʬØw¸W…WÚÝB`G"ÊàL&L½9uÉœ‚¼_w´{h ¥ü MwÍYìF¦ !0bb>FÁNY¨p#lêù<Ê Ä‚Ñ'¬‰¸$·F,hfUk\Yp|3%†¨ÇæQ™[Ê."´ùÍû¥O=ó8üUã·§Úz—v1ˆAY’ˆ€Äû´f[ÿ`tñYøZ|9,º_•ÄwªD 8 )fF,ìL}~÷@ž?.Ãëö¡/—ƒ}9ò×'Ô»*fÁ‘näïSTsKgðº“û½‰Çâaý,nfý¯€»P*©p‘1—u­m]ÖÅÓ9¥œÒv¹ÔÛŒ0ÛÙßß­XdU6±êº5Dª\Ñš ¥!Är‹MÛ²núåÂÎûP"^3s"€ÿz¹øóþ½Çÿ+žû_ýxTâ=’‡ „¹#„$ç’Úê¦V-*Ä‘ÉÀȇB¶AÄ“¥‚|sxdñ¹öi²5ÅÖÂBlW:;ýžŠuŸÅçø¬»¢©Ï}boËayö–813œˆî†¢p ê Ø€TY­x"Iƒp¥MDDR0'‰ v'ŸUœ-„" "óP›¦©¯~]ï¼ç÷«w¯åÀ,ÜÕØÝ0­îJ)Ë DÄæùPœ­%çìµÔgýØòäçáÍÿøë•%›Äm]þùçO?ýçáí¯Þ´”ã$¼OoåÚ(Õ®C —³©nX·T¾;OÇ#êÚ^®²ëÇíúãÓöq¦Ù‹Q²ôeÂÕ}Ýó0sÕ.= î®me$Â4!Ñ{Ðj¾µ=˜³2³E„Gy¡MÛÕÖxsÎßø8D¢‡ó! å°®¥m|Iq[Û¼­Ë²=¯—ly.3ž>]ßOßûS{3¼{÷·ô?~ÿýþí›ÊÑH­Q« T×:€s³œ¬+˜jærgÆ÷U€™jÕ¢shâ@LÔà áîÄ@€Üm×L€ž‚@!$=·÷M‡‰ƒAÁ!–¾Ô[é’üSöMúóÕ´V r¦fVëZŽÃ²Üǯ޼M>ÝÖO1Nc‘©mÛíi^W<|5•-­Û¬Ë&^`~Àp:ئ÷Ëmç€Qö< uUÀƒei¶½l5•‡iZ¶ªH)¹n2P:#.Û²=Ýê-líZoOõö‚œ0°Üžë@úû÷Ÿ>|üéÓïņç÷§œç\·XæjeDZ¨7³íoÿî»­.—§–Â1ßž#C|÷wí†mkukÁkãõá×Ó7ß ïóûÞ}8Žùá·ÿ×ûp…ÛO?à¡Czóî›ó·Ÿ|;~úx(éíã7çãÃËÓs]iD_Ÿ`‹K‹ÛEóÝwuÓ·grY¯?Õ[S×qiBšdèmi%JÓ4nAøøü2l’³äħópÎÏïŸ>^g ÊÀ·µµëÒ~ü‘Ej­M]’('<>>œNÎq½=û¬ÄmÛðñÙ†fCòf#Miž—ç§—||\ë<ò›¯?·ácÛæ(Uƒ¦RJªÇz]VׯŽù›ß¼ý›ÿák¥¤UéÓ‡zÓ« '9äkÛNÓøoû[ ÏÓp˜¦p‡Ý¶›þT?¤Ò—OÏ[[u«ò(çÓ%Z×u†ÖÚùñáåååãóÓ7レ×Õ$xx{"—¾¿mxx8®—5§0PYØëXˆ˜Ã4þ= £ÖŒ9ÐLû¶êœ3qrxTwu³¾OWs!ˆˆÂÃjcJÂÙj9A‚CD$0³œ³ªª{N…ˆºË ·rû1™û.Ô¿#%´Ž9!¢”X†ŒHªºÌØ s‡­!¢Æ} Õ&‰sNm«Ä°ˆ@,"ò`·`AxkUi†4”8=L=üx: )r±æDa´¥S Œ $ζ–í"XWäcNoRä6_?"S»Ð»Ç7ëûõúý~6<.+.ó»¿×®k¡XŠã‘èÍH+ኃŸçßÍŽ-P Õ±V‡Œã¸^»5ƒ#s.“@Lµm›Pbáûx "™HÌŒƒSJuÙ žËu©<äeY‚A"…ÀÌu3›ç÷þ~o}åìŒ0Ù=ø"TJ2#ÙêRÒ:/jFE¦ã˜(y”¬S¶áŽ>j0jµá^F§”Jº…žSÚtU @kÐðnqŸ£ šU]8‰&ߨ¤Äâaæ]·}·„ÈœÙÈÁ æÈBlî›éj­RG°°pêVYsîçG»{ÕÌÁÚìΆq*c.K«/[]š›H€R"`DtèâgEYüÒÆÝqbý¢g–@´Ö€6e*c…§P¢hìs´gÇÍ7Gb^ÚªBÃéÀ%/ÞŽ…WmfàN¹hä’¡[Õ°¬4h*q˜¨ˆ‡·æÎáî´“Âá`Šj "t„M$æÔ} jÕ̃jXZÀ™ŸU©|ŸÐѽÿ…¤­ŸD]ÐÂR$Ê09‰ãt:].7k1Ž£0mµâ4ÔÜÌTÍ”©#˜€ òèb$0sFšk!V­朳­ë¥r‚$fÎ¥d5WÕZ5'î—i*Qkë/H8…kSwGJÈ™( ۦÉhÞªYä¡Èyp×<¥0oU§‚LåötËqòz{bÇõã휒6E`¾n!Èc)=•hSÖ( ˆ0‘Á Í^•ïJ³.mD—ЫîfDü¼ÒGñ‹¢åsðÃ/kúÓ¡ÿO½\§²}ù»éX²6pÎ(%%‘>1.¥4ê=¤$Éêíi¾jÂZ ã¶­2už†q[ª×öf<èuY^¬ô'æÔ%pï–‡;¹"îµZ¿;¥ðKâ‚GXD3 ‡C˜¸¹ÕZµi4T†…ö´‡Iò8Žç1irx<><øf­F55&bF€œr’0{Xë†}˜¾4ÝÁ D9ç”sñKmfÆ’„¸ªöwÆ M­…«) ccJ‰¨¬m].íÝø¿ûñ·¿Ÿ7ýZ>¶…rÃóˬoòùˆ¸ÕyšÆw¿þ:LJª~Ïä £çO7­Ú><›[«kÍvþÕéÝø°\fŠúW_ÿ‡÷??ᦩqΧÃC¢Jõr».³ê3Ræ, ócÓŸ¦ÉÝk'~ »» —¡Ôe&áF±ºfáßn×çÓ ÅÃã#YÞ¤‘§ªšS)¥‚ˆ?|ü¡m«µ ÃÚ`Û:& ƒßr(Í /õ²¬—í»"±#R“I·årÝÌn ÙùM’!ßÚö|¹­5âvÑß}ø¯K»ŽH¤iÝÔ i ßüý·ï¾{{û¸ÖÚ²Ýn›»¡Y-‡,Ffm¾,×K»Ú’ :<<öA˜ƒ`·ÛêŠ_}îºhWëf+n·æÑR€Ú æyÄ·ß~=ŒY½µ¶Õº²ƒ¹`}Û­éÒ0€OtÄ0œ²Ld‡)'œuuZ‹WòuÕ¦šÅ –ãC>éô¶ Óp¿zó8LéÓÇ뇿[·•8ßœõç› `’ÎË͘Ì2¥D†yÆbH¼‰€ÊPÕ‡óùüøðøøXÃt«ëºþðÃ)¥”YÝKJ>Ž+¯ÓaÈC2óÃc© ­FÄÑ»HHç´9‚ÿ4ƒu§ˆþ‘Éÿ¼®âçþnwZtÙ5Þ3^"Xˆ(ˆAÄ¡]w„(»‘£oåáÜ'=Ká³ü¿ï>½¡ò/ÁD÷¥Gî2z"÷]hú®ÛÑÚ_lÎb€y¸iE]µºfι€z+0<ÚNvõ(&D0¹ÀÉPkݧÔà  ˆmÓÄ,…h"0ƒ+¥wâÛ4å–¨µÙ·+²S*eÐæî -áªx\µ.‡—é×Å‹ocø!Ÿ'¶ì3FD¤ŽëÕ ›âFXfÍTR ó O‰%å~rÜ÷øž¨þ¹5þPÓµg$ìâ²½% f7³¤”Dr?evÕâÝÃAäÇvÙšBcm·ê2$‘ÿ‡·7ý‘,ɲûν×ì-î‘{UõÊ!‡šøE‚ÐÿOPÅ¡Ãîé®=—Ø|yï™ÝEìydVu—zzØ£ø@efE†G˜?»Ë9ç']$«¾NûT¨ÕªVœJUˆ$—CËâd`oà2fÆ2Õ>¡m‘œÈ€ « ˜“5pxsß!åþcÈu;;FŸ$KèbºxµŒé¬†5Énª;I„$¼tíØGx7é¹Å¨•c>ýÔû.>2mDBHBKW´ãºIý.w]—*Ù9»gh“ ¹ٳÕMU»!7w6¤¥«9SˆÐñP É<й –ðÙ`ÜÞoÁl„¶#ZuC G¬äSÐÌ 1…‹éÙ.¥åÇÔêÖ}RG|,#šzýI‡åh·uŒoˆ¨nðX¤öèšúÄ¡ÑÂ#ÛóGÖ¬†×l±Å€\ÒÕÉ ­r&"&á a m]Rê"ÌÝEdš‘Õû´¦4—âúŸUVIJ’˜ùîî!gÙ ýØ :sBF¢BïÞ¾í#Ùa’œýŒ,*è3/æu^ÜAH>_·Ž±Ê‰Woè² ú'$èþcüOþìÏyYâé¥n 6´Š5üQ)AÎ$ "7‡»T£½ëáAÕ¢VCHkÕ¥P bëÁY¼a‘Ó[^ÈÚ°;ýäËŠËL`b ¡½» Ì©1{†€ià42ÂH‚=œÍ-éS1gD,ËÒâ` ­!-B(BÖ;Ô¾–ÏÌ / "’ &Àš¦‰:Îp/ýØwc—sÉÕõ¦ìéûÛ¯óö7ÃkúwÿÓÿxuµÿæöñÛcéç<øu¦ÌH®¢fsÊ›Èâ!e±Ç:ë9!í†Íq:G`Üîn®ž‰Érw:žüírþ^q&Ÿ4Õ¨ì§>wŽ`NÂ"- »¥QZª %"rCRßå”è†á (§, – NjQ˜50\—eäûóËÍüÙît_nû˜ß~ýß<ÿì³gŸ=çM:âË÷ïÞ¾=ÜßâWÏ®¯¯nêt¾"¹ûp÷öÃ㳟¿ùë×Ï_hÝl¾:=ë·›®?Ïï®Þü÷¿†xx<üÝßÛ}­ï?;‚½¢ç§qOÛþÀér„>†‚[ˆ+Kj›êˠሂŒaM&áL±"Þô"³n®!kã##¦PüÙÑ?ýYðé§Š?Xù>{vµ¿ÞŽ×!º` f®C7¸­‘çäê:Ô#æÓã«CŽb$§MJ#oÓ8ëÝ]µrfÎPsê»ùt®Õ ãÇ2×ãéþÛãý[ô'd ßɸ¹!¤e±eš‡Óáî`µÚ\™Ð%Ù[×puf ·6 Ï'Ìnq³hÄán¾Ùm~ý³WÛÿüÃÃ}œn!ãW/Çç?ß§±ÿö+]Ê0ÆfÓ]ͬÇyY–ŽÃ„ÛÃÃo¿ûröú»¯¿>]©‡ûý‹Í‹W_Ü|±¯·çSùò¾[î|ûúÎýM: æã‚Å‘‚ýç?ÿ™º=Þ?pà~9 `H¹ë†g¯n&-“-ܧ4JOçÓt<èI5EJ‘…¶WØî¯†q;L‹W¾½½/Åöûm×¥i™ÝuúÓ餖·ªD’³ôÕ „Ìš¹’r$gÀª¹*W¤›Õ–  C%¼ŠÍשz´x÷Ö…û§Æ³ËEâ—V¨}¯™L­çU‹êQº¦!6)÷уQo>Ã.<©§Û–žF´ÆÎé“=–™³$P 00çÎÖu Š p§ö”v­®Ìèú~ØôÜKî3©™…¾ìÛ¤oÎow¯ÆÏþÛ_¼þŸÿÍÕîúÃúý¿¿Nåá~þþîtº7¹(/՞ŋ 9òG›Ïå¼—í8ô¥,5l;nvãîááîöë»éxöƒ¹÷±‡r4,´ IDAT‘V#çÜ-u &´Ü„ rbñz¡\Mrî»±ÏR–YRÒºLÕˆ¨OL© ÷R+qÔªføB^`E²Žýy›î{¼g}ðÕ?Þíóðm*—½(àÑ‚&ÉÚõHÿòéÛ´æˆ >A:ÈK]Ü»œS³*Š× `§BÎdî¶¹,-˜žÁAž!BN@¶…u÷²ß]ï¥Ç‡‡¥Î ’ˆÍ/gô›Z¦¥žÀR†´™¡~>Í_ÿîíÇcJòøøx¼_ú„ýØ=>ûbgUõ;{<ÊižOn³×s™ÎU©ÇfO}߃d)ZêrsÝ Ã»ÀýáñÇçe ª)¥¥L)¥Zë<Ï»Ýãva§s¿¹zÞ_÷ïì%‹Ë´› `F‹£•òñQüÄîˆþÜñA»/ýF2z2H@Lo8„€›1˜Úv" Ô’ÃÒØ¨ìBmDlP¸´zÓƒ¸;.5äê$.¾ 7³&€ˆ°•ÒJ?É3³HÛ*Ÿâ§ä+I©ÑEDت®‹¶@Ú Øœ[dU¨ÃšEkeJŒDÁð%œ—óÃ$“Pïá\y‰Ú™ I§…&‚3zO£°FñYçÈ]î;¬Ðyýy0¢X˜ç,‡u9Oužý …ÊÕ6Ç‹—!i__Î3ØÅë*a÷6 3 &NÂ’›tžªNÆfJ. *ͦ-pk܃FØpwA aWoAÔªÊÁ†5sëÇÑîm#ÃØˆ‰P@’Ià.°káàKZ»À›J^ÁŒ>w}Zˆ=T½¥r»Fól4‡ãI–Ô¥4rˆ;I)7c”¯&0_+ì`еÜYW`Hc~€„¸'Ú°tÌ“†¹Z¸9 ‰ÜîNÑàz ¬Z@‰(y0¡c‫•jKÕ´U"Ž'ÿËÇT߯}Zv)]ÌW}A ±cl‰GŠÄt²åÞ§»ËÀ3#ÀÀO‹S3 ‘„m›ÍØCɸ«"ZÌæê&îp‚Ì×t„–=ÀAÁ k‘W@¨½°há±ë¬Ä#üH•ÖÞàË?N$£†sA,¬jPÁ: !&e°'–”RçH,B!,ÒöåÌz‘é¶¢\)ŒÂÃa. çµ"»™…k—Vqˆ;\Ýaµ¹£Ãh¡ mV¥¦D™ùiË”.q,Ar§ªZ}©€9,Wes`žp¤Ófèà!„ù|~¸ET8 ¼.Û’»Um!3#@®ní ¿2=?bY '¿ì?)È.‹Ú§(¬?Ùý3º—øKyÚ­u E¹E½Ô8Œ¨V£ŒI†~( "Ó%bæTHÔ±Iý‰®±$âWV QŠêV"–ˆL©}"w‡9Ì“{çÔ%‡“r0q&Qj‘ˆ¶ò²™É)¥tq»©º±5„\CÂÑ6Ÿk#çfÑpDHÄ"’ËeȽ¤N‚¼ÍKQ´NWÒ=Û(nåùn·©¾¥Tºa|õúúÍóýçÏßMï—/¿½ûnìÀ»ñêzìËù´ÜO§[UÕD‹k=î—Ù;Êì"!¬x{¨s8ÔͦlNêlªA•j"¡h´Ù$J¸;¬ªª‡¡} «y©6•Ê”£ µÈ†tt]{¶½þ»ßÿ×ÿð¥.öòçÏ_üÛ¿¦åöL°ã\á»4 ›œ†12?è4qÝÿìÅîo~÷õW¿ûæ›ÇƒÞŒ/~ñ?ü ®òõ_ÞËñðpŒIçÇMÚïöûåö™oo—Ô3‡©ã$ɘ’ÖäkÙÒŒ’+³¸µºG´weÛó«êú\j¶Ìµùg3†·o ]ՊƱXc·ám‰Iþÿ˚ò\Í*)1+j-Õ”P‹(IWg³™ÜÉÀ1¡èˆ™xGcŸ-ñdÆG›±l(å¼÷d“PA›ñêúê†-Í·Ó.÷Ã6úMב—‰ù1ånè%‰¸žNónßO¦ G—d3l§é ԥѓÅÕU÷úóîúZ¾øâ¥¸ÅÙkYØËüðîí2é÷ßàûۘ°¿Ù|þòå³—{Ä9µª± Ü÷› Ã`µ<¦t>·9JÑ wŒjã }?^]oªúTæl…"I—‡”´æéþ\Ÿ×M¿ÇJt`;£n—ÓRâFPQbæsÑfµŠp8ÙÕgég¯Ÿm_á¸Øð!q†gÀðr¿Ÿõ¤™%眅ÓÅ‹t¹M¡Úd(g:1³a™y†0'³¸¿¿ßÓ^Éd R²â³QD‚à €Ãâ’ÝIhŠ9ù‰‘ÀŸéúS;"\vDÍø I@¢Ð‹NÈWe”·¯I@Nd€…w8âéÍ…–Ý'Z£Eé“)éÑeMë^e2Ô²‘ã#¼þ‡ëìÆè¼(’íkÏV©º<¨ª™Ej7Ò£gnE‚Ùs„Sby¢€`ŠzP\fÆîN@p3xÈê pãÛ2qK© ñV19 ø)Ó<Ú•ˆ€¾ïͬV w»¨ ‰ÉI 3C5óD R‚U2mÍ„€Üᥖ>KÃÀÓ«Tr.óâÁ¬T¿ËGc³Š»; ,ôðp¥ð°™m¶!?ˆö’[¹ÈÚHä«7#»”‰H¢å*«»“0Dœ,gn¬ÎU»ç Æ·†¯­ÞXaø»DäZW»…¤FA­T×ýS;¢ªJæL‰¨ã2íSÚT»ÊÝ6ggujíЮ*™™š7Æ:©[˜?Þ?ªÃ ’•T‰(¥$‰E$'böˆâº˜-ª‹šÊJ¿¥ÆüBZ´?Q8A¸¥Ø?%h„ ‚ʼn"4X[¡K]ó=íªè" yj‡Ù…ŒPÝÍÃÍ),-TàpR@Öô{+ ŠØ‰M ë¿Dhε±\ßþÌ," J)!rèšiMÙH« È«~º]YkÁO6÷–2'rÉoo(Wb0‹8Ø,rî k(àÒ§1a;,n!Ò’ º¬ ­*”R¦>ƒÝ+)‡¯”¹p„{#=¯Eyü¡hç9?¹ÂO Šþb ¢vÆï'ƒ6!ÉJÉb<>2I–”R Ê©×R°S4agÊ‘J!S1ul7¹Z‚Ì:¯2‚Ö9D /ÿ#΋Ëx OI~k”¿»¹UuJ™ÂÈÐ$ØÌŠhünâždà4Š$ò RªA˜>I kjàRŠ…çœÛöt:ÕZ#"çláìΓ~\r#"Vû®Sâœ3! W›H3º.¥!-º”jótÎCÞR_?<¦Óòr;~÷þîö÷·óÛ÷z=Ȱ{sõùßüZöýÝï)"!%P7 ݲ NUSêºÍ¶’—ùÌ}¿¿~1LS¨™9˜;ÊL¤æ-ìA múEîÖo¶M@˜%#hYjp ØbsU·RßEæ`,>Á¦KD¤çòŸÿ÷ÿó«÷ß-ïÇÝö¯þí_]ÿê—Ç»‡»ÇÃ݇/_vW?{óúÍnÓ2•åÁ–•_ŽÛÏ_ïÇëÙ}>ÔCÕåPçÙ¿9}½ÿâõkéÿËßý?_ûõ›«¾›ËÐ\4+!Ò@ƒgG CqIujêÇO—ÿä ]zioƒã†”@ìM«ÏéiôÐ:§À*«„{ËŽaþÿPÍýe’ðqˆõéã£E™Õi:ÉbcA¨YTÙtZpIr&KPŸ­,(‰Ys•MÊ©#¼ÔÙÎ@XPp³º¹o·›aØ Ãæt7=ܟϧlCªìË‚aèSí>$J™ëlÓùÜc ,çiè0näjØï·»Ð… 0K*‹W+9ËógW_|±v‚ÝßßÎ÷KûÞŸwÌüÕoçûw¦Çùí7ßžåaÚ?‚–Woä…¤ÓÙsõÇóR|v8ÃÕËý³Ÿ¿:<Îý8l†yW¯zË2ŸïÊ]”é Ýbqû«¼%/”tÒ¶ÛÆ6Ç’£à«¯¾¾½ƒt¥!RbÐé P‚–z:ÙÄÎÕ¦¥ PO†nÐΆ…êl†e9‹HNi:‡Ãáð8ŸTÌÈNX/;u­ÎW,0sY|:.˲p*”ç7_tï¿lw;-¦ES—Ÿ_½¶Ъ\±Ýb¿¥ë΋[Èt6[@ÁIz¡gðìcb¤% º 0MÐùSBõg› )[-E¦]2„d>Mçj5ÈOó4Ïó¸Ý\Ý\§É݇Ãn;š¯4žï¾ywœ»çƒ I§ùt®g?8$Ë0T3 Âµ¥v­[Yü¢ï§TsÌžˆ¨ ¯Ÿ¤ùŒçá" hÕIó¿k„‡k›¡YwAñCsÿ§Ë¨F‹'b'º§.·ƒ B`fF‹o@¸{uB+eŸÊæ°Dɔ܉™…SŸrνYm7ܲÉcØ`攄ˆX‚³V.-³9I3EÀ‹N÷sÊD.!N‰ú _ÂzüpÒgÌŽØDåÝfÈšÔq-]ßuW}¹ª£zµ‹M§Œi.x˜p¯8ŽiÞ s­3½£7)oNÎîu‚,Q0Ì=ôÉœ5M`&"gfîª,][L~ Y`æsµÖ/­á´k‹ÚÒ.ü“ ÉUÕ%´D‹ˆÛ~«ê-3]DXº–gap5qJôQ7Ÿó¤ÖuI%IR âÇéh ¹g&ŽUbi —aÙMÐ@)Q{]Mñ¿Ò/B$ªÖ¾Ôfç6WçÖB˜Ö4Ý͙ӈF`EsE ‹6U5ƒ±77 ‹°?ù³ã)oú§‡qá—·Sc éI¶Ìû~¼êÇ“Ÿ@ä™kŠYKOÌŒ,2äÌ)7¯‹»«L-]gÄi?äD,•áfU}¶:k].ÅÀÁ«dkõS8<¬ÍÈíÓ¸£6¿|Ú€Ù“þ#Û”.7쥊`|óAáL åÔDbYxuÂ,¸´èD‰Yˆ‹K0]D˜VŸW3Ó9AðI ù¥ø%ðÅõ‡£±bÝ]¹·=+"BÂYÖØFkgfn:7’ÄävÇR묺ßlD:t´"f²Èf¨ïRï4Kî4-H‚\!¤ˆQ];JÈ‚.Y­s…ÓSõ FÃ~’S<óŸ6TÿË™‰â¿Z/÷çŸ3C„²(ì‰@dt$m£bs|µ1F m'4XZÊ’ºeÑHÎHeÍ‘[Ÿ ú42¢ÍÚâ“ËæÓõ(µj›V¢8Á9¨aŠGÇÒsêHzæÅk&T­Näž<ñšXÓN#ã)´ùÄÚýÓ„¾ 3“ÕhíP»}…‰¶‘ §”*´š"HrJ)—óÃ4醞åͳn?¿=LÿåÛî¼ýÇÿøŸ¾ùí÷óï¦nÛqºÆínÇÃý»óýa+9Ù¦êdœ=K¿¿¾ÎWû;èqZö/^î_oííãôö~¹?Sû†™k‹/jZÕÚþ‰“H‚zøZ3³t8–e‘œ‚E2…™Ù<—†àH]–.'…—i*Ì»a=.¿ý·»¹úåõ›Ç:åaw«úÎËw6­ƒn7ÑeŸ,t¸êo6›y„½Ù)5sî7Øýýù÷ß|ØM¯ß<ÛvÛ—×Ï÷€ã|øý·µ?|øû/Ë—ï6º«ž&Óp'‚‚ÛWGFÿAðu _cÛ~ž +—èã¡ §XypG4ct»Q8ÚT@ÖHóÙdo4‰REq!9ô<Ÿnéî=b˼ëúqK£+¸(ÙìZÜœRFO*QÔ‹k¡·Ø@¶I,’‰/K´,s©µÅ’H®ž=îuáÇå÷Óï½PÁÕFú1nö7ÏúºçÓùát>N›Ífš§¹âúº{±ÙQ×}.y; ×eaLQ€zè1^çg7×W~ò;ªõûáæzxóz¼~9,v.Ï”“âÝWïK·ùe¾¹º_od׿;óþ›Ûûr>”r°ëp½­§Þ¿yww®Ðº¼ósBèdÆbE°PÎtóûÇ0«W5£K•Â)ŠÎGã@—Ñ' ‰7yÜÈÀé §ù‘:¦¾§Ü™K™”=’ãºMçÜ{¾–«7W/~ùªll»îôXo9mw;9ÞßÏSM ;°í·Ã68¦iY–i:Ý͹ܟ溨Ã5¨‚¸‚qÏåý·Eú»ëgðWßx)è^O/òˉ&lvãþù5u §Bˆ¬éþt.¥ ]×už­–ÓãáN^þ|›Æ|ý¬»ºMàÒëx8Â5È=Tí\ÈË4/©¡ú8§Óã Û»4FŽóù8OÓõ~/"}?FØÛ·o=h™ËÕ~“R:LÇù0gä¡ï† ¼Æ2[)¶Tx"Q¸þ„_ˆÿ2— ùq"-{À#‚W¿4ƒŒÐ"žÃÅ£54ko ëi4 ÷Vp¯Ëò Hl!@Þp–þlÅ¥bÉ,Nw²&’r9Dh5Î6Ö 1!S芄­^]UËÒŒ®ë™(w ›\YD$„81q{x 3;š`/$:`Aw’´'XâèÄ4ÑIð¡èß?àö¯2öI­×TÝRÚäôœË9ÀM¾úÙž6–:N' k„×’UÙü*l«À‚yAB9¢)"ä¨jÁHëˆÔ`œÑ¬B­!wr%a·ððpPbišþ¢Õµ™zœ/é í)NÜZOp’±§i©f¤”[$±zQ›ÕËj_géónÓ…f.¤€3Y‹k †|4SDpTvvPEû)‹Á‚|ª°h'h=7 rŠ0'{órs2áJR€…Q˜B›Ë™{3ˆVs3¬´».P²è#¨š2Îæ'ÃXÂ̪;÷òqd°*Ñ€øa0ÑÓ=J@Ï¢!0‘BžÃÅ"»n%ízÉÕjÊ,tV=œæH ëÒ˜3K¬mÛ0Â…B’#¬¨×u&r:Í,‹ç ™’’ƒcRTBe®DD¬HĈ°ö9ý9€ $„”ÜÍÅšiÜ FX¬X÷V7À¥I ÒÄ9z¤Ü!( a]êÛ½%¨;‚H˜ÈË⥸ª"4Uu´ÓÜžD0¹5tRä°°µþªEÝ7»Þ¦µÅÖ™™7ΦÕ°n[ÈÞ! «Uhq-NTÁ-f­à9naD‹ŽHc'î¥ÆäÈ”!C7 ¥Ê*²ˆª¡0 J¤®•µTr‹ 8¡ù8ÐÈ ­-üô÷Ÿ~ý3ðsø!ëéGÈ  ‰%þ„׈~øÚ@A‚9K4×–9y¸¶X™µÂep5vtÍ»¦°€…E/ö„Ì#x”©¸#ud)x…Ú]Vðð§&“p±Ã}ìñºüQÀ ‘6$AƒJPÔðkD²0F´h»à—öT¥†Ïv7mLÏœ{-^k%¢f›L)m6›eYÜ]‰ˆ„›Ð) œS󒘙i5 O”γ×ʸê¶[¹’!É,䑉©Ä ýÝ»o¿ù_ñ7ý?þ_¿ñ;Ae 9Åa8¿{P_ôýÜÏ’C"µè¼,óTë"]êw»go^ñfûáÝ÷˲|öæç_<ÿ|N\ÞŸŠpó[U3w0‡p7ä3s‘6PF5ÍHcʶMÃ0¬£ÕU³j5ËØõY¥$ -DN,}‡Œêvu½ÿÅßþ«‡:ÿæÿø_ûÃ÷û¾"åt=>þn¡É¯móüÙîæÕË:/_Ý~øí»÷›¿úucÌÇBE3×óŒdwßÝQ<–Ó¹¾ýêÃí?|9¦ÝÎôå‘|Kƒ iB4¹ ÖY!}®ù59° IDATÅJô£f¤K-Bwe,¯ßËáú&Æm'´P™=ÜÝnm=IüÓYs‘•`36 0#¤Ô#(°ÜÙy{<ìýñÝ0<ïúMŠÁ§fý¨TU‰“F-çù\¦ÓáHóN®òÙãáÛÇRÒÛ ØtwU©@"†1s"š4›«q“IoOóãñ‘ë!ÏûýsA¾»;|ÿÝ}}ÄV™¸‹y¯µ–i>fv6iÿæy%zûýýÁæÌɃçsu"qQ+’ôêšæ3=nøtWæól„>õçYÝ9ç\æùÙþÕ›W/—:¸}G¡ªå<éùÝ)<‚ ƒènÜyIçãyôíýá Åéòg×Rj}x{x8n·[êdâòýr+žºnS­Ì3}…-•™Ýrû÷'ùú´\u7ŸïŸ?ëþo2R-ر.õá] qO ?MÁŽÐ8ÌfœrGŸõ)íñë²éžm®3Ò—ÿø­ôøâ‹ŸWSézʸ-ÓTÀFûq«ç™|¾Ù_í;*s=Ÿâ|ò.h)dUŽÆ@ý¯Þ©þñ÷Á¬†-’»!w]ÊÂÄÒåZÎ9ÍFá,∨å))ƒºvƒ˜£“.VZŒƒˆ’ä”8Ñ4ÚýS}A-ˆ„FŒO)ç¾,Õµ°¤¶+ú~~xô>³HKÕJ}rw/ÅÔ÷‰±è²¨ ˆ(ÔfŒ†³87ne);J)--(„=ñBŠfHs ÎbÏ_^ÝÞߦa”¨C“ŽöØï mÏ÷_Ÿ»<êl=Éë—uÿêïBÞŽÝCÏ%ÒœêüQÊs’ë}OÇeê2è `H8dHªí9õ±‚FôPŒçØã @'šú߯q|„œ@‰t©“¹Î“áÔQFPl¶•Œ-RJ(¥ Àv>òæªï³ª/uffÙ=Üò¶ƒ%rv7«îÖÄÎÌ ¢ LÙ´ßn§i ­ãÕõ¢UO ?×9Iî÷=‘„F©5‚œ"o·ˆ> sŽ I=úÊ'_[Îó5e+¥šÓ½«$÷ÒßBGo5Š¥Þ$w8yTǽÂ'B ÀŒ‚…I‚…©À aaω:G¸"z>Œ2 u9X¹w»·8ÍKMŒ”Ì ûÈ'¤ë»ZkE%Qó€bëô¼ÛlÓøvšn«=;.ä KÔx÷$ ot$ÂÇàŠ¶Wù´YòÔ,phI”(wîCÈ3Ð>Œõ|¢rì—Æ!…ARî!jpWs,%Úæ*I‡èRå(¥PŠ ÉÀ)!•èl|Š|DCfOÄ!¬‰§ˆÅŽ.¨w&hNLL$AbEUa'‰Pd]=¶pÕ«ìADäÁLXoáB ‘h€…Åbc4õΪëÌ ­áNžYX‚”pi2£cÉ+Â,Ô‘=QW8,B©K9³d€«ETjÀŒ‚úŽÔ0O]×Ù¡ÕA"’rFOÅ´”%§êæJŽ ƒIÄVÆ1Ø‚KäðŽRŸ{®Î=,`ìÇÑK=ËÎÓ2/ÛÜëÃy0täªàŒ¹FßÃûΦé8/º,¡5q0Cֺń°©~Bކ} ‚úSAO­òjòeõx*ô?ýõ)øðÒ°hù‡ÚX#°@ŸxoèºT<1¦âÇO\œ;±‚Å ¦¶*„`=!°P­}wùG‚|mR‘iÓõµÖ0ߤE5¢Ï´œ¢Lè7D™ÏÅ:týéÃ2n1$ ?-W2Àƒglò¶4J/9Zh <(¢ïºuWCtÙ„©x•!áî?Í9 Wµ©ž«IJ¹k ê‰pJÂLT•‹ÓBìÄ®MŽl‰Øº&*œ[p|dæ<ކ(eI]꺎’¨êÃt\–€HÊ–(J&âl¶8QJè’<]mÞžîÒÜëi“ºKž}¸«η‡¹ì®û7ݯ†ý £½Ø¿8êÃíý‡ÃìÅqœ¯ÒvŠ%u²IÝèì”n¶Ïbýîjóæõq^úŒê·×CÍåÓ°ßþêû¢þñ?_>?o_Ž£^×çóîÇót÷ö&lúõÍæ™ù¿üæwç°ûûÛëw¿˜ÎËm~ûù·ou{Óï®ÞJ=שcÞds›Ak9|[0E# EÄå6X{T‰R³Õ™®6}B´T5rö`âv­KKÐF,ÙápóU—¦)!C€ÿåsDô¥d„¹Ó>þtÎ7Û»ûqÛõIDX–¢EµZ©ÕS(KßmSî¯Ü¢K[b`Šc^ÎχcÙë6®É ýy.jµÂçùÙìqbšxl)ªÌ0F5=Ÿg²ä•#Þ?Æ0Æv3Ü=|;ô›‰góyâ‰}ìñË¿~÷ÍýÖËtx~Ü8¾ô2l;PJº½£ÝÛMºÊµ°2 Ý|Æt@Ÿ)£¥N U݌㻅F q•·]ll ¦y©ý9@d¶¥n×]õ›ÔyòEˌЃ/ÊÙûÞ<`\–ÇG3?œtž ÀÍ5ov×9ç¢K)åXOó\Ë‚a;Fî˜X A}ívœ Å\‘= ÜohØz¿­<Òéê6/Oåñ … Ãls1užq½îv;-±—I¡±•,œsß!¥"VµFh·KWßqí§éX¦óqÆu·M;ax\W‘H”ìˆe_ÇÍððp_ËÓÇŸÊ~e\Ýw\3 ›ª€I au“nòhìÓiYæÊD‰£Ø$Äc?<Ü]/^NÓqÑšÆ|ÿæ¡{~|ªV©,‹–r5ØbèÓ8 }®Ïhp7Øâ_ÍÀð߆R¬hÝ)+‹h­§‚øò’ŒW«8 tùçjˆ  •~{¸‰€ÁÌáÔšŸ¸Á[E?‚‰È]a¦ p"NÌ0x-rB­9[HE23[ò0[[¦[Ñ@x¨!|èzGÔk ¨œ¸ë)b1«@õAe+ýȘ{˜jQJä "OÆR+÷5ÛáXŸÉë³U‚ xD} ž"W÷Të©Ö³¡iÊýÌ•$ü†|Û!ói¦ÄÃn˜CUHÕ.óMo7vD»ì¸£î>Í76=¹F‰¢V œ‹²9Ü ¦Nti­jÁD¸F$pHⵕ¥Ù%#5Z, ^3ÿ¾VÏx[D[åVf#i0 „!–€Ôps$Œb®Q\0¤<]f)T)”Lˆˆ™˜ ªUàF§Ë!Í úÖ5¬ˆlÎ 2ò ã öVhØÚç<ír E$·ž¤j-Ûs`W6#(ÈVߘ½bRœ(È A‘‰DRHÒ¬Öz` nRÃB²ö‚È‚ªÓkt Y°Hp±¡¯«Á×U=r»=8H˜‚¥ÎÐ3î7Û¾ÇÒÇÌ^%ÁAêAD¸´M6¨5§‹ÈqšÙ:1 I"’§ä 㬞#²»¨»zX¸“Q¸PS*ž,rmD.rñ–JDÒ–èáe²–­úJ+àUºP®²P¬É¢h]´È) „‘#¤Ü0+ÄKx‹Í4d¬ zG\zá ŽÐPC¶¯<\ŒUŒ"8·íËLÛ€¬IÜaAD’{H&Pu²V)¶rò ƒtìæªÆDimy.®dDHAî!r"v"'’@ neik[™)U9ÈÄëD¹Z¿šK1”`€키µz›áA@D `_Ç´2OèkÛÿ—ÿØ/ÀÅ@ÆñÏkDí /®¡õF}ÍáÐ׊”_ÎÄâ  ´!S³š’¸08¨ž ›˜*šª-Z'(B*ÈL]ŸÇÇ«]³¥çe®B SRŠ Ò–ª´Æc¥‹©©mÃÑàcŽðXÿ ¯p6#\¸X—¡ž½¡ËÍO &¦$°0Mˆä¡‹ê¬:9œ!«3œ<œ…)·2–zµš%›»ª!¥”R&JVÝJi‚ ºí 7Û_üw?|\öÏç½q:yÝ&®Ãvc‡Z}Ún¯ùfÇ·ÃÛ_ÇcþÝþÐÝvÛ~ûÂóIUœÕƒr¢.õ}¿õ(K=—ZºçÃ~øôáãùp.ÃBS¡àZJ (æ¡'"¥0«0ó°Ù¬®ZµVñBNÎäV5h¼ÈÏmJÉjç9¬#œûƯ黟ëô¢ó|0OöÝ»ûg;Êpûáô\F?Ä©Îqw³=vý¶ï¶éj“®ö;Þ˾ýÕßߨ§rüé9©}÷ý›«·[:ÎÛÎ]Y¦º{{ûW¿þµýþóüa×ß\}wuþí ‚KKÔTY8‰…®†Wx_{€Óë_1!Û`€¹õAµ¾C@Z7Ï¥¡§‰êðö4`S08©•3Sð_º}›.n>rB¤`` ªá¸ÇçóöÑoOC¾éÂSX°kB©+Ù] j æe)’Ò0 }7ºÅrŠåQÓXê¨OãÐfqÔé4/Çñ주¸,¼Áx·»E§Õ'FxÝL‹Ÿ–gÂóg_ÎPôT@;>>/¿;¼/Ç#™ˆ™ïvy ôïþæßü»÷×û§OøÝ?üïÿó§Ç§«««û¡Kc¾énÇÛî¥>í_^~þé‘K|øüt||Ʋ`ë½aóÓï?}9{ÕÊÜo‡dÛQÅáxÞ¿ì ÜW“åŒëÝæo¾ÿ¶œ¦çDzTÌŠºÀi¢‚ã N`†y©EÑuFº}øöúö¦ëº—ãËãÓ§é8OnÐ'FCÏ“åìI U;wÛØÜØî!®Þbs«e˜ŒýpÝuÚ%ô YŒÃx™M§Cí!Ìÿ3îºí»‡—ÓñDG6¹¹½º½¾®“9éûŸ?ƒÄg_Ôl“’¹•(Fn²l®øÛ_\É­øtœöÀŒNfš½èâ¢Æu^Ž{>sYŒ¾½ÝöW7Û~/?“aT-â0‰å‘‡M®äË)öÀ¹Jc•Ây6.aEYºD8i©çâã8"©ô¹¸QIÝiZ䮾œ÷V5s%Ïp‰ «h úRÃúpŽÓJemPº E_‹nýl@3nÅÚÕ½žÆÛ‘œZL¹©Ïëïu IHH¤C°+le/PXÈë&´µˆyU ˆ0·¾ì ¹!r$ÄÌ,9ga:Ogh@Zèå-HÄÜüL,ÌÂ$ÌÂ^jxx°ËÀy“k”2)P‚Å8@dNlš"q-TÚßK/ãR˜°‘=®¼„ÕRlë¹"rŸRÖjæH)©žIIœÏó2ìz7‘±dâi³éî6ù¡/£Ë˜"$Òߎ˕ÇPQªš«“Bˆ$9Xkuo#"»E‰!jÆ-3“ˆ€ÙZè"œ8¯Æ 7C´b ó Iî „Z—àküÄÁOíð׸ä` fN-—´˜‚\¥V5geµÓ4œ.qãìê+Mökç™yRB‹¶‡®,NwwxónF„¹Úq5ÜÖ ¥€D$Cnl%"¨nÜš›2./¦ÖIE…haBÄ’:A6O‰;ÎYƒ<(¨eiÖmÀ+âæ5e—\ü5”D¬¯ ¡àÛ@Ò1¤—Jz¨Ë)×ÚBVfV‹’[˜”Y‰¨†i(åÆ:…_ºIVY•$ƒS8ÂÜ4ÌPݹeĉsx[Ž»%bi÷)¡­mu¾ØB¾ˆ—ÀÔåÿî«¥þµƒ›làB$í{U¸r–㫎>»`ÖbÉ–Çh»þòr‘>þÙã>³ˆ¤}5à` ¥$‚–kõ/îM¦ªªÞJ„AÍÌn¡–¹ÍðÁ HD‰˜™ë2È!QA50)&ÕÉÐJD˜Ñ‹Ì Œˆ°X; °`L‘¬ï땃KB ¯¦¯ÙCÿõ]ñGEß_]¥_{çþ_+zþÄŒGáÿt¡Öp^ ¤`!‚Kad@cs·9 L Ýv“†laˆ¤ÓnYp# o¥kNh1-K5K™É™ îN†öp§¸\+)l}÷éZßr¹[="BAœs£9¯3R ñ32SsÕZƒ¼˜„(ð³*³…ž´Ì®À‰hbu„ˆäDÁ"ìVkUm¯EÇ»UsH¨aÐPáJ!j;¡MÇ»¡¿¿Îg'.o¯œ÷ǰ*™—2…ò¾,sµ«_½ýöÍÛñôœ%¹ì=?¿œ·})º»½™m9ÎçòO‡ãÓÓ“‚ú~$óäØHO9bÒχ÷®!Å·˜yíÊkæy‘®ëÆq¬µ–y6³0gfw ™¹§‹H÷Ô#¨êܲQZE¤˜ªÕÍ0¤ÓYYùa[’õãxóÍ}¾Ë¥z˜ïû«ë?~¬Eß=¼ëeüù§÷O¯w»_üõ/‡›|~¿W>_]cË™|á)áîíí&ÆÞs‚‡›xi . jÓóeñÝ€ÿ¸‰q½Àøµ¹±€Vš#7u´Üês/ŽÍ°·†Ïpgæô—瑬丶ç–vL0O5 6X{”±ß<ÓŒýQŸvo62Pß ›M6EY|öF¯œóf³úÍ4-uB=E@>SǧL"”ÈbP ËÇǽàÇ@Eäöꪓ4ë©öƼ­‹îŸO¾ÌÇÃ2àgMY”"Ù¬/ó ÕÚ3D½ lBì8QµžóØoÞ<¼»ºú;¦´»¾ÞÞl‡«MŒq¬§?üöåS9¼ÓÑt~¬/p¶n¦—jä~ØìÒ0¦"ùOÓ˹˜:rÇ’A„1ÓíÝææ~s‚÷,Œ´¢áÁ„ó0£y#ú›Í0n6ý°ãÜÂÂ> ¢”€=ŠºÏ^&Í`N˜›“¦ ¶wùöMwõÐ_ßuût¦„¥ ¾qµú4žg_,´j­î>O– ÂÐa³ú«Í÷ßðS²ª¶hp( ÉÓ(È ÎTQܽ£jì5œzD^úëîÛ®6ßJ=ÍÇE°ÿûù8GL‹—€dF:žj}_í µ‰*Ýüü|žOD8\÷Ô9§®ßñ¸ËèÆZhÏ”<¢“ÄÌ)åD‰³¯e^¦ålî)¡ß$Iþrü\ÊLoÞ¼òP¦89LJdz+„ ê‚YaŒDŽ×bÖ/¥6ÿÿ:åþI˜–›eýrRe€ÃÁ”ÞVü´ª ”Á+ÿsÍQÓj6‘/»Ûõ#·/Î3ÑšFcM¯7'[ÛÈ´Ñ(ñ×LÝÃ/Ï™L`D"H'Ý™np2kz!%fšK!I"9çÄ’=B§bTº­; lÓX 6$‡˜‘ÛÑÍÌÁL Ü4ó˜ûA}–ŽúÛn>wÉ£>žëAÑnW ç.,`$€;ˆY!HȆ¥K °Ñ]­ë·ÝÍHW IQ‹Q lèHg°›2E0¤•øÒ5Î@äîä.’Z Ÿ™·]“´IàÂGpÓÆljT¹Ë„‚HÃI¸]Ï™s]×Õ¼«ù¹ÅJ8‚µV- q°äÈcxj¯Ž6Ù®%‚ÑZ2ŒFë¼AѸ+Šø’2iÄ"„ÙÅ6ª¶¦ VOä@z¢‘Só­ù¥«ƒ™Ú¾–^_e-÷åDg”’ÀI‰H$QNZ\)Ì×K]^},_–´ö¡ÿÉÍõÚ=Íp ƒ3bq Þ1w™pöò¤ó)‡÷ܽ&q‰â‹Ä 0E´]ƒ:áb-äëP"’"²¢³`sÔ0 ÷õTÝ>åuøŒÖØèKÁ ¡ùºŠ]áMv»L Â(|…Ë|õã2þ­–›bCëM^+%/¡äU‘ˆhȘv ÛZ…~IÔD¸‡…y0ƒmµá®5——ú¸¯•N_¾Ú—ϨÅBXÀÌn¨fÎÍTæÎ­AáU óµ1Ü2Gff°$½™2³0Ÿ ™C @,°ÅëÙPÍ7;Ô!+À€Á€0±AÖ»3˜Ð¾îí¤å—CRûš\Ž+ñ©UáË”ø/›…þ¤üíÏÖÓµù÷Ͼþ¤Êôõ×0.[ªp§õ¢EÎRPbd´Ö%'rAPë RP ´T4ç®×ZçbÑg" —¨¡ªË\Îežc;2`’ˆ˜ƒ½!x¿Œy`¸Uô¸­Ð¥Ñ† ¼îe¬íÏ[˜ÊI˜˜›ìÙN³ÞŽºæKØIKÔÅKX¥ÐõÒ5÷P«k¯j¸šfN$LÎA°p±#¥¤ªD$Ä,Ü^—†8ÍL}J9mµ¤@­Ëãþp,ÓTõ‡w߸ZB¼<=‘Ç/ñ½“ô||ùÀ‚Óé4Ow7·Ÿ?|ŒªBY1lòÍíý¤INÇå8O=¯«®ÖüýŸþÃÿÕ¥þz¼z»½[h9œ^Pj'}TÓª¦L$œ%uCŸû^D¬Öæn{•03¹t&µï‰k5˜E§Ôw9ç\ÂÔZÕj×ÏeÿÓéîÆ·¿úÞPÅ$¾½¿ÿÃO?žþ¼½¿âb=º§çÇ©”w¿úu?ޱ³CQ}™ÏÕÇq»y¸}ÿÛ§“O:¸ÜÈÍw×>:úóùÓ­ì2[—èéñãÓó§ïøå.ݼÿÇ©C,¡ʈµÎÐTX<À€®äpâV§áLté¯ŠÕ C 4ÔzS×â¶› 0 Ö[[3W´æå%M‘˜„Ý3AÙ‰ˆ¿”,2­Õ½ícÜêyO¿_Ì»kp_£r8ô7¸¾MݮϩK=’˜@Ó8nÆaËÜy)Ë9æCØI®ÙÃIKع²q®]æíçé$EDJd€GÎDãȽƒs!¤–p“$Ù‚´Û ß½{{µëb9ét(‡—iBÌ0̇3~ÿ÷¿Ù Ù C—®¯îÛCªK}ßgËþøñýa*Èøþ—×Ó‡ú|˜NGœg°àóÁ–ß|þñéýKñÙ0ô‡íö¸I»ŒLB¥§ 1gÆ«ÔO¦mÑÊ///ÇýátšÊ‚pA¢K©»Ýp5+¥¸[îÒf³ÙîvyÌS)ósU-çr$áÛ«»”˜ÿ<}\ ޗ ãXÙçÈ7¹ßõî·£¥e3б¬â¾;îg*óRË|¶œQ+¦‚Í?üâúþÍz$!xÔyÖ'ýdµtÒy7°H˜Ý\"„$ CÚÅö.¿ýáúþ¯zÙNϧe¨þ¼,ϰZ"ɸûív>Ñroäp8\ßÝ.ÇšB~xóÍùñåÿüýﯮ¶Yyô=o(Ým6›ëÛûo–ˆüñG#tãpwÏ)ãæññÙ–óëÝæû7ïvýöåã>ž«Úº€/¶”R œ¹k…‰¹,K)¥I^­ñßÃØÑÊG’tÌlªª$¡êf]×ÝÜ\w]wžÖiÐf{<¼¤~9Èr÷öíÍ¿ùî4¿ˆ–s”.§ÇŸ?\ËpÛ]I‰ ýíï~·}¸ýþû_;çÓ?¶¼¤”ñx<îOÛ«~ûíÖ’Mr*6¥k^ŽËtzJlw·Û)–—ýÇ·ß½ÝÞ½ûå¿ýÕÏÿñwR@È‚k´Mœ¤mëˆãàV ÷s­-Èå,ÖdšÞDðÈ ±„7m|},DXDŠP'aêIÚ"/'PÆ_\#‚.$7¬Õ`€†ñ¦ú©.Ëþ£•rÚ\ÉÍÃxývk/Oª~šÝQ·qô뱃RqÃ4-ZæÊÆ›¼ ²”)™’Ô©ÖcIšGê{ uá"œ‚§ùdvŠ.É­°q×g-‘kÚqR÷ܧÛÛíÐǶӫëÔŸ'¯õ#R 9>¿ÿ›M·Ãn·ËÒ?~~~y:̧’¶\ÒòûÇÏý-nnî¿þæo÷¿=NÓqÁbLöù§§"ùO:Ÿ* @ujÛPtf˜—ƒ^ŸqL´3«‹ŸÎK%œŽuš=M3@¨Š¥ Ð÷7›Ý‘ŸOç—ô×ã &r/Ï×Ûë¾r'E="˜9˜ ’²l®6‹žóV†ëîêfss;—Í|fô Á¬KßoæyFƸÝðfè˜$E÷û§OÓé•]QÕÐÉ"QÛ‡ýËF£F#"¢¦¦âb™»$ˆà bB8¢ „¤MAöO Æ ÷ƒ9¢Åã²Mi­iþ•/×ײ_bBC„TÉÍ‚Hä Ü•˜‰¥ýñ™r¦- âY²‡×ö&Œ”¤KyòvTU›µ.Å5Vîž$]N4°°„;JQÍ)I×' EËã´'Gp8B#@Ôea•¥ªÕ%*層Ýv}™v qÜJÛɘD’z#y»iñyF­Úeë(’6E&ôŽÂ´¨*Q)‘Gê»M®úãv@Ž6X\€‚DÂh3?.kù?·Åm&±j+Í–aªÄ, š.nX«º™Zˆ»¥¨ u®(Õ)Q+5qN9,ç~õ£ 'ˆ Dfœ8õ=\"ÌE*­»–ØY¥¶Ÿ p¯ÁÓuQÝ|rÖœ€íïµ´J#¤ §öÉÆª ÔÊ´aÞ‘Œ)eÂT´¬eSìhJ3ƒZäürõ»¯UŠ pV‹ t$NXÌ'ÕÙµ¸5«ìEõ„_ŠE¾tìþ“Yèõ^sp°Ð#¶› Â.q?$Í8!Î)¦ŽK¦J¡¡Š.3¸côÑ™Ìc CXжSwƒ†-´`©ºØ[xö˜Í‹¹º[#©K#›y¸™³‡:eÀ™B—ú€U¸+°‚bÀÔ̯<Ö¯ïtw_kÊ=.¡úVŽM‰8z²Ž›£ž`îÕ¬š¢ë¢e:^›È 7šAFqv a¼9ù×éúãfÿ¯Äd""†TƒBÍH5R3;0]Ð]++)ZÀ¾i\xQ&®ní(»‚bÌÝSb!wIí§’XWÃ1áReßâ+àVÿ ÍÎÊ v_A výaÄô¥u{-ÿ LðÏbþ9èë»\þg~KKˆùW[ðø2 G£2D )òj¶úÛ¤K!G0G$BŠÈ!H8™˜Ù¥Ù÷Âá6¤!³$‡Zxq’ÔYÔ Üri Z½O Õ kCŸ5úˆ Iš:Ô0—Ó•ÚªR™›Eæ@f _²[Mób$1jxD€“AÛr†È F«š,,Ägn¥Æ,Šp­®¾>ÚiäõùÐÜàYƒHÝÍLý:õA…V/pCÇ"~úðd¤×c? yвt•´,··»´ýX>îhøÕ›ï_Ïûß}`MçósŸ»Ò«VË5Roz˜M Ä›®—”%8s¾ÙÝćýéáÝ_]ïnî··QLçZNK9WÑyèû¶à ¦•Rܽ±æ«àKëMGY¤µËšG‰âf:/²a°0³p¦L8Éét¾Jã›oßÝýú»þÛÝËÓén¼:úøÛßþöô¸¿ys{Çz^–°Ÿ?þÿþ‰>Ÿæúáùù§ÇOé Û]7Ëþãá¯nßÝõ7)ñù´Ÿ©šï¿{s§°Ç̾,çgí%õ˜ëé§÷¿?Î'äà>¥‘ÙVÂwòääMùi»ÁK_èE6Õt_UŒðW vç7e©q ›ÛVÐU+›»-yûõ, i7Ë_z"ºD0Íkö‘0-jî(^fçgtƒÎOÕŽãíw[¦8DÙ”´Cº†ŒN'äeYN‡™ZÀ ëÍ6%.TsG¡±Ô2MçT2(3u=Õ›Í ÉkeŽPÎC5ÝvWãnC‘(ª¸¸Úîò²|>çwwoï¯ò²ÝÄ}ž®ê|°”ë<ëóó3øî|.ÇçùãïOË~ø8E™ÚáøáÛû7ßÝvïþ>}˜ SÀò¦Ã°›ër8O/gœ rE‰2 Ö¥‰©+ÆJ´ÔʽŸ‘zT‡M‹bK°öI˜,i|$ëçcQ­^Ìj0ª–ZçÅm™õjŽa‹«±»½s'%âj¼­Ç.7³°3¦¼c2;G¡ÓžKœOa©—zyºtS™§3 Ö³M…Ô“ä!ø\=;yJUò¦Ø0Í ‰ÎóËò2Õ#b'‚‚„R–nžÎ† f3[Ns؈k’Zh)Åm“©'teñ¢z„‘s! IÈÁ]ÚÕSøl¶Ã-†ÍèîTùt:íñÜõl¼9-ÇO‡y l®m˜ø¦ðYë¹”suî^‹.n×ÔíÆ›ýržÎ3¹CÞ?¿üCù‡oîÆ®5õ¸»»~¸½9<¿ŒýçÇ|Ø?é䀂äÑJþrÂjs†¯ѪG3¯˜æ5GüuÏj¬Ý×ÿH1_Ž8AÑ Vø¹VfŠXÛ®#¼æ¿$Ô™£ýÁ‰SJîÄÜêÚNò ¥! 9>“D–œs,ÅÌP[ŒD`‡£ÂÄÅQœs–ìÙÕ]ÝŽ$pA%T5î7ÆSém¶SlØít„ûÍuÒg#±„ ªaµÚ´`*°0ÍLGs$¸8À&Ô22S°ETæ,B‡™š)ÜÁL¬p¿Ä[ÙDú‰‰d¥Ü‚#ÈÔÜÂÜuªæÖRÈdftC³Ñ™{u*†„8¬h3Ù»ªç>¹k[Ì·¿š‚çäMH5z”0s+^“æ$‡·°~;l‰HC~^!H 9ÀüJÄŠ¯é(¤+í×ùÂ)"Ôqòª¢‘™JÉ#s š–y&WP ¯f5¼e¼_õ´ˆhš8,"88}`“hÌ]€ÎZŽVNjK˜{3¼î éâû*RD—MyÛ-Ò%¢S É‘"6d×N·Ì[AÎt¦ºG}fLâ…}ñR<”Q4ˆÈI˜XHHÌÔ§D‰ˆ\¨5…—гg¡N)¡ m„xÀÜB@"7j“yPÇœˆ$((¨õ\¼ˆDNT#Û DñZ ±j )¹a1”@]ð(1DtÒe΀(BÅ-GX{Ä´5 `í˜Mp!rf0¹“¯b”#<Âh•_üµÐ–Ñ6°ô¥ß¥p´tÝà ÷ ì«ÁÅËs¬V߆;en=$f²jË_Q›°imð öàÒ“&‚‡xëæÓó“c°¼‘,Zw³Q«…ÀšbãË9>VÃß+vÙ #{½ýKä ?þòüùeØ%JÎ-tÉùeX_¾b.’‡¬+ô•Q'Íi!µ)h%-y#_¯-Ç ó@ X­…|ªªÍæ5ªÂ¹¡LPÞ9梧3úcÇîªGŽU­‚p‹»ûÚ)ÿ…÷h¯¬¦—BàÔü Môkjª+E4W­5Ô‚¹Ý-ZÔ9 œX2§üÅæDj4|+÷Ô{Vsæl«zq¡X†/–]ÂÜ5’úUsJP›[˜+Ññø,™ïò›ô4»~ÿ|”—e:žS¡ÖOÇ—óáwsXhú<ÇôpÜÝÜ8Õª5å®.ÇÇÏSÍÜ_ ]ƒ¤ìO•ç%©ñññã©;>¥G/>ígUg÷X–¥F˜ÙR ´¦”¨!Üz5q¤”Ü/µ§ªWDC3ÕZçs­¢ª}¬ª×»«ífÜ|s»yØÍYç\ûû‡O?Ïÿ÷øS)…9u׺xÝû|в‘rZöS·7Û»o®ú!Õã‹ÝÞ߇âlË%:ªÕïî†4ξ\_õLê¡o®ïßì~úí‡ßþãïïã>H„’DY¿;FßnÆU½ü /ÏËv€\I diGp»æùu—Œ0€™Aæ U%`F$ ‘·7ä_\#¢µÊâ $#䜬&BtBðE8»?é,´‹^d@w“}ÊD¸ºÞî÷ûi~)SAxÊ’™% ŒE—Ù–¥F-…}1?r'“DÃUß¼?—eReŒ9Â=gº¾Úd*dnÄq·½Ú¥ÇÇÇLúÝ7ÛïßìÎW.Íýü»§…>¿L8œŽÝf{x>NÏÓüAW²1®Þá›_Ýííí·ýv+=DG¾Ú¤«-Ÿ$'éqò\»ã¶ëú,Â"Ýù E}.<; 9·c"ŽÓY4%e Rs_*'>=}bq¸¶3¬è «ðRH‚±Ãv±‘©›»Á<…s(–e »Œ†éhϧɞàéq|Ø|úÃT¦t*¶8’›$xâBîH­x0qÞŽÜDzÐá4n)q‘TÑÁ˜Æ†Œ”Ñ¡žTÁâ LºX!‚¡é\ÏËí ìWCÒ>k’S×/¸àŽ(ÕÔÕQ8”¦ç)º¸zs}ýpC‰N§“÷nÝbêó\ò’ÏS}y nÎç;9w7ÚŸm)óÉa ª/»ë7óþÅûn³ÝÜöç£ÃáÆáq>¿ì·]w³Ýœ–S)óÕ›Û‡7·cŸB'¡¢"áÝþeyÅrÿ%¼sÔk(ãu¼ÁZšÒnðàU%ÅŸçS8·”…ìî°hÆZ 3kà€‰µ*sÀ–;¢ÁÜŒ.Æö•[çNÄ"R‹Â=HÖ]};™¶g›2‡0.ä„Ek„AX:á@÷Z<*X<Â=)JÀ ÆÎ‘¨ ¨ª‚˜p/7ô Κ2ÅRPÏÆýK}ÉiÌݘE¬]ædÎ’R©³ž æsA(ˆjž»!3 Gi_Læô‰°0sSׂº£›ú² º®K™ŒÝÔ½´È‰àkîë‰Ö¯  JLdE™¤1ú\œ:ÉYµ‚|i lîD‡ôƒ-I hÚMCE¹«»^ª–X¹ëHàUk­DÁ]?ôÃB\ƒbÅØ½¢¾©yÓ ­™‡‘™EÂ2Sfb'÷¯ÓÞÜWøZ+h>4Aˆ#ÁûÌs"¼ÔZW Òðh[Í×B‡Åqj]ÔÎŽ9b$Úpî9ÁqRÂÏ¡%B£Uø®Öư¸ÄW¾pKÿ¹ûË€fíÝw¡#K—Žf±3Å’¡X–À„Ì+Ì!™ ìp^l`ôièûœs'É«vQ»³äJ®¦ 3¨£Z(»9‚ƒ%ZG„š{¤œÄ!ÌLLÄá¦XSϘ¾N®´r¹øªOœÑÚ»Öl:yH”‚0tˆ$á2‚RèW«ÐhUxx8ñJ~§ ‰ËA¼ i„ÚœöU“¨¹¾Ê2HU™"Ñši âöi¶~‚– xx1檚ID’$òªÅ¬ÉÕmÁë—mËe|RàÊâ¢ÑD ILœHšâeX/T Mo?i:è%Š@Dp òfØ¡xÅr¿ªCiý_Ó5÷'×is&¡äW/ßë=·©‹j10÷ãF]J¹$á®ëXdÑjEqéqi2hë&D˜¹˜ ^1>îN ÷ÍvGáµÖf…’8"î¯oŒevô¬‹N¾¨Ø§§Ï//‡_½ûþ¸?½ß¾y[’½­{ÛÐãôéãó§iy¾ûææûwßq –Aþ¼ùéÓÏBPйhQ$í÷ïß}ûððë_ütx·~x·œêϽ,ûS§‘=Ãj^m}˜´¾R¢•û ´¼äˆ&õ¼Šè2Ö6Sf¢Õü˜$\ˆÅ!M‰iNúV@çHˆf.Mæ‰éRïA¯~ƒKfà_{ N+à/à›;KÀI‹1Ë æƒ=~‰²Åíwõî‡äŸ'í—ÍÝpÿMÌe:íOói¡‚:¡Ï¸ÿöÚÆ\]#4ºàºàù´ó~¤k#«îøôã7ßÞ<|×—êÇÃrÔS²®œÊáùEÕ™±ùt¨^÷o¿»Õy:<•óÿûÿú¿ß=üæúgþÝýù?¾?}¶¿ÿÝÛºðíUÒ'Ø RÂÝÛëOwèïé?/ïÿËßÿÃþŒ©" ø<ïŸ?<§Í¡­ÿŸÐ ÃÍõ{9–OO/)»«a{‡¿abÓY1Ç›rôy¯µÔ`bfH™—)t^æè{Ú2/vz9/§s1t¦WW˜¨Óñÿî)õ<½Ø§¥œ¨! Mm.wR§EË‚ iÄd˜€§—}Úí9ÃÍÐãöŠúÜYñí0޲Ñb%––v0²C9ì?<ûÏN×ÙŠãzœlgNTe’˜m6¤eª>áú~Ã{)çƒþýþñéñ´Ôòþ§Oï§ágøt'"ð´,¡¶œ‘$K"’HŸ¼–Ê)ín~úéóñåe·ß£‹,Ðû·/›·¡R¾ýå•Û’9~?¡Ë˜g§Ó¸ÙüøóÏhAø‹S þøwlÿ½X›‚·’¬Ó":VÙÍ…:9£ÿ!×zŽÝà!"R˜9àä$pU³!ð€”ReòÚš‰d"75  "gˆÐ4-,éÕëÂóeS÷RmÖ†D8È6'|l´Ø[%ŒÉû GØ’…Q’ &0S’$ƒ5KTÇìNpóišs.»Ý!ÜI£.K[ÖÁBúÝ.®U!sÊvòð¤–]¸ŒÃ0lç×–àNU¥Øˆõ]6ªs+RDFàœ8¨™Ù¬©d›ZÎ|zÿØtëIYƧŸw·Çãj#¯DÊë<w¯ê)Z„¶X– »"%·Ù´-Sû8ËimºTµˆ¦^"ÒŽs¤uiu©T«­Zï†áªê­Ó0 œ„™—e!"î…@¸›y_ß0]–½ýƒ5%÷œ³»5SN)-ëjªn¾ž—áö0Ÿ¦õ}¼ùöûï~ñõ?üðÕ7_›Ž¿ùÛ¿¿yu÷Ý÷ߟt~œÏ¿úÏ3Ÿ¦OŸ~|88‡¿ü‹_Œcv³¿ûáÇ_÷ýoûÛó§Óÿô?ÿ/ïÞ½ûýï.óó¯ÿúoÎÏËårùOÿù?_Ýî—Û÷ór™žÆA~õý·§¿..ëÃt+‡²ßÍ)I[gÞ& ø ÌGÿh#˜:žž>/ÌI6I!u6É! ²íäÙÜL—uU×â>0%bvË,£PrâpvûwÉ#ŠëK ´Ç܃RDÿvAÁ:ËŸÑVDEÎ1Œˆ]´ìáJú´¿ï÷¯œV¿ o­­h(㸓4ÛdËeÖ‹N‘rš&}˜ïòq¼Û-Ëòøár~ŠÕçǨp% n«]NIöê0Þî£Éã‡éÓOñ÷ÿå7;}zÿáyiËîÃ-Kø„ç÷øî#ïS“Xs«ñ{ûÐÆÓ?¿_«ƒvHǔҰKóPãpX–z>Ÿªéù|¦d”¢º;föqO_}³ÿ毆1ÍÏÓåqyüýsp ±< 8-º¬º„â8Ò]*ã~¯ªägÉ8g 9ûnÄÍ-~ñÝ×îõ<Ÿß?PJ7—š û1ÛŽÆÝ‘ÅjiÓ.à æXWܼŰ/_¿ùfHûóã¼Îʆ¶Ò "R$A8Â×¶,ëä³Ú³%C)ÉÙY¶ºz´j)§Â\ˆ˜sU>Ù‡æÚNöá·ççMÝæ‰|½))¬„09ï2mY7¸¢³¹`Z—•Úºœ/uY¬"y ÷1âXЪ¯7÷©íî8"þü¯“ÍåéãÒÖ&eDeußñðêþ«ó´ÌÏË›ûW¯în2ñ4s–0-E˜ýã§ŸÚ²Ûá˜XÓ*&Ìåé±®up31¯ý48¼z9ˆ˜?›l%%¸™9D„˜˜²G¬kkÕÝ;2›#¼ý™™Ùc³S÷3³Y|FÀvBöf@æíWxS#l¢°Ïkë’»ˆ¸{×Vææ=™^mãÔ¸ï­Aó|!8)\›»D N)sŸ&ÆF¿8 ÓóÖ‡|„"åG,ŒKbf$ŽJÎYÆØïëiómÒ4Ÿf}<ÁLÆ´òë,q–uÜyg‹33(*v»L@Z%šûS³Ì‘}ØebV­Q•ê¹¶Ó §¨|ÌÄÁÅanfª¦!)½„n9ðÁ¡ê¦>ú'êg•‡÷ÿËDvÕ=÷·tã«"À„@S Up’Üch›oÆàÇÑÝÝ<¥ËR É”GG„›ªºH$å¬ÒSCÌÝÝ á›Übcá~a!„0wíæ‹=dÛxüQiÈŒÈA…bd:"’…a›H‰¸El€›’ŽÏ™â[ØÅ‚DLHLCðŽy„°“:Z 1LȘb³.á…ýõ‡õäç ‹/±lWB¹£8²cØQ$´`¬ÉäÈt“m”–¨uÉ› ”É5ªé¥YD-,C‹8˜…¸°pp¤2dO'ÉêfÒ5©Áî!Ðè«SoF¬ÌH§¾öKo=mê%÷³ ߯H"b\^_¾ºk“MYHº §Ò¶ G…2TÈ%†”®æ+s7ÕH¬`ë.@ r$€ì*;ŒëÓƒ]G IDATþU_Í0 bWè2EàQéôO"õL¯ÞÔyŸÒŠp#vl!p´)|· ·8˜»Ü5$Ð…ª-];epôÛÍÃ9¼¿½Fž",RÆ”2U6NNµª‡ºÌ/€Ž+±`" ðïðE]Ð5}B/³ðëCÆ7S Ë•’ïbݾÅÍÌ@ú"“ ˜»UÌ cW¡Úb5(%IÂJÑ,Ü=‰ ’V3˜!jHÌܵ…S£$” €@èf3¢Nªˆ¾€î*J¿. ýÊ7îêëP8,TCh]5©ä1 fnK­ê>¯Ì dBœ‰sf™öCö1’›õÍ•áZQ{„qïˆøºUF<8ú¶­Ã™r1æÆ±F[¢U¸v‹E ™ª’“!‚rJ¢ŠóyYš¶ðË\…¡’êbÂê6©Vqrèê ZvìÞˆ¼ÕÕÔœ8@â [mªË4-ËZ{"i.%"$¶K{ vÀçG\—ñÓg ¿©2wjÁÌŒHçó™ˆz)3ð?öÃ-/ÓtZ>Æì‡}yüø›§çn¸¹v‡œ›a7Äë»»ûûûóQN-p:/O¼ñæ›òùÕqw|÷ã§??̧Ţ)N)ï‡ý¡Œ¬êzYt][Ã؇››3c{¬¦Vm^#¢wêŒ`&áfÀJ:‡:ùôtvœÔÀ)—²Fmi™x70‰¯óežá+\ÜÄP×ùüì›.Ë2­iŸÇqÜç\j´î‘mí#îîoØÊñÕ±­Ó›×o/¶4>,Lu‰vYç1Žw7÷§ã¹^ÚðjŸß¿¾IÙO—‡u¹x¬ü°q¸íËn7lìºÖTsúÃ'6¹¿©ÿ¡Îÿ·ÉâŸÝ%zÑÁÑ_¬•¸Cd—¹ªŒƒ{ܧBºçÇ® Gþ"ÀÛ–=@¯«¬|{Î0K#m €8º{s·_cv\µ3`±Éö|³2kèF‰a➊ެg#`¨"ÈÑã\‚T­ 9„ÛL2}€Ú"ªÇj±8cqLäHÎE†2Ö%ê³éϘŒC˜_ÚùøêU’”„vš9b‹]ÉÈ#ílÅü8×Uq^b'–‘~QÒap­¶F²|>Ÿñp†ß¡ˆRf¢\-È)4ȨËÎC{²I?~Ƚþ^òb¤»¶—÷…ãsË9•Z+Ô¶@ùU‹kƒðæ5"DDæ|™/æ(ƒ€Äêæ<8î W«æÞBHÌDfWk*ÖMóÑ#¾?»ä¯g­wb[Ÿ–GntBÔVƆ* 86[ª¢{J;‘œØÝk³®Ú³/ÑCÃ=b“Kmq8_E˜˜:Ë.Fæ=çÄÜÕm k‰“o¢¼ Î÷@Ü-ÒØq¥õ^Õre$Á»°à6c_8¾dªÙèv c¢1S6 g@؉IÒ€¦Õ×0õ“ó²61—œ9;xÕ´BªS%2÷ ¦>ï)ŠŽæ,,×üUw·Þ!t ~tÉ]ƒY»ž$¾)|鈘@W62qa)Ì9@aND‹h r%¡ Ù>Ž×%°Ç&a&¤@&)̺µBŸsZý dû×5À›9‘û¿Cæ x!ÒÁ<œÑ7“ÝÔ#júGÖ{ÅõÎd›CQ¯h¹£1»ju‹p‹—Går ë±Zf/0ú”Rç=EmÖɉ×è&Ô¡ž œâOÔ};I›lZ®c!tÿoèÍCF KrµŽm”ÄDáäᑤ_Õ-Ú•¸«ô¼?þ{ÐlwhsD"»Y­j!`‘Ãn·Nó¥?™8P‹ÖŒBÁ`¤,…ú{Ahá0÷Í’Õ¿J¦ë4¤Lûs­…ááá®á„Á jH…8J)ÜvWUí¸ êÝVl"+HÌÎÑ`†FÉ©·åKÌ,RÍ;Xf(Bv¹*Ç>G,á}é6äÜÂØÌ¬‘Spˆä$$c™/ó´Ô®€y K©O”h&_ahdŰZÕV5)Q’K3ÀjÓµº sF޵~ë\'k°¸2'㋉¨‚®[͈ý¥9gVÕµ®Õ”’ %%*—çóS{’W±<=K:ì9ÝŽ‡ßÍ?ÝÞ½’ý~nêY|>Ÿ.ÓÓ_ý‡?ËJÏO§¯ÞÞµE×Ëôë_ýj¹Tùê›o(§ñx¨µ6£ÿëÿüÛ}æ?{óÆê~YæZç»ÛÝáön|“ñ»%Õtæ5wõ}'«3“EÖõÜè>®Ã¶4Þòٺ˙7›Ÿ½Ü>½­í´w¸r_&Ié+kB!XF¢!b *"Äýߣ#zaÌ«Ôé#ôÏ~‘P$aŠP›cyj1;1°@ÊÌö“ùrw¸½{%*TRTfÞÔTŸmòv·#k9=\òn8z—u©ëàûp6ƒ`h¶ÖeÄ×oÞ~ýõ×jõ·ÿôïß·‡Oçw?>J­6±àÝÏT÷woþü¯~}üîõûŸ¦yýÅ_ë/ï¾ûðß~~zäÐMA”3nÔ,¯‰¡aq$’ÄÁ’d¤ý‘ÇóÇéòÞ&¤$%ÁÙÔIbIp¢0wµ]9Š —ËOŸ0LøæcÔ±rb%4*4 f ŒiCœI'…(ç™´E„~vx›É—Э.è¢à> ÿ2c±£™Èû0V„aŒÅj«ÖºÚÆÖu5 „·f €d‘"œ)à`›×'ax„Z¨™P4mÞД¡ô…'íÊNŒígòÎáî,7QO5{‰¢¹–éÉBÔ3( œ¤Ö–:«z*Ö ÙX;/~k7|®\ÑS:ÃB‚wÂèb^M«»2«PàªÀûâ{þë‡MtÏb‹]NÇ‘í¶ðñXÒ.Ù®­9f±5%b¡¡ˆhvNÙÎwTŸœpžV ˆ"RµÈ‹ÒD¨ õÐÞ-’3EpÇš3u~ÏêœÆžÐÚ‡÷nænNdüÀ­;µbcìY— Òïˆøzá:ä>“”Ó顈 oŠpXŒ7MVÿ.½x‚0‡ˆ0gâ‘) ‹±,Öþˆµ±&þ ¯u]™4]GžŸ“‹?ûë®!V I˜˜¦Fި潲ÇVmúÊð ¼û²kŠØz§°ë¯{ïúݷ⻋ÍÈÀf¡¶ª‡;Š”Î±ð gÓ³J:BfƒYm’¹èdEþï¾èé ÖBþ`·ö¥éˆb3#z×Ñ U‰À@¢+_!(42¹F0!K?2HÕ¥B×@fB*tò+Û†ˆlуÅÜš[ô™™:¸d†ˆ›ÖœÈf*µUAPb‘D™DIÍ ^]5®D Gê`?æ’KÏ%ÛnxÞÔ áEXÀÆÎà,Ì"Á¼V]×ÖÔ…S’ìlÛ—\ÜN¡®î. d–ÐSlRáhn‰8A ‘”Rk ]‰Õæ~¹™‚¡B•±-AkPLHB¬laª¾1¯3"°;옌„©¤mÚ”Á)7"a=ŒŽ¨#ä­v¼Á^ḐOO” €ÂBBA¨ÚZmìѾF"@oêªì—T[1ˆ¾°óuI®A=#9çLDæ­©>ŸÏÞê}ª±HÉR2Ëí°;"QCâ<ŽûsmŸžÂèÃãûê§LÆ·wÄ Âÿ𛬗JžjÖŸ~øéíwß^ß„PÙ?žöw7·Ë\˜~øðîøþ8¶çß¾ûaq—_¤×cÞs&áÚé,¦ðè={˜¾ !¢‹„»ó+}áãÁÔ’ý¶$"J ¢Î‹ìQo„­Œö Ppx‰æ.áþwDý„¥ÏNŽm6@ׄ‘èˆÆ«"PM³ 1kÓãêɆ4!šÑêPx!(‹[Š:‹9H“­mæ:£ í7‚rzš‚‡Ý²¬—Z«-þðqÚ‘ÜÝŽ²×ãnÿÝwo¾ÿþw].ΧÓ2ááÃÞ%)>|xw¹¨qìßÜß«ÐS}ÖbßÿÍ/~ýõ¯¼®çÓs[Weš¹ ö£®¦ ¾R[«Ö$‚ΰøøñ},äÍ3("¬Bk¸œ\Ýš×y™çµ”²ÌÚj# š Vs…#ÂyE{Z.—eR¢”’VsáAÊQ#ÍsýðáçfõpÜݽ½vi,LƒJ^§§X€K[£F_uuÓ0p I9È[êåñ”,-ç¥Mu:Ÿ>€Œy‘ us×YI!¸ÂaBLÚ•5mvi ”B˜˜%ËPWµë¼× ˆ` ‚qH»1½~ûæá!Ÿj­ªak-QZÝêÕ¬¸Q†­ˆ†e±Å"Âæ*–¨p(¸æåÉS*ûÝ]Ù?¯¦šãî»ûÅõéiÁ#¦Ç'­íR—e?Ì:í"ß œ)§s$Ýßï„´d„.âPna±byZðá£i5÷Ü8½–íò¹ÿ¡Â¹-S(Â< îÄ%Ö™sN¡jfFœ“S.€³„{øÆ¨¶ yÚ+ÎÁÛ8]5¬[Ö"ØtG‰ƒ{}µÝ·|ÅA³÷WÞ‡¬þò#Â`$J`sòëàšysκltc Zà j(ŽCÂMâƒ}(Ù›» •! »”Ç’‡T'ÇGòÚØr*)Ü(ш]̼ü~ÂgD`ç&3ÆÝáõ- p1åÐPg±p$D®g_~žñû5¥,yê¥L>„{ÐJaD(A™^Õ‰Â`ê ÎÌH)É88KCí{›Ž²é*Ä-|Õ2"aNI²ÕÚŸïØ¾ò¦¡ë˜õ€˜‹ákŒ7„™«¡ª)·ðÕ@H»§Òš±ô˜‘ØjkÚâ3P[ãUÔÈ,Ò—œô%Õ#ú¢ªìݗαŠƒÀF$§-ÿ)<íœÂŽx U›MgG kÆ*aA[ÞH‰L£ÛJÈ_@Òfá†ÏNÌ€šª×pMÒˆ"z}ÚK)ë©JTxv7<˜¹çÀ^ÙÛ!DƒòN±rv Öds²g·É8róµUëN™“+èÓ´è^nîßî_ßÜíooǽÌíôññöö>Épy~N’hy8‘L÷ß¼á”(ñ7¿üþ‡ßü°+Ç?ûöûO>ƒyœNÃXŽÃñqþôË_ýòÏþâ——ÓÓÿö¿¾Ÿj‹Vƒ¸gqóÖyd™…]%iÛ&GlE¸3‚¶àømªÒÙ±ëú”"uNTx×»r¿_ˆû2-|Ó6$âL< P"’#$"éOÜ¡?ÿ7ÏÓ»ê_Î0£—´f2kÔË>4€à« Õz©oân¸9r¤ç‡ùáÓ)»›¥8"eJœÊÑXRJh¦e­¡Ëó²^¦"ƒ+îߎßû]r·u&™–ù½yK¥ÞÜ G¾~óÕ·Éò}ü¿—Ùð|©§éýÃÃ?þøÑôß¾CäWi|›§K[£^̖˸÷–D›æåL'YhšbŸª_¬ò~8]´ùüTa‘ƒ¦ÓŠ¿û¯¿›ëZ†áã»§w?ïÆ»Ì»W÷o+\Oñ»üùCz>Z>>=¾‡÷ÈŒzöåé1çlfKóZAнTØi•N~8îà±Ø²jÙåãk>ÿtš<ã¤È,€ÅWãÝ×÷sž<‡™ÕP‡'°Ð²z»4œs†îP‹´L»†[Ÿ›bC]#IiûÛ>ÕljáVÀá^ÙE¨¾, 7¬\PD¤$fÛ¼õ: ~‘@0õkÚõ먵nÿÕg×Ä ÝnGBB óFQžŸ,œ˜¨¶A=À×VsqIï«ãËÜÕVƒdO ÕF-©n²Ì+GþE‡ÖeWÿØÕäÓýÐN§M¯Þ;®TÂ÷©£äA3´*¨f•É‚E㮃d ô~Á" g]E¸„‰2QvxÓÚT¤äÄ•^ñBe¥«ýªÅ†ˆxaD§@iQZd‰1S΢Ù±™±24ÜTiµuá6¹!Ñ!Ýôé¬ÁBÝjØê1F"°d5n. ©9Z’™»A o]ärm?À`'F°[€Œc[¶ÐÖ×â¬Z}™*"á³"öÅîrUy½ •86Ç™SDô-m´+ ¯7w½£è¾‚qSm&,$I¶0° w‡]cØb£™w Ò¿Ü"¤”„5!z$QoYÌ#o9f]zÝ™0Zó«³#"ÀˆÌ’qSyqõ¼ž­ „#”‹žÕÔój^ðWX¯­Ázë—"ž=ˆK±º!ÈI¨ëºúx׬ƒk‹‰‹þ-;"ü ;¢?ê¼üñþ×KS‡Q##‹pW£™©D@é.{¸[—$v¼roc庈Já$AÔà™‰Â;ƒd 6"ÍÜ*Ši2ð¦ì$ï]>XÍÔYL"¹‡š[!e r àÞ;ÈŽk7ó~ùbËöíj9˜š»7µjBb1ÕZ…sˆYdަ+KFRd I$ˆß ¹6«Š9“;Œ#1yç#23©éKWqM¹¢®bîkðXÖm^KØ1u=¸Zޡ磢S:…¨´º¤![¢•#’H’ ¯¡§asgN³µ®È™ÙE½õÙA¡,†pu7J" Î’;ÅÜÝ&¿îD7qëURkáý°QUBCúËaN$€ ™Ü½µÖõÜ)%&I—¶:øxsûöÍWûRljç~÷ëáÍíéô|,t8Ž·ew{»ÿå·ßþÓ»wyØ‘ìß?œ~ùæfmþó»ŸNÃ;‰áÜÎSLûW‡Ww÷úë¯ÿú¯¾ûåwãýáðêÎÍå¸~œž~~@5®œÌ82ÀÒ‡~D)õh§q³º;ˆ#¢K‚‰®Ç x*$AýZubêÐåÙ½Ëݾ~]¶ƒh2I’G¢ˆ- ïO®šã@îqo@ßKû‹§\±µÌ¸~.j[ˆ@Z[±<.­Ðnh¡aðÐÓ4;ûC©ë¤°Ýq·/ÇñèˆÄÌÕlöh˜Ï+Cvrp«C)o_Íö«Wÿá/¿E­?üÓ?^.¿wûóçÛW°»]|û‹W7iWL~÷·åáÃ’4]Ú?þüßNÿ°`p‰óo?þÃ*Óá»}^üÃ4/§v‚‹žÃoK>¦{|z¬«iÔŠ²3†dNû|!gIOÓi™¬µ¶ãÒ uÆ4Ûïü)€uB0R*|›‡‘@f3•ahOçiž–î8ÐÎÏÌ|:ÛWeØ¥’³ŒCÊÏÍÚiÆüX×}5¢#n1©ê²Ì ¶»)«:f…OPo¯ïÞÜÝžŸýòüøÓ§goÏӓ늶@VÜܤŒ’Z±­5o«D€¢!šÍsÌ"Øï÷yŸÜ=žýGÚÉþ0Føéü\gÇcá,TB–à5-CÊu}/âÃÈ"”—´MuPÆ4”ƒÅ:Ûsk‘ %Ó¸ *ÞšyÍ” xx7µgÜ¿ö´›ä2/Ãn\l¾ùêæ«ÕÙÇØÐt&s±üéò¸,s¤à1Y2Ã^n‡Zž–Xép'!zzÄøüÁO§S§ tÀ€™_iÿ¿;"Þ„ïîj® !Ì ý@V×:GA$åž‘ÞÃåC„E@\ÔlK§ÿÂAôùØÞ*Ÿk;·¼MFCz9Ú™F€ƒäXßް>Àë‰gÛ}în€A$£}(¼¾¥»$#œ_ÜŽÉAaŒ·Hw̦ž•˜M½µV›¯^-¸\)Ó žØŽ ¦fgǨúæ…üä8;ΊQ±/¸ßï_ï±cÏîbjl)#†„³5BeøˆuÀ…/y—? ”’¬®:Œ¾×ß,2YW\_¸Û¢­¾ˆÍpeZÉíŒNëÁïîý,íûð—(! ¸Z!âV+̘…!­µ<0„™œ9¾ô³©Ò$7 'H¦ÏŒf’-£$ ÉÀ¡¡ÝÝL[p!]cð¸Û…Q„€™Ä}tmn 0g§`bŽ Í! )gÕîKшfÚF[Óítµ‹c˾l­õô˜$ÜSn‚ŒEdKNÂL7Õ@3(õ3±Ã@6×|?&èsGôÙÿ~U£pb¾ÞHcð.xÇ4–¡ìs ¡& ‘(‹GX3'U1Kè[>ò0S˜‘‡\&Ľ¨·€™“‚ ¤nÊn°€EÈ:ˆ#¶V{z Gl²Ûk7â´Çúî˯§ä Y@Úeõˆ?Jî5ÞgÛæ7Ž€9CFïKÃ{±µ“_L Õ€d9#±$‰ÜXˆûk•—Qwÿ«&¢¬öæ(Œ/#‹ú¥y¹R "Ûú· ŠÝoöÊŠäW·›Gô`„wNLWØ0Q„BCÚ@T×eûuåêfæÂ[X§;¢š®­5ƒ ±ºvÞ|ÿTõ¥oñ¢d_˜¸þ4k"& b ¥ž).,œ‰„9ÂzGT˜õDÌIÀáa®ÖÜÍàY7Ew_Ô€{EYM[ta&¢‹ÄÜ*¼[‰(%"¨Y«n ÒÀ  ©¡z3oÔš6˜Î_e³ IDAT%‘ð¨€Èfïê½ýæCt"%@˜„Y8ˆ¼{‡ µY?ï:»¥9¨™¢ÕÚ˜æ®!‘DR„›uùSÿH÷üU». ‚_*Û^WR–”8R€%¹P€Àœ–V‹Cˆ»ØœA Jû‰QXC8Pˆ÷YvÎûÈ Î'è Ì"D>™Ýv»)ÏM‘f&fqðáNá<k¿ƒ%˜B›õéêPÊ–«´-¬´F÷ñnžàØV˜ÝWƒž´ÛÎnfá"J/\]uã8lBw‡;ÂÌŒ´ÜÜ=øó!§»W¯]æw?ÿxþáýéý£•ÈeßÔÂ_ßÞ¿½—§qÜݾ~~\Õ¥ìn~zÿé²êîx¸Ôåö«Û(øùég*©-z~ZOo¾ýºìÄiv᪗õÓ»÷ïþé§oðš8P˜('¦`–€ôz‚¢KÓ©³Ú­«Á}îÕËá)1oÏÒ—é ¾4°ÉUªë0 "Ê$YRG&Ë´Ýæñ§NhÅ•™À_ŽU‚^†yŸ5¹®—‹™R`"Z×Õk䜦ǥ™îïJ9îIm ãÝøºõ¼>^î^ßÞß÷ÇÃ?ó¢ó9j€>L áœ}Áz®®1pÉÂ…Säg¦j†ù„åy²ù½­úêøZW?Ÿ¦åRç cŸÇ|ã9‰3A\ÕÖÐ €Ç0µÚVDASaW¬<"Õ׿ÅäL‰jË˰ˆ¥ªºY[½.m~÷> £—AåXn© ÆÓlmÌ»ý^–çsÌA‚’p³¿Õ¹¦DîG³ðfNš[41M§›·÷ä!Äuš_ß¼É7b¯õ|z–ý´û:™éã~Z_EH™"Úý›c9Œibúpy_o÷elCcØïŽu¸ù˜qNíº„,In­—1ŒMWÿo! , æ^0ñ8 ²L®ó2Jœ¨§´õDŠpá~û÷Ý’k!:ËßÝ!@¼Äz¢GÞ´+²§¸öU’Äu®þB‹„ió8³›UD‹ž13L9u1»“™[3]ÃtÜ%" ânð5$‰ä‘Šc¤|ÃyÏ\¸ŸEg_4&Ek[°3úÑf@0ÂrÁØ róËçéİú„Üóú¯Þæo†3Î!îݹäÛÓTœDq¤ƒ«M-¡:jC5¿mÃý®Ügۣ쪅ív)Ýçu˜xÒ€¤ôW‚˜;û61 0³6"âôjÖ£à:y)Ñf‰‘À)å  ëOÀnºÎ’,D]÷å$A@.+8Òñ,Ú Œ²ß©Wêé`#aòŽ© ¤Á0vgwX¸…cKË Qgv11‡yt:6A¦dG‡ ›‡P †%x OÑR8à¬n«Ù⨠/â$ÞPr¼¨Ëea’"(Æ.¬„•¤{‘Ù(’X,bAÌÀÚW0qáÍÿŠž6&Ôç¿aAÔÇçbõèÇ.©Š;DìØraÞII)9YŒâFÖ`ÕÝ’‰sšçÕlqR0’HJÌÌÂ,ÁÙbÆÀàmðÄFæˆ óh@åP ¥P5&ï]0Rßë™;s £ªÔM,=¡™ºdî¥qíò%îUygli†W•÷*Ôzƫ£Ç@Ñ5á3úœR¤G…¡‚hÖ¾— JG¶JÜý@³{϶ôùçn¨bC@ÁüÙbƵ.…a=F‹z.íÕWOx|.\8u»wQŒíÊß½’—º ¿_PÛÔ§ ºš¬^h|±éÜ€+äfѪ­áÄ@Lë²,ë´ôÅvlq±üÙç³%!QPý'úÿeùóeŒöÓù:VX„q8 `8%fRPBd¹÷à”ÍÖ›a’±„„™6÷Õ 0ëo,¼QH#],\º7•AD+lQ€!C)ÃØà>¯NÔÓÉ[˜!”ˆm]§ã˜ÝàŽÆwtWú•…Ù¾a/W0AÐUô쟛x˜yŸ˜£GO©º„EP«¦Õ¬"%;î2'a@ Hê^ݪ‡“9{Ó…œŠ¥ˆ( "{coÿuoÖcI’\iQU3»›»Ç–™UÉb‘lV“ýÒƒy™¿>aÌË,ÝÕͪâ’Y•±øv3]DdÔ®Gd² Dƒ'~ï5S“åœïˆ]Fî0o¹ Ø ¡£«N@4ì6 Dhó6¹;ydÀwÃ8*…F¤æÍ›9`L¾†z-–µ¥¦)F#餂“›³¹º¡6%6ð@RÉÖ\oÔõ7L9çÂËx¢ÿyi 1öëÈ`äìÝËxMZgîÞšÃM]†´2VZ‹65¸Z+C ã8¦1™™YGÿÑáp÷ðñ"%Ü…]Éå¾øøþ£.öj›qËŒM¢‹ÄdÁÿðxØu·yû›_ÿ¿c–MšþëwßûáÝÍ«ßýæ×›Í/Í^í~Á„aš6fÞr&âIFL‡nöôTCóK « [W25êÄ&õ/x9Kãü#õ ™ ÖnÆËNôË;mþ~fö:%ç0`r€°²4©²é'¡(ÿ]å@ÆTá«‹ó É1]‘û—4m}œØ`BÌÂZ€@Œl9ÕÖêh‰Ü\cŒƒÏryüØL7Ó.P(K;l¶»ÛpYæ§ùÙè6D4¹¯Ç1n,Úø¾÷çØ#½ÚO_íwyÑ>-Íß½{õ³w÷ýwÿøqù°!©O‹€öðµ„ü¿ï‰pófóÕë­>㇇ǿþÕÛa;œî—ù$O OØmÆçz¾Ùxm!‚äŒyÆáŽ·a»ûM~>?ž.çRŠ8¢»í¶SnútÑ!Bi: ÈÇùéòž¬m-¦‰éPcÄáéñá|~® „nv¸ÙÐë]8Ÿ§˜– û!ó›,ƒ°´2_rZÎó¬ËrÞl62 ly>=7¥ž¾ÿ@–û÷òúoÞÍôøñ?_Þ¶›åÞZ¨<’üt:=ͧ·ßäß~øí~3¦-2]ÒûÅßîÊ8øüüô 5D¡e®MehnWþãµÇwFoBþ4eû'r w·ÄÌ1z V½À v:_ \eìµAiJ`cІ ˜W·ê概LîݪÝO*ĵ-”Àl­Uˆ…˜Å” ÉMºpΉš+¬™h570KJ$VÛb-C«rD'AQìÄE Ðgmª¹T÷!Hת—åL“ìßì÷w·'ϧãGØŒ‰‘2¶4Ývû •¹´‹‹E}X¨( Y¡•ƒl7) Ûdzec4àløtÁ–§-µO—í&¾úó›‡Ä3ÿU ¿9-'=#­µëA Š˜Ãn™¦ ž¿¿à¨8/°‚Ûx¾û¸ìR»¥ñÍn~ºX«Abáe¸ðÎìù„Å#*´jŠ\Ή{Wêúl& âÈ ªùêˆD"â€4ˆª5mA’™×K®¡¡šñ@DA$µR¬Ía;ZTéfŽ«êŠ‡4¦œkQ¬¹"ÆÈ!P¢Ï§SÎdˆÔj£†âÚO,[»ÔLpámqK„`7éÕ "@55mÌ,[æ(š•kõÖª£!ZŸº&Á$½½¹Ùîâf)ùœ‹±Ðg^œÀÁ¼šjÓ™T Ó$ëm¤@Â3¡%JÌ7ÍäŒímÜÝ~øôé“¶6G& “))Ëì S# «‡¦ :€DX@«7RW‚6f$סàvƒ°ÇePúˆrbÄ»D“I<Å@”s+ä¦E%Æjæmm ‡©‘’ª’eBg–aXX›švÀ_NVû>'íÒîöæx>žŽÎ4Ž›Í°Y–¥œ²,JÆÔe)»q3 ®Í(²š©UuP suî¢ ÕuÚF½/«¹mtm`ì$ÒAHQ8ˆ­¹Ã¡–%pè¼l9/çR<„¾ "€X¥UEu0C ”B д•fpª7Û0)²êbm€"+9ÀÅ݆cˆLÎJUË<Ê¥5k•É"\´%/#h)ª“‘,¬ì"mTUµfSÌÅÊ$1/Eúp©ypdPxv×Ej )8KoÝ»‰·-¥ˆÈ°Ý½B'V€)Ú!3µnBa òK)!¦Ä¢ª R8›ˆÍŠU!¤)9ÁT–ÇrË7úOÏÿùýßçòãÞÇoÃfzs÷îŸ~óýÏù7¿¼Û½Qðû¨Y¿~${hôë§¿}ûÖ–<†w_½züøÃ.ò×wwÿç¯ÿËf|õ³›_üæÿø‡±¦ívÚív¿ûîïÞ½{×jÉKùùíÛKu?_nâ-±Å$õ)KæW>`‘&Óû哯Æ`¦ÀP¨iÓ&ApÍ®óÆ»ªFùÅ0Ú±ù]€×‰®DFÆýìub'1LÂ{ ›¦“ëÖm$JF‹‘±Ëÿú¶á_r$²ÿØ{tõ½Ô”«tXÑrOÞZ Kd 2»l¨[eè UÔq̰ˆˆ[<äæçÓ3ÃÏÇç6ͬ>ŸcܦýðõVGž^vwû0Ò»Ý6¶ü븿Ź\lÅÓí¸=ÙIÛñ¯~õõ×öf®íñý‡OçKs 12MM–s¾Ô÷ Á´aŸðz{÷j{)õRjEÓ`!IcÔa ƒ•ºÙl¸ ×g0˜™B Ã$i`†y5‡¢†! ûÃæà¤5KUÎó=›„ÃÈÁÀ°ˆÛÝÄa¬>ˆûPN(K)‹]*5MŒ)Û4îã0©‚ð ­Œ-r!T;ÍTTÕŽ´†@Õ–å÷—âeF–#ñ`,‡›0&L¡’Y™ç<·œ·FÌÃÕ»Q”¢y­Å5q #Á îª¸0ÁFÕÚŠ/­6j9Üìq“p{Øíö›·oß\J}hO ûàÛƒ>~²ÛÃþ_ýÙëoï.t|¼ÿ´<œ.gÔÇðNÊvwÃ7ùMÛÝfÿûöë!ÅHƒjXl¶“Ïrø:¾z{7_…©5#µD1æ‘.vLcÝîgèÊ妿ý‚¨_½Ö#`"d´AýüŒ ’RŠ‘j¥¥”%Mƒ»¯ê8ï%S‡¹uÙ?½`™zV;U ïú‘ä B4³î"½Ú±±$ÀˆÁl$ B l€¡ÏLpîtƒGæi&.MÙºÚbbå–m2‘ŒeÇhˆCåÁÁŠÆm©ù©µ%¾%DŒTu±R.çù„Ja WP/ðŠMÉãéaúøíÿô­pÚ_f~²½œ¤Ôà#1‹²êŒ¦È¨™ÂÜÚÒl¡ã~óú˜å’—$²âÐJm—… 9Ø}²x:\€¢e:²5ç°h)0Ì&]Ì@ sƒ{·yw6ÅKŒ¸u´ÊjÉèD˜Ö7Ô°jÕAäfên¨ŽF®ÎÄ͈1Æq  <Ƽû$ê¥K"­i úx­C·•‰¹óµI¹'C9;Ð1ëL¨’ˆ‰»«‡á±«–œE'0kë–fG`W6µV´¶Ú¬¢®áú^ÂLÉ™a wMQvœ&ãRµ JSÂrÞ‰¤h;›.Lƒ uZL»æ\àÌìÈ¢PpÄN pê]177 LˆŒÝ€Í¸DµàgÆ%xaTAF»´rV3Ç8ˆÈ’«ˆ¤Q„9™"{ÕR,0ššPi$XƒuÆ´³Á”¸q̰fÈ8†¬`v®j1[©ðzÍâk.G?Œúªîe7c ãè\Ç­U ¤°Ðw#re.[§Y;HK¨Fm@Ô-{³°Stl"$ ô ¾[@À(Z÷œ¸ú1cþb’³ôó‚ëÊ„ÒØÈ̬ZÆrw¬ü @=i°#3Ðë^©¯ª±²ÔÙ×Ü·Þ-Q¿ëºcßÁlWÀ¶»7x5X³ÆÔ` (îR ÷(°ž«¦æª*‚PË%‰­®ëNÌýgPÿ¢"À¯k+ý©`ÅNt+ˆôV°ë— ˆCܽÓ`®Y®ýÕ¼7‚MÍ­oÈá}jTaÚcWAc(P¼ºSe§®‡v˜ÙóéTku'ož/3!óYÝ=@"$%#…¹[Ó²´F+©ÂÂâBάÖ÷›‚±wb*y aõÀºº÷€X×÷#¯AÎNÎN"2 ý1jÇ/ç‰ÌknuµÖȽš5ÓÖ•Á„Ôªn¨÷PÇ4Œ"D"K`ÎpÍZÏ­RÉ#óx$ÙڊвX37kêÖ•`rŒ!:Ƚh¥Þ¹»Á€JO¿›²àš¤[¬¨Ü„ÀlLKëà•ÍïͽjNwÈ‚FÔŸ ÍšëÊ•éó8_=Z}HÒyû®î¡Û ÝÉ{Rˆºk5“zØlѱŸ>|$:}û×?ÿúç§ó·wwwËRRá ±Ÿt!‹¶à÷Û¿ûáøéÖF7üáӴ䯾þºÌ‹+áÃûÇç÷§ƒŽ¿ÿÝþÓwÿ5¢Þc>^–‡|7ï¾ù:< J#!«*¡©¹ºCÍÌÉÝœ¯qˆbú"yåê…­T]'ïÐ/Àº £‘¾PCBKìƒi„%"& ,*ÿÃóˆþeЖ~N[úŒçtÌŸ[Å¥¦›Ý0 ±p9Ï‹JM…J z>?O»1R;¨r1Ï—§ùíiÞEž|ÑÓû¥Š¾y;în÷Uè|ÿ¸äS-gÙOÛqðýts‹îq9¶œOmÌ~>–…'üÏÿË_í·‡åáñùÓóñ)„Ww7n!¶mÕsYŒ !`L!—¥~zxx|~:Ï È¨Ll­hÓŠ¥Í§ ê"1QÉ¡¹Ôzq¶q?nâ&ŽÃ|Ò§Ó%µÀzÁÍÛá&¥¤¤§sÍ…5‡˜T­Íó|šµfu¥/Týñã#Õ%çc1…Ÿ+¡VÃëý@‘â‡8P o°æšK!sî|J…«…ˆF+9›»Ȉi—v»·ã°E)IL0/çÓÓå2çRM˜Óœ‹mÜ]Œ‚YnÚJip®#ÇRÙZõ (‘h¨µKm‹2dÅétÚ¦ñfpb¾·”üîÛÉ£”’Çßš:D†ívOÊZh>{9ãûO–Œ¸A8ÐtI£q&|_„="±x+çÓå)‡ øZ¿4óBä«/”̼Á ì0 œ ôR¾±PZívç~LŠU×Ï~õá~Ýq•"#(©c©V„ÔÄÕ>1Ò0nv!ÝX`J"òrò¦¾0©K ^›gk®(ðâ^ÝÙÙœ¤ê¶¹•Z|)TUí˧ááç¿úó›Wïä«ÃÃx.·^G¯RbtÉÕµRçŒE±Ðœ ™òsxî†R>1BÆÍvÜoÉÝÏVN4EJ`„§»m}¥x¼€š‰‹ ŒPM\Ô?ÞòÙyÙ?_8=Ì^þÂgq—D“C˜ÈUÍÌúôË:b•TM½Y§» ‘™©Õ0Œ!°‚D!!DÂðÖ*À"pëÞ  …èÍ WiçõB£+šéú¹‘·.x„Ò5÷%á¢7{"]f݉(0›YѲ´º´šÙ3‘’ ôu€¾¼dÍ$†1MÒÜuifä…Ѱ(¥4/ùœ—Fnû„kÙ+Ì„@.„$’pH¼¡ï'¨O ½/dz"jpDxJˆ#KZ\3Úb-›[ˆÆ¦ô9­UÕº¥¼&\öeŽ!vŸîüIªÞ¤ÁLú+5¸™9;™Z—J±7o×)0®qÈZšµÒ¶ÿÙzùås\É«§Û©]3ïÜ@&¶fèz¹Rský¿õUjÒ•‡QBX ®ÌW°Ùúÿ(\]››¯YÏÅ@` äFW$Ý:.Y£ÙYÍíÅ,Õ—'×Îi•ÞùË<µÇ›utÄZÄw½ÙʽÃ:Æ„‰µ%¾"w»§¨ƒOŒL×ȹ˜:$"²Òúp‰…½Ù‹3¡÷“ëœ à?¦ Yµ6/ÕM³f¦®åYs­Üµ ¢/~QHálŸÁw褸ÀÚEÒë]ÄÔ· ruÔ¸5‡˜‘ªÃo ‘“ìæh†Òì:§!‡7´i6" ,µÖRÔIS!E/…B"Bêýúo+íôEÐhDD:2ãÿퟳ²ºj=á¹Y´Þý^ýlý:e[£¢˜¹jcN áa êšð@cˆËÞTÕ\{üÖ5÷ʱ@`é ³˜†>’ æìohF ¡6+…E"¥M”-‡QĪ“:vsRbc&" ¢ì‹ñ Ëð¢(¦jhý)Яggr œ…ÌW S`êbÍJ¦êX[ÁàîÖTUáúãõ‚ï±N]ªˆë©A€p$›kÓÞ_u'¨»;“P5o™mó¸\¸¼{7Žû¯0Þ|õ«o‡ýö|>Ï­ ›ídž+Ï`5p"o‰Ü¶,9mÃv·‹SB jÊVÅ…ÁˆÌµêR**’8šÞŒ¤5òö€²˜5‘”Ȳ·B$$lÒ3ܬ©ŽIÒ”ÆÝ 6gõR`Š¥ÏÏÕ…›€š?ŒãFYèd¥X*–Z>>ÞÇOC–zÖ£l1Þ²GŒ'IÛzYòû÷ãa´T[6[€ 1,'ˆ ùà páMÙIÂBÕÕB†WØ#3ŸÆ˜Ñ.>?•ÆUö[FÊ—,iØìó¼ä¹ €´¦«Ç£µjÎtÍÑë À-Œƒ+´¨ÂÐ]ÀC«è]€Ö³ëˆúhÊžÙ ‚æ&Ôe/î  jæìꄤ–Í0ƒœ˜€æP"1#3¬«2Þ¥cmA²>îˆÄT¬ºFç@063C5©ˆ†šÁæ1xp!&foG›ÏsdI1Råd îÔ¸-ê—†¦Fˆ‘RF¢i1/6e³Œ­1žÐ~¿ü?ÿÛßÝßLuHo·ÈÈO—J @L(bÙò☙°D«rü0#SÜn6±‰hjÛÛÝÍvZγ.xp Â*¥ÕâÕ"ö_Ý ƒ½”‡Ñˆz]—Ýf¦ú9É÷…”Ú• ªUD²b¡DÉLUµµfÖBH"ÂKP/Ý7@$) 쬦ڲ€[sËÍ[ã[4EvmÐ@Nº™õq¥ÌW5ÐêÉ`¦þôù2;Ålu+ôâÒL›67R#q€‚ÌCÀb4q§\5×Vܳ£tß³™™«uåºô9'¯Îxò*ÎDl7›]ŒÃýéx*edhˆÜõÊr&¢àp³<€R'í:©š“› ˜{)¹ÞUŽ`ú–&"5²^¨žÝr³Ki 1’¤0D'mnª^=±(¹5õæPélbfçÈŠØsà ­ªBYmê¼wbüˆ"Àü9ŠdÕÑ5Á÷¥U~‰ýyÙ*ü$•ü|€K IDATõÇóRaï_"qfÁÊ4€ìÊÿ ê¯"xeîDÉ^溻…ŽÙwg!&× $ !VZ8«¸§ÝFO.¶ÆXQ &&SHWVŒó²ô+ê:µíµ!:‘–éÊÒ]yRè\a~±÷¾Ü¡q¼äe÷wlݱz®æËtYÌk¬  <ún¤wDkÀ‹LáfWü÷ÎÊðÂ;þ#V¿ä[Øu»µF¨¬Q’L€®Ú/&1Ð2ä¡3 =%¹™ ‹Úšr 0Ì\a’† 43s˜¹A™(“[5¸º¯rae(P]C¢Pu37óaˆDdŠÞw™ÁÉÜzïÕ˜¹™Õ¦•¬ª`ê{Ç~ñ»«º1s ñJr39“{]ÑîŸÍ 0‚9üŠzó5`èü4ë×6µÖÖ–æZ­29ART¯nÍ ªL"Ýr×·sêV›–jD`Yƒ»H›iOc23sP3¸6Ç8l‹‹lY&¢ÔÛÅÚ¢$c·S\Ô2Ї˜‘òâÖ´·¦Þ_‚»kÇJ¬­#©£VkÝCGp¹ê]áh€š “„@@1oªÙòúm_é ­ïÇb¿ ºÏ wƒÃ\­û‡!ììÂ"LQkjZƒcÙᜟ7?ûåŸÿêÝ%[Àùþãéþ‘wÃ&ŽbTO¹]¬Îµ>=çrþCZ8¦ýŸ½Úm†@<ß½X¼™²Ñ974ÚŒ#^O%dɲ¹Ýß}õzáÒîŸNÏçýaBÅwßÿôÛ›Ò…Ã 4gp$o€Q^Cè™uLŸ–¾è…¾ªúšø÷’j÷ãå—K]"Šqd‹ÄbÅ„HHæR0Ç¿½ŽH÷ üzïp¿é¸g”w!aCÉ.ìOí’KŽ “nÉP-KiyÇɨ,µÖ\¬ØH(Úq·¸ç‰©Äq³<Ÿž>”,pÆï¿Û%Œ¯n¦Ý¸»mçK¦‚4Iœ¦E={9ÍøÇ﾿Ôs3íæE!qç|Χ§ºÝcÚN)Š™æ²ä–,ƒ$&ƒã,˜&2S’W¯^Ç8<ÝŸŸfؘU˜%Ñ`º`±r,qàËùñ8?/ÑÆ-7Óôí«oÚ|´zz>?]NËbTânIchT5bØãf¿ds~Zž>>—‹’@ÙÇC`!vWs.•¦°»ÛûÉɲ6…w¾…@¬ù|º´òܪ‰HÜ„%œÒ+ÜÞ¾¦DÏÇ˧ûÅæšç%WoùlíHl!Åqo´Due¿Ù†ÃëÝv— Ïçªd@E1ø¬s=ó »ÛͰ.…L]ôÕí}:=ðñáñù±ÇÒj;¶óoçõ¤o‘˱Vkº4ÃÓóå÷ß÷ãvŸÚŒrÆñ»”Á”9ß—ÓïÏ‡Ãæ6>à1—£Î¢lÆÃ´œçù÷…Ÿ.ìœâ^/KsWe i>žÜÈ\Ìɼ“ĺw[ÿ{%w%µˆ„,¦J$ëù¦aœˆÈ-¶æZšiAdtž)»¹*´g¿y§‰½(o¼Ïß*ˆÜÜs û$ ÌbV ‘º×…ý‰¦b$8»[GzpÑ•¥Ö·Óg"ˆ¸¨²ƒôúL„7 Ò˜¶q:L1I)Kž[¶FFåiÆ9ÃjGÚšçSÓÙöÛ]&+=>¼¹j34•³Ks'£§¤O µ.íýï›ï.uøÅ.ü|HÛÁ‚§$q)(l9ÚÜêÙ1æš ã¾-C¡qà CØÑP?±!æ|¢°a7”¥Ôêêz{¸Ã>âÑ}‘¯ûR#J]¨°ŽšÖ 0Г‰øGë ¬K†ÞÓ^l#v´Ú[­×ÖZ9xës0‘0¤0‘3™¶šKiÌ„¦ 5òFµµiˆ8¹¢sÓºÞXBÐà)F’ D/2ÊNS¸j^^ÉjW]‘âfª Ö³^‹Kt…Á=6,£ÄÄì¥kÖý§ ¹©·žJîlwr£ ±ª_lÁ..Õ ¥lcÜ[w?-óÈ„Å4ÃŒŽè¼æuÖQT‚ÄN ÒRïd,,ä UqÇ@!HdcBY™‹cŽx®^Xáb ‰Å]œ¨˜Š™sˆÂ"‰x#3Ô$—À¬+áô ™‡­ù‚×4[§5ôç:×ìŽûÂ^Ò¹ìü§ýûöø§~MÓ霌ÎGÁ 1ú˲½S|¦ ¼Oý;³ÚšÆÈA$¹DxBp6r‚t\5È)°(C^*¶^bš‚{è×¢YûKlºJ®0•kHiÿž²V@œb‹÷Hjȹç‚]÷`º®&Võêèj+,dí@¾JÔTWr†@ªÖf5Ftú\kV1ò:ÑèY&]³ÒYþØçòòª®SíþšzšjǾð÷ؘÙÁ°Žd"¬;dHD±0¡ik C0kpåòÓ•´nÀ]ëBZ7mÂ<„Xµ¸3¬³•áÞ£ŸÌ™™Ct¨:ÀÜݵoDÁ¼܉Ö%Š×ZJq'pðµûºŠxÖÔpw× qwknW4{ 'sÅgF®rg¸t¯¯GÍú–à µÖZ«Â0‚¸UÓ|Y®V ©D1H$›[«}êÁ– n= öú£‡Kô•¨¹U¯Ô㈉xíMÌÝÉt"—w!îX¤6ªµ¹Ë*sf:“=¸Ugƒ‘mak¿4ùxÉÍ¢5gÌzhH¬6¢uwd¶ª$ÍŒ˜Å̽'ù˜œÅÝ«›“}Ùo÷æ|àІ,ÌLašB¬%‹¯]îužEyêpu ŒÉƒ$OQc hÃ^jÒ'ϾäöþçvøÙAZ !™Ñ\­¹Ëà­†W»ÃŸ½«æ8øóœNû»] ›ÏGVòJF¶=LË18=LÛ1§0þòßým¾¿ðÇy|¶ö±üû÷ßÿ§¿‹Ä±+¨A›Í¤´0µ® ë;â—”¿á]'P]Ç×x6¦Þ$þ8Ÿ`ýTŒÌú2V®ÔÛvÖ'vûÿÇŽ`"ëdaë·UÉ®§ùÙÒ®ÓäY8»èåØJÓ–°4Ûr\æóâNú\N?<Ölá°×¥’àøø”ýò±<¶Š7oaÉÖs%û ÅvÃÍÛW›Oß?ÍøõßvŸNӖ楢æ û¦Ôåæf<ì7»Í¨µÍç£åµeºœÁ‚Í€#)ÅÁ%0uZ? ‘q»I’N²˜™«›{ugojŽe.úñÓ.Fx¼Ÿ—gŒTb婞ª]æåôt¹Ì¨¼A7qÚ9òpss;ÐDZnIJ[¿WI¨­O1¯@œÀS2Dg¡äƒ„>~ÌÝØ÷yt)ŒËöëý»Ÿß3¿ç¥Ø¹ -õò4/§#Ù²½‰ãn¦8פX=D7i.F©„ÑPP/p )r©#Éf³ÙßÅŸÕmónó³¯_mÒtÿ‡ÉWËÓ|†,H槺8††[%€ê–7ÚåœýýŸÀ¾»Þ ^°9lt3<ê¥Íµ|÷_¾'è2ççLJãin Q\Äbyžïõù‡ü~3Ž7û¶öô!›—§<µó²´Ò.g˹´mn+µ#æÿõªÑõ!bŒ ’bN®ŒÎý±ÎèG  w'e&xO1w‚tæ)Þt .*6voÖ‚bÜ!´†^[_‹â¥ªpo­™L_P.}®Õ§7ìè|Kvî{ IIµgúޤHؾº‰Ë(VÛrn—ù‚¼ 8Ž #¤dà%Ô¥èsÁEçV`(!DxEÙ«u6í|Tï#;e,‚æ€ß,§óÇÓûÓöÃ>ÜŸ±iKùñLÚP”ÃYql8æ j¬1X,ˆLÉ>è§åj”"§6K$Ì(²^ªb L¤¥™!8÷\ÂeÎ&´†¨R‡’÷þ§]çÁŒkìÜûÄäÌ!˜R¬µ;ɵ³~™¹KSà}¾-ÌB`ræÐ–¢"„ÜH !õÖÌÝ…(²H›„GYæjDŸ“ÖŠÏy™Å1s÷¬Ð(·Ú8‰YŠ;™²AŒ"‡9&Š*ÖŠY%R†²«˜¬UrvwbòkV¦9¸´zn¦"8&vQ¿I›†ã²s®„°»»±SóΓ…± A‘‰Ü‹¶>04¦ž²Ê=¹R} ÄÙ8Ѱh?”·‰ªˆ‚m¤8@M³¢-M¬1$¸t™3 ý¹ëîµÖf b`g1‰à(žÄ%p¶¬«Æº‘Ì?/vèŠÒæâðª¯ëqå? "ú#>CÐ;¢Ÿ$¢º‘ƒ¡ê=n'^áÑ|õÕ¼H7 }ENˆ,(€k©L€PÁ4™„åTYÜÜ@í ‚ÀšjõÂ…Ùw¹«Û ¤»«"È=I$Ó—Ú+qî§y>vÍ-´«¤®—G×UÙš¾ÔÝxùÃýô5®µ«åz{onª®Þ[¾ß6THj­ë ŠY$²TvëÉ'k) Zññ nÜFÔ¯ŸÜM ¿Rv?Ÿž´&Q zìlÌÒjü@°.;Å¡K¬²50Ø =pÁJ(ÞQ«„È2 Š BÊè)iúüjý,„;€›¥”ÞÉxSéý*õé…AÔLÞéà@kë÷ÖëÒU< ©U}M•3³@Xú›ã®kgÿd½ó:zœIÕz?ÄÌÚšªæÚów­_áffh`Š"‘(ºGG\™+Ós€$–æÚ]6Wøgà5[Ë™Œiå¦ök”ˆDØ­Ìq%lBˆ¨u_¨˜A™2èèxvÜ»ŸÈœ}£-Á€°fÝp³vw]1klØC¯Î¿álèyO.° æÁIE"‰ÒçFÈûÆ’ Œfýèc¿2EDÍNŽk¤»SoÇ[m}À×Ö"ÀýùùÍ›éÕn×–¬â‰RËØÉæfszÌ•Ù@O¹ÛÈ‚ÍeQä§¢¹eº´vÊ9·ï~øxó‹ŸŸçåùáøéòi|8žÏóžÓ_ýꯟNOüÍÛÛû‡çãï>ÝèÔž FJ-åhÝÅÜÔ«šâF$N=„×à=u¾ß<}Ad×Éý±Œã.HvíeY—®w^ó^Ý k{¼ È×õá¿A‘Þv}é)êÅx§É;à•´ùÀ¡q‹.ÔB9Ù…‹G[ŽMgZ¤%!¶¬º´Óí~s'ånk»D2&kÅŸ϶€oðõ[üÍüõ<Ÿ<„ôÜZ<ïm—4í†Ûi#ö6•‡KÍO3Š{qœ,ç<„'…ßÞîw›!²´%·R]=A6»8îöqHµÖ6W6$.T½Å”žmi(÷Yðfw€_\Ý̪g§6¦››½5eë:{÷VU«ZMÐÓõ|¹Ô ?JH1ÄØ5ħÓY«yAÍMÝb”X¿þ‹wïþr÷êõöáááTߣ<ã ‡r.NˆS ˆá`¥^òñÓñQ%ð8ÞRÜù‚'χ´Ùï¦ in.ûo‡_N‡á;;ùóS=ùG ŒVáhF?‚ûo亖¦fE©H2ŽŒdiÂþ0µ–ó9/K®ÙrC&Ðà"y°JmvTB{¼@¢úÚÂ’$„Ìçâð.ð#1Jp‡Žx(¨ 8âw8ÿæ;BjÇ]F9Çæ¸x99ž —SH÷m+FÖmðdÀ¢wqº‰ÎªsÖÄV,ò@*ŠmÀ¸¨»'rRm}NgÞÂô’Jôeatu¬ê¦~m„B`²@1†Ö3W#‰P_%õauç[iób F®]‡Å"AXš)YPç®— àÍ1 sä(죵²N“¿ˆú%rïUˆY‡l“‘ðC«2ŠD$°¸HË=ÆÈq¢˜Kx¬jY5 TB%­+¶˜œ„WBz”D¯oæì­{txK¼«—ËÙÑøÀÍÌäËIÔÝ‘"n¡Z‰Š‘u‡±ƒi Êu#GdIŒ-c ¶Ù¤´u¢ÚE('o,:QÜ­ÍÕ²õtkn†šû]™·ÈÍÝ«Õf6¤Ž`nL ¨{ë{U¨“ƒ íSÒµ‚ HÛx‡;ìîͬ¹¼õ(Â?nöÙGÔ)Ô×ôen¸ôY™ä ëô”©ëùºÊ’+Ú¹ÝÁÒª© sˆ¢äˆÞ‘&Ê×ÎõŸÛ:é+'f˜›ô/IׄqÄÜÝ•¿Ö?Šç¸‚«Åð9ÇÕx›îM’Ð5#èºz`¼û‘ ݦNXSÝu®¢´nQ2g’È& îýcæ”X½'æ˜^mNÄÄ ˜ÿÑüGºUû×Å‘n¸¦ûµ bé1®ÏŠnÖC kp™»ñ:ÀÅIЍ–j+©Ï3„þ¦5˜Bµ’¥À‚Šœ]½©z’î>2÷¦ öájo¸µÖKI0[³+&ÎÕÔ™‚È‹-è*S¼†>]¯5 {q”uO+‘¯YtdNÖ]á]ïEF¯­z×|Š\¬t‚ºŒ¯© P6cÚ )-³¨¢˜–œNçî^†»Û[x±š;ž_nïoo^’ºiZ¦óºÔöÛ¦Õk£f·qxúáðÝû#½ìä&}÷Ço~ø/ßþòùÛü0ާäþÅ]ؤ²Ls©OχMîÊÃÓë—/þð‡ou”_ÿìïSæ_¾þòÛì_ýí^Ò?ÿÿçÓÓ“8½ýáÝsy ,oßôítøý{éô'_½||üÁ²×jR³Š+¹ºy€'P±UüjѶHüdôóIZI3™]fCî×Ckÿí‚$²Ž(Xp0I°\ ®øë;¢«ïß½#¢ëä‚Öµ.1Ä7\„îÅ'¸—¥(c)Új¤`»[‘–y±¼ô»áî¶ûå«ÝPòwË<ûÒß"lãi.?ýå5IíèûwKpJ»ýÍÝi< \ó<ι8$d3T¼ÜÞÜì_t7›¯^Ü??—7Ï‹‡[X1¦9pYœ—©ÔZm«ÓëŸ|¶»½UçZ-¥~¢ùùùA ývÓŞ™`Ì8-î^—*„Б$…hÜñíÝ¿¼ÝÝwÅJzÑýö7ß,3^¿¸Ú?¿==ÿ4>ø>RQ55‡ãyòRÄcp…"ˆtûÔu÷øéÏ>÷ðÃûLJìóþ¾ÿåW?ï6ñùýñüíòægÄQÔ—RE°»Ù†»0–å<§Ð¥JYê”§·ãíW?[ª-÷/ÂùCÞaèãàÝîÕ0/Ï9g]ªz°Mϧ鱿¸Ã—?ýêÅË·ß=.óóí´Â†MrŽ§Ç‡§iÌ·ø°yÀ(§‡ùéñLHÝ݈Y ÕN!ò¶ßm6‡”z‘¦E?»O^\k5Ñq<ÏÌxýj¿Ôót2u¼¸ß+ã‹/¿úý¿ünQ÷\ºí.ÀÏó‹}ÿÙO_ö‰žŸß”Z¶7èûÍû£ñ1‡®Î#b’ ýé0 ÖŠÏþ»ï£v=ÿùG)ÅÌ(“™)vZ)ŸÆ, ¯L-X<¥Ôm7[âx>ÎË\ÔmÓ¥®¦9Z‰üMa^ UmÏw†sàA5»USvWS2'We pB˜ÚB$LTç3’H×1sãå6½®¢¥pãBì›V¯È'HEÏÃýîþÕ>u4NOOÏÇóÃL“¢”E¢ML›éÌÃn3lD5ŸÇçšGg+Vl®¤¥µÂ!!¤hõДA¥F§Éó"ÑSdgZ~x„؆ôbÈu ÷7]7ð,óãRž³F †öÐ(K]f¸¢$ä¡âEWGÜG¦ž%zŸ±ÝÜô¥ÃmŸOÓé¡Z·è4ž«pì9ˆ´zêBJ)×eG7HŒ!FfV¥R Ô š'31çìªÊ$]kÍ¥,³çynlY'!"‘ ¦(`–èË9¦m;!$/¥ÌjF7ôu^lÉ@Í”bžß¾‹lD™w¥&®3oR6U\ɬb7¶•LsÍ¥”Zr&¢÷¢„RG i^–¥7‹Re ‰`7Ìb‰÷Êå ìfd`&µ`Þ›÷ð„p:ŽJ,‘Fèhá’KÇ!q삸šæRÝØ!6›Ä53s:AµœÏªZÝÈœÜD<‰l" }ØÝïfžÏpÛ Ý0.)‘xB¨ÕhqnVƒVs2¤ÛôÖù8ÎfDHëÂŽÄ!:a©È"Æn6OŠk5+¦‚&BÔµRnV<_¥•¨µwuS˜6nßÔZ IDATñÊVn9äm9‹ ªA›‹ìãH¢j f–æ&7T¯ ÄÐöQÖ€yB[ŽF޼jιfÀw»®/ºW¼LÝí0,Âç:í”·æcÉÈ`âÅÈ+›ñ23IYfa^Æ À<Ï“µ¤ÐuâDóÐÀÓ|éÀmuRÑØ†Í•n7±]üwŒ5ïÔ«´Ó¼õH×ò±AœWè¡aâV–À:®X­*pÓÔ÷M‡l¶:ÜÌÕ T•™º.¹{553od÷ÕyðÑuÕê4w;3…°êÄÌlYr“´ÉH ¯&¦2ÜbUB r¨:ùá¸Äˆ„‰Í¬:SŒ1zE”J^T³Y1B5°¨íP˜QDZD-”ZgW#AÝBŠÓyJI­Ó@ÔwÒÅX笋VUrïS’n•AªWKɧ”–¹LsVÅú†±«Kµ5™ÈE¯v8ò¦ò#wHµV8D8¥ "ªšµ´h3¯­!dbâZ+4¯T7c¢.¯ÚIÀyÚm6yèûéølÐÔ§Ó4¦Ô]œÉ¡î4y‚yŒÒõ›­”q^ª™…àæÒ§ÈRkÕZÌ!p5Ux•–I`Q(¤(©Ùb:V-Pĺ´  §‘£krtŽÒ)¸CIÂe½‘É ÍÄb$$Ìn5kí½·¨<-!ØZ.3DÍj©Ê.Sß­ó<»#¤¸,EbÉ4-«+,r)%Æè¦jpŽIRˆ<åy³Ý–<[àÂ:æó ±#~z÷öý¿ü—¯±¯?»_žÇ$»ßÿæeùÃ˯¾¼}ù¢¿ß¡Ì]ïÞ½Ûn»Ýv{^Îþ¯oåP~ñ«ÿp>Œ§7Óao7Ÿß¼Øn÷~^6…?¼?½ ß“ÈÛwßÚ´Œo/yû«ÛŸê‡åŸÿ÷ÿüÕ«Ÿ0Gr®Åç9ݤ”œÎ¥L¦Šv@Àk¸ˆ"@µé&.Hªâª—kƒ¡OÁÜí_­kDQ$zc¬4»!{û#ÂÎdþ×;¢v{ÿû¨ÿ˜byy„i³E@Ý[|=š4 @x½àÀxœ˜½ŒsŠÜ †>î6KÉö´éq÷y¢ŠãsÜÄ]Ê1±„RëR9ôCöçÇ÷‡çé<ßý.C‘"úAMÈÌõp˜¿­ÿôù¯·û-Å›©Änû]5Ô‚šóý-ŠkžÔ+ö{ ©}×÷ý8ŽÎ¢fó<ÏãX«ÖÕ£‡öètbÔÕ*Ulzë¶]Úöý¼úéÍO~ùjw—œsÅ‹·f¸Ûo—“w;înÒñ¸dÇŽƒ°åJ:Í^ߎ‡ñå~O•…c×u!Ž£¼yøáp~(aI[ÙÿdûóÛí¾ßÜlÞMϧççã6›H̪ê,}ßG‰¬Äæ‰"Q+¢üû¯í‹¿;l67LèRÕiy¢§ÔK°¹Ï5CDSÇýnÓ 4mn¨B¿7÷7ŸÍáøôž±C0ó(;tÁákøóéi˜–£žžáÁÆ•Ý6u]$®¹Œç2Û´H„™å9s½ à9Ô\~ÿæ÷hÊS…† õ}O4eõ<ÙöÅÝÐïÀqžKd‰ÛĪ÷ÃM J=v÷ƒlöËr¼»v7wñž¿Ö‡š %OpX ¢µþ©øí_½þ|ü)êzûUw²ÎÝ ª ¯‹.Ä6ô» Zk®^m)V ’ÀfÕ×ÐöF·<\‘޹š&aJNB.†FÙœkó‡jSå®‰Úø×m³¹šU˜à&·ÛaˆKŸNÇñðŒiDBÐ,r É#y"V°ŒæPW- ì—ÁéÕ¥ @^À€%K†¸R È+b(®#° Z9ûÑÊ8‡E”PT@Ôò™`ISDȨ(é|µT‰ƒmÜ¥Ì4yõ0ݶË÷©R)xO3,Ñ:Â1w¯VÜL/®aÅÖ!+CäS¡»®©3vM(ZÉP…Ø$Å¢3…º‘auh»ƒˆ¹ÍDz‘Ô²Z&K˜”J}ë PcAäµ…3«ÍG²fXUQ kóWs7øõ5#@bZ³Ò1ÄÈâîNœM Q2*Ü>5ôÛÅ7ODÁˆÁ¥±øZê¤+6ì{æDrfYÜGø ,‘$fª`q#sûkZ ',+Ê íh“_vDcS¤‰$ØdãhóÉé>’ŒBYPZß}ñ^×Z}ñšµUUóL$)23u¸æè†¨.ê\%v”F¾8¯äG¾ÞÕBO`qÓÆ´O\T^ëQs§†]³‹k¨m¨埀¶ÿuFëǘ¸{ukÐfU`ÑPØ âFb–Z¦Ž7A‚ÖR4zÙÀ7äƒ[vw'U%7ªë¾ƒ.>Ÿ 2”œ…\ˆ‹Õ|E"ÓÇcráȬoùÖõ]ÇÛëßµê$YaäëNéº#jm’¶]ÐÅTÔØÜŠ‹¡h…m^`TNlÞ +-fÖð`Ô&­œ‡€„‰¸š­Ãþj µG?~Všqÿ#cûfüç® âîkt)A½6œÝš'·&M^‘^Ð8Ë~iÜÐì "CÀ1(F"iX ’„`â¬&ì$²2Œ/^À«ª»–ZÌW„ ;ÌW„E‹|"2€ÖÈc‰.l¶–dÔ¤níNüëÐøëölåίèys°&‹«+>K¤Š $ÄÌ^ „-«]uµÉ°™®)¥0VU7rVoÁA^ª9™3¶zY”…–Z½VWSj|'…jkÈYLÈŒÕt½1Í@`FâØÇ`]ä:"ÍYÌ“‡ÁeëÝÙ¨º:³]TsÍ—%ƒ¢«r²ñmQ›B\'_ö‘ÄÎÄnl`iÍö´Ç•¿·fqQÃ!®hÆö×Ñ5ïáp>IðnHKž?ÌOÉ¢p±ý¦ßl†âËò˜ËAkáÓ¹ô<éöÅ&‚cžÊ¾î÷Ã.l;D«8>åÇ'Ëùù´¼{ú§ÿíÕí…ŸÞ0y*,nºÝOòÕ·_ÿዟÜýâþ§qô9Ìõ›§÷ý&múíŽM#Îçqœòœ‹î6ƒ–Z²£˜iÃRX%arŠ,ÊÌÎÍg踀#.MÑâéŸÔ]î×%¤­òpk:¯hùä`%vÐÿˆ;"§–0r»æ· qƒ \ØLM?Á°8¯#S¯€ãnÿ’EÍs­'u—zþðø¸Ó,wCÜö’M·ýrâ·‡ìüœ—žvŸÓãaùîṊï_÷çÃ]êS?ó\çó4~øãs·ÿýçŸÎã¹8a»Ûm£[½½a+ã\ËxB.H4™§³‰¸7*¥¸j ÙUU«­9—G-S{.ðfÓ÷··ÞoC¿‹aƒÅ\KçÍÐ÷}—§SºI{Ý}x\JõÔqßm–k­çç|B^N–³;R )%"'!g/´ŒÙhƒÛ‹›ØÝtÃmO^¾Ž§7ÓÓá{Ò€ µVwßn·Q"Ë”sÎVL—êÙF ÇðbÿúöV_z9þæøÝÔ×.xºÁuœçœÙ±ï7Ÿ¿¼ÿòï^t[_æ§e>dµwù|.¹,CWˆ}O`ñ4M'ÌÀå so€„Yk…’‡@ Ýì»ÛWûí¾¯>?<—|ʹøË/¨Ô¼jÃi™æçÓóûÇ|ó:ôû`†›!¥À'+ã<ŸóëÏv}Üý¶äCؤMß´ï©,§°Çð"¦º« îï6/^|Ÿø·_ÿ°ÙS;?Àµfk×Ü'w¼q†ì¯ÝGîùí‹j½B©­Þq–¡Ž¤ýÍb”ÈË2ƒƒt™ºgƒe¥¼_×Êä¶Î—늑5Ã.˜5c˜³1ÌÈän XˆØÍ\+LW~¨iã:Q½KtÇ›ûa¿ß¹ÕÃãazzÄ8A› 8 Šx ®úá;5ÒœÊp´–#-ÊÎàÎ3La*ܵ74œY«dn®ä¦® LJR=”¢ž±sâS®gÅ"bì.¥TfgˆSbF'.AU',¼(öŒ@êÕC°BQ"o:ì±TÍç%Ï Œ±*PPšS‡ Díå×Ü¢„ˆJ]pE©®ñkmÔÔ8|‰ÿ1S\§ ,h7-šíçâºFS|Ø[Rk¸ÔjFnD&dMuA¼$ˆ#S`aZ©`Ÿôç«1½¥©k+ÏhMGY;u*b‹ê…¸«j1s™ …áÅ¡0(q˦g‘µà*w‹C’`Ä,¸%Õ á.ÄWý–€bz¶2:Ί¬ÖF}T•T­ÉàÈ”œˆkëd˜…fʫ̯åF¢D‘ºŽúMìï79‘§ª½ÍRÏÀ¹Z†u!µe'1¬¤ÊlìZÔŠR¢ØõέN„£‡P=Vçb”ÅQZ°$Ì]/ëâf½`ç@AÜ››èǯÙvŸ·…ÏÊÜ^“tþ YáO+«õBL| ðQ¸^ wUoÌ4uR#ƒ8qÇlc‘6)tª¼,l¥cßviç™+9Üj%feiM‰7Iš€¸ ‚nň!"ì­-U´E–5Èݪ!ôuZã¾RÝÚcþ‘ pé f2mK3jæØºÐHWÏ€·Ðá•ȽjÐú¤Õ]Ä®¥¨y“߬ÁjDÂ-“€Fì,k_CÀGéÛºñ Ie…=8yÔ¶4]œõ¼rÂ[×¾ÌäìÕWŽ5Éú X1emÇ…¶çl‡­x[†Ž!xU«jÞ(ˆT‹U 'q 9t!›5´w4ªkRŽjçvnL8Zî‘“UWãUIk†RWuÃ…²•¿‰¦¾&§ý sË^e´Îžú`^K)nµÍ¼q” T™EDœ`ê0c¢ÐîuèjzT‘ Í®µ.¥G'¡¸AŒƒ‰)Z È®êf`‚·…€ÕJ€°ÄZ­ ¢ÄJl'®^ݼ–B ïˆS/•È‘¶F7$;„-±°›i!Ëf$Fî ´TãभC&¬5ìEÀ¼rV4\•*QU!ƒMaëÅy%I¯\ˆ‹0× ‡ ¶aW+¼e†«¤8Ùr¶S|ѧ!BÙßÝ ?ûéön8|xœ¿y›BO»A8†Rö1~ñú³‹ç‡?þp·Ý|õúËm·ÉušGyÖéi‚ÂÌÎÇÓoþù¿~öw¿ÂnS—:¤þf¸IÝÍ篾Ìûðû§Cܽ¸ùòWoóíóù†øöÛ7ÿñ?üïo8&}x>~ó]~3BWc/¡/Fܲ~Ià$Õ™Y€Öñ6£è cý$wh½´þÒ ºY‰Ú]é—|am¹u!’0Ñ_§oÿ›ó§ÿ/>š Ä©q·ýÅÐÂmÑô Ò ·uRãõQ…áðtº}1t1AY‚îo†×¯î·2¦ô€P67··ÛWó‚(;Ló8Nß|÷t6<ÎßöÇ·ã‡Ñê‹/_|öÙOnûÉf^r6ÇÐÙFͧ鷿ùîÃû£UÏ‹æ ?ÿ›W›îNmúÅß½î::=¾ûÝŸxͧ§cû1M&®Ñc"î¹Ûôᦫ¢¥‰œúDœ¢/^ßÜßt?øó|ô¥Z®K„Æn?–™³ößß­žB PY‰T½èˆäÞT¯õxxî‡MŒ!¥ ýF–e:'Ü*`mº:ŒÛ*¢ ÖäB@®…™œÄáŠJ°Šb¥p”ë+°±ÔÜÍÙڔƠȶ)î’vîjãá¸Lóò|ÀX`¡Ã\P JÍsã °Q˜Á¶+§K/°Ûõþq«èCº$`òcª€·–3*£´œÅ Qµ¥¸«–Íâên0br‚U¯n†œÏ uDÜ:$} •’-gLŠpƒf…w‡›ªr Â:œÓ¦NñkõK—­7j:]5'Íÿ°š1ÖKÆ¥‚ âDÈTk³%„ -˜¯™¶Tr…9LÕQ­š+uýº¥”š¸F$Á|eUñ:é'&’k™Ú®‘6¶7EBb ¶.ŬT›Ì Q&,Íæ&wi…£¹‘Un>mn¹îì&aQ!64·îâp\ò\ê¬: 2±¨€Ea(£ÂmõŠø-R­èØÙÍCHܱv¬=ûÐÑf77Â[A ^;äX Y&SC)%h€1·ãÁâlâUe00—*¥¦( ±T®EªK5d‡"@'ÅÑÚ#¦–óEmñC ñØ€n—´ (ÜV‚ÒŒÞìVŒõíìøµ0ò¿ì×õÑÇO25¾¯MZ£)8D8 ì. Q… …4A­yrëÔÅÔá7A,ð˜©ÁÔ«ë æðà€4³2H­õ£ØWëš«›AÕˆÙɉÀXcV*\kkÚ±¡®Jû1vÁ/ÅAm]ßå¡‚ºÙºTZ‹—0žuAÔ¢9hŽÖ&v­AYîädNíß jfk‘DL>2Ìý7Ãõ×ÝbWC ¾¬zØ?ýAZN²–,Úè4»8@¯xkrmSQTí“¿‡AÒ.y‚ª@%ˆÖ’š+OUU, Us5+VÙB7G‹án¡Oæ ç(êV›$Z›±ŠüòU«¼k_z9×Åð%û+§.³¹„ú+#±µèŒÀÂÌ0´d­jæUÍ”™‰eíÕ¨  ÆZ¦LHàŽ„œ…$¦J¦ðbµ˜–j…ÁµrŒWóICâ[#³©£¨UnÚi6°'Rw7£e‘" »Mq§Øoœ6bX &ÉZ$p=ïNbpfrÅG¥%‘ÛuSÚº»´Çhˆ‹]›'bP³¬-ëÕ’2³  ……†ÃqÀ]K5òŠ"‘<ØÛãcw“þþŸþ‘¾þþÛݯ¾Ø|ñzØl4Ôòáa;té~çEÝRâ—CÿÝ»§Óoß¿ûòÿá‹—_ òûÇqúþ¤ót3.¥ÌU³ë7_½}yOnÓ4Sˆ±Ûndû²¿bïd[gx:¾z~:<í†M|µ}õ?‹Nó4OyD1ñ]LI„f‹uµ³V8Hœ™ƒ“‘®\I¸»¬F!òKpاQãŸF\Â2ñRð°[c|@½­aHõ_éˆjÕÿ?:"kE$­KcÿHšC½"h|%¯‚a5S¶a™4™€‰åœ…ö]ôñ¬ª ¶Û»Íg7»ÃwoÞ}(OϼٕßýîmYÞ?¿ÏO>eXÀÃ÷Óün7?¥/^}ñ“/õôái<==—’‡Ý¶ïû(}¦ýv_Æòøa& ûa›$<Ë7o¾~õù¾ëÓí«/µ”çÃæ§”`ÎPW¸«k®P¯j´ è·Ý:Ê\p.¦Y‹çsY–:ê2ÍKÍ£ÇrzÀù-0æe|Çñ-WwDŽV-ÕKöea-T±ÿ|³Ùô}Ló4ŸŽYs ¡ë»a;èüþ8ayÄa˜º§¸IóãL?ÈáÃAgTÂ1ç¬pAßëù|fÐñxœ&$B`Aˆ`ÇòXÎïÎ=SÇ)ˆù8¡$ÊóyY–¦ Ñ%ÏÇï¾ÿæ%öe©ÏOÓwßÞ`>!·»ÐuQéºØwýf´<Ô®vgdئ]JÉ\îjÅÀ}å œ¬z9O§ÃaœfDB) LjÉó8ò‚Vyz¿GÜÇÛÏw/>{9ÏóÛÃÛãR;‚O~|ûPç%lÁNãyTêÉœ^ÞmÂ&=ÇñááfˆÓ°Éåñû·ÇÓtÞww,1 ±.ZÇuüþ1fýÂ\­•ÿ’˜€ÿ Nª„Vj3Z&*°\Vþª8‘›8Du™ UçÑuC׉т €VÎ*šS…2!¤h`´ö8¦Š²XçÌÑÝ V³uBØ6bª­Òñåq!˜ÁæˆL8"/9ŸÓŒ\¡tp¡J Q/€)d½ŠÄ”ržá]«óª),s1FUw9óöáîjuRr0!c´Š¦Ì‚¯^Q&:¾OîÑhYóÑîA«k”‰¦.$¦P%,”6b¯0 LÀ"£³‘°ÄØÝtnž{ÇPðN¨ˆ7k#àfî,"× Ñ+ûO6ûD¾®÷¹U±ëМ¨™Ñ¤¡Áüâ<‘ÐÞ­Õ!"Ndn¶Î–[Ó¢d’X:R^;¬–¸`%2ˆÌµ*QÅ¥Gk‘ˆkr¥x` ‚ë¥RD#R¶Á¶m»ØÅ$1TCq,®UÈœ‹[”È\È(4ϸ“qmЦ5Ó@•ˆÈ³jpƒUU°¢¯ÖOê‹Y ¡qa.æÁ îÊîc8“’wV7"¶U+²NíÝ("wAû!Cì·ò”<ÅGöØ;ŽLìäçjZ¼†šµdäB‹º)º6#p*ƒÕ "‹AÔ£‚«q&*dþ©Lårî@po£>ºˆ¸>•Q5M˜éÀ[¿×Ú]_ß„k6‡;µyÁŸ©æ>]Ñõ’b˜k*5ß{£døÊ„¦ÈC—†] ›!ÝÔ¼«:z=$²ž´N«“1ªb6«m[Ýn#BàuDAîP‹… 檪†ªdz¥i{ëjÔˆÀt]ýùô#±ó¢8µ“iè­KƒÑþÇ=Öø(ãúØ'^ÔȶÒÒ‘AZ¦f£Ž;›Wmõ¹© LØ]Ûñwn˜°«¯©˜ðqï»êµ;¸¦Ë’~Ô‘úz¿¯Ë¥kèm¸ÁWóÕJ—¶5úˆÑ‚©©Î®šMÍaDäÖŒ:ZÔÌL³7l†[“ÁŠÕܲ4Úp䳕\Øu»‘¼Úºj#€K.«û²•»Üñ«ùß×@ÝËÏKvAnjuhÕ†.X&å‹zÛCBÕý²ÖlŒ@UW8›K»s¸ñë+¹ÍLYl »š-fU)¹8¡Â\ØÝŠ[Õ–¸E0¢ÈÁP35s­N¤ª¥º“V²FÅkhAs×:„ÈSÞ{÷QÍ¡w)%ª}¡¤*u]³@Ý*y¹€ÎÜÜ/Ô3ÿÈâÇÅ#Ò‚¶àÖPjm뙋²³{q'HfsϪ¯ÙMàuš`hybܰ!NmDÜ ÁÏË¢ø€ŸþãÏÿáþõãøôa7ùWÃq7k®‹}¨!„Í6h±ÓoOêoðæ»ïËó©ïûÛûÌ©ÎöôÃùÝ7e¬ËÓôþô()Èíðÿé×»»»wÇÓñùDjJË©>ÿîa þrì§§ÃûoÏv:ÕwOå¶üêoÿöfèŽOOß¿™ß|ˆ§©ËÖÍŠ…fçs7§ê0Bh8[‘âV´¥Ò4a+5€åäªæ2Cqú~ƨéĉÝÈÜÛÐj.%3óð¯IÿÝ?è’Ðh= Øq=lïl58‚À—!Ðe+ÎMŸâ÷÷÷»ÝŽi ̶âíÝÀÓ —yžèxÎOO>—ã´ŒÃÙ /p³½ßív}t±ÓaüðîqZ°9ÛíäIâgwŸ?>< ÌB çzžÏËñÝñ‡ýr¿½½{½ÿÉëÏ_þå¿þæûï–@hùÝ)¬ªP¶©ÞVB[Võ5oÆó¹BT x–âŒé:",Ï0×ÍKp8—¬!a ãPQk¶ºÌ‚l:jLÜuQk ,à0Äí6m#‡ R.Gœ¾]¾_ÞÇ^ò±ò–ÃÂÀ6qqS‡l6Ýn³5³9N)•.Rä¨Å„”«¿ÿú1ò|> ý¾ÿþ})zÕÎz¬.¦HÌp~>ÿð]=‰>·ÐøÃ÷O˜ÎÐ a$é³ ]¿ÛÜ Ã¶.\úG[T¹Îõ¼,ç¢Y:G)kÎãT3ŸÎ˼‚{ì7{Jœœ0å2H✌ên“'pº.¤J¼Ô§7ï_þì3h-eQ×Bà~§²1¡ó4==/PÛĹèôøxZ*H6çR«H‘È‚©pÉs‡¯YFŸŽmÿíë¿:­ù!t‘ÒI­³Ü ܰÚ-{Û¤‹êKÍZ„ªy¨:Ihâg\’ïTáÕ)õhÎdnXÎÆÌcãLbTµ.A]Õ¹ZÍëk™ ¥"\ìãÜ…ýÐm:¤¡NMSÁ¢@qˆlѲäÅâdUŒH5 b*cãÅ™™A^.“Jf 7z¨··ÁYV›¡r!¢ê…@v±ñš+t}YˆDZ¥ \!êm¢ C`¬ä$‡‰“±#Àjä¢/s6S+à°9³j2Ûxêô̈æ§J®kç‰5¯ÝZ qcér›§^‡£—2ÂZâ-Ö >s\ܵ‘Œ›®…­y¿Ø¥\`jMLbkߥf¨U@ÜrE´:©3™™{-5£Ôœ³©sQ]×q­ì¢FÇXƒ•˜Üܹٞ‰Û€<0„Àf®š«.@1›­áJPç q›ÄØ …ÛÃÜ̉]/À`—Hæs! â°åØC`^Éu$s©R,€º–ÔöLFkº Ö2#UdM6air l©ã~1XÇ„{’Áyü%Æ¡‹…ÅiÉf¦Yë¢îNlmÐè¹'ã %´·”9U!(¹`»®² IDAT)±K{%71†¡E‘ÿYÎz‹é5ÑÇ­rÛôBY¥Ü9¾+?ö?þ#ÕÜŸcß™©*.ƒUÀÓ2`k­.&‰„Daˆ©á&Ðfª)Qä8»kMÎ 2â>’f2m0æÀ.M¨ãp5I“µÜÐHäBug‚¹…¦ò u/ôI'ÓB…‚Ú,|Máh»‹pD.Dí›\AXWTkzËÇ\ZÿQa³Þà$íÆ»bœ `"ºF+¡Å™™*úžóÆ]/I¸+zõÆ\>š§¡ÑÏ×+@šu¨“œ„} ò++¯ ®îBì &À‰©š®J<¾$5ÔÜDqt¾ÛÜÅ n ™¹ñUkH)ö!V«ÅÙ\%s“ÏYËZ;Õëé03[#·MÛ@«¥!}ºìZ ¿P7ºlðÚ-¬ªm*$«à„KHkK»ÃÚ °ÕEh£Ú­é;æTÜXÖÈAõP^Úk8»iDqSgg" X‚6‚`Óýª“›ÕªM>®êªÞ†RŠ`ä"L-Ø(‚÷-¹úhÁ-V ŨšC‰ªÌÚøvél¯q±-Õ U¼¸d-«·çõzZf+9¹6ì«´Šˆ»¹ d%Fš*¹6Ò¹›ØŠcq¶aè?Ø.}ñ³Ïý?ý§û¿yýÝïß¿üûÏN7%û¼ûâýû‡‡ïß’óî‹×!ìÆ?¼ÿÍþçþîî.ô8>é8í»‰c±Ï_ÜM‡Ç§÷oŸÞ¿‘qÙí(u9ÓTRŸ@‰°ZUkëZ@E¤åûšÕÖCö§O×OŸls?Y%}šßÊêd ´5åÿh>"& W±tÓ˱ûå=q¹÷.iKäpÕ&¼¬î nóTf_–åxTá™w·ôêõËý~‡Óß¼þ, =¼ËӈÞ>`HN{FÙ$ö1±<½ÿP}xÿ||:–^0šç锆¡ˆžÝ3À˜F{xû®fÍ–ë8ÌužhÿúþåmüìþÝÛû‡?´GCaHƒ+eîRÚ¼Üøg”Saó¼Ô:æ¥VugéHÝ‘ÀC” Õ޵8|ÃÖûçù43ºN´Ô‚Û1í©B—ì5 9‹!—iÎ1«fîcŸ(I+kwYµNêÃó{hO Š¸ »ÍVÙx>“p߻ݮ”² 3̇n# ñ4Õ\­àÛß¾_*§dRGS…æEf®UQ˜Â!—:‡e¤§ÇED 9ãxh¡IjöÈÖà ÂÄ»QÓ4ÇLÓ>Þó†ùøc>OocIŽ´¯£`i7ˆÏ©óPP@ Á‘myÂ!$ !màU“¤]èÎÏ'›çZs—‚÷¢\(RÖš‹:Eáà%,gªf±ë¶7ÓôlÇÃÈN›íΦIœæé/íT™ÿŸøˆjfY,Í +xvw¯Tb120™˜6 ö˜óy^àµù3‰Ì˜T)Ü)DV"‡qhQT €†˜z!‚L:bP¦è‹3 bÏH$2‡Pâ>ô’¶1tŒ Õj©‹/®g%ì@BìÌ…È ÅÍ3A ^‰Á{¸•Z@¡-\QU×íˆp㌪6ߣTÁE©á0½Øz•˜]A"̰¨çM&ã´¸d¸’W®¦ ‡éš·nÎ ¶hµªJœáð@âBfAësXÑŒ“a€["‹†žc}‚ÙeæL«¦`W¬@ªÚèWšBCߘé‹Ü¢P[ÔûJ’æºdm+'…[5"5ƒ+$ÂLÍ€a¨{uÓëlŒW‰ÿe¼ìÞba^Í”ýOFl03È.Ù—D˜K€KÍ9˜—<‘°<@Û[_]@¬$#¤ÄF¨´æíµ§:ƒ˜ÅàF$Ì}´m=sKö,0%QZ¥}Á¥£ö[«ŠŒèn É nó_¸±À#1¹²iêS쇘:AÐ~×Å …q@ìÁTQ«WíÓ6QñJÕ©ÍÚ‰µ’HPp-Ù6)¦HA Õ] XÙÂÖd\ÖH9 OØë­dYO‡]^Ôd@%mb¶?}L¯ÊA†kN‚?r´ËþO$sWܶÍ*S]¥á‰Ö Œ dÞ¨‚(óRUÌ)¾hËö±fý'%áÀ”ÀpçÂ`‚ 1Sõ Ž«9¬^æ;×¶)8¼zUG)­Qo8jóñë®|‘›]g¼æ?Šw3Z“–¬‘Óüc%ÄŸ6E­Ãâ¿ûÉX™øbVjôùÆ_Iú-DwÀeÍYµ d›æÍ/ߎ±ZD¼-àìW‰ãe²`LXÃëVÁõAï¦PEà_Ì 7B®•HD¥¯ålD‚8 F LMP Y7oM<ÃBäZ- '€,;qKo¸ŽÒ¯Yd Æ´,¦õÿ¦îM{äȲ4½÷,×Ì|‰…̬ÌÚfÔš@ AúÿÐo$@-M÷Ô2][&É$csw3»÷,úp̓̚ª”ôa¦ãAAFÐÃÜìžsÞó<¶1Ÿ×QÕ—Ó9úKí½üL÷þƒepçƒ û¸r·C‘ëzžm]kÛiÂ+äš}deI&ËhÉ ·|͆$)™bšéÔ=>oDL™ÌÌ"ä³@¸ð»EP:HH¹ á4¯Ðð¡N0e6rª‰t $gÁ@Ž ÊFnÂ‘ŽŒÉ_Ä6Àöžµèc¸> ìÇ DBðþiÄÉ ¾‚%¾|§gœNÉ€'ØÓ£[ûMݘA‚ôïÏÿù‡?Üý»7v˜³^†Xîo§7÷_Í.íq>ܼÁWßâŸ=káYsúé×’ïþð]ýîIç6L7»½ª£Èð“¿ûùÛ_|óüî‡ïß·ž^Þ~û‹áíí\ññåý#Í2÷Ó)×ÅJâHEŠ¢.—ǗLJ¶ÌjQB‹å2‚ÐÀJLJ¨¹+2™ZB‰Sˆh›6oƒÌÈW{}Ùük{@¯À“ˆ ˜É#œàÀ¿Äš‹ÿ*`… í±ÁCwr¿h²Åv9õemâíîg±!û¶Ña…‚€})ÇýDžï¾ûîÃrš–áï~ò?$ïþY?¼{ß\ÖÇu5•tòA’1ÝLûÝîü¼¾ûøÓwç÷~zp[¡‚X±䈲S\Ïn˜ŸñlÏ“ìnûÇÇË<•™æçƒÜõ8Ü|3­5rõ"Ã0Ží¼®'+٤ЛŸßŸp®/v^æj.ýcõ5¨‘b”óе"*r¶ýNÜ``eoá„·ß§oö´<ׇ÷¶¶¸\@ ‚à§¼œŸ^Æ9jkkRB霙_ý5z£ƒY¬ê T  vIZ”iG Eš™/V/³»»5QÞï÷¢ƒ¡ÐyþôþüòÍ0Ÿêìð@4xƒ0i×óÀ¸7wwßî.ûb¾¬ëÖqÊeY—xúv9(`ž”Dº—͆Z&™îË8NË»±=­¾ XŸŽãA’|">?<‰f½TokH€æ|nžZóýþˆ J\.™m½Ùß4Ëóùe‰y¿;è®,>ïÆ½{Ôjev‡}º7onïjË÷—§ÃnÔÛa\å²Àô]L\‹‡-ÚðkŸ¿–šÛÐ [pjë‚3cš¤ÂÖŒ¶=ʹ€i==A@Ó8éXÛâ/gdÃ$ÁÝÙV˜µ°¨fn¼@Ú¥pýñÌ‚Aµ áp—ÂÌ î®tfÞvŸ%hR.åïùß7¯µÍK=/çu™_°œ0ì€NTöh­(¢ªº¶9Оýg$Á Q1mí¾TÕ‘xkîN”¬I]áÐõãçe;|0 I6¢¸;<7ïƒhr ÕØ$¼f+Ù<ƒ8¹9*¡ç‘)®ÅB¦Õ¶º %RGU-†`_V˜ƒ‰ØiOS™xDd}¿ÆPÑDS47°N9¼¹‡ܑҗŽRúRØvÎ ïJ]÷mVN b’28E‰V•aÌ×¾¦ :¨j—“ïÔÍÔLô1UFkLTŠÔÂÂÁàL„£™›B"4™ƒÄ…®Y“:,®$1h$Þ¨2B@ÌšT•ÐNh u¢÷u`Ïg„L;$” AÝÆ‘ ™Ì( %|¿žœÎ­!‘YŽ  Eow÷ö>åçÞt*_J¦d"¤†]â@8<í(öÖvþ)êSÄÒX“EH•‰EÌMah­º{7÷¡Z*¢Ö–&h¤8´¥6 VÔÉ Ì¾åŽ  ‰@fpG˜$2@FéHOx¦] ym° ˆ;á$€p¯!7Öj¢›-?ÇÀ¡ýRÊ( ôL&¸Û(“Ö­V˜SQg6‚`oskÅÜV&®±Z¹$ÓšÞÈX_‹ÞÚOJd„™™Yל(2K…ò–«UC(©ƒ 6%fˆ&¼¿xË}©ô!¢¤? Ñõ™Jðd€™àÎxÈÜjÏWXQüø„Dôzí/8ü³y]Ë&„‚×Öz>4™¤ó"ˆ=l#âñÃoŸÿzd/™h+ü‚2 "ÝEÔ«Z"ñ°’’™¾mŒ~Ѧ+<+‘fA(DIH2Ó`ÈÔ=Üa½•T…jzsÇÝÐêÎA²¤Í« ³ˆ H_«¯p¤îú¢?}>;ö†tg'RôÉQJªÙ«…ü³Pé¯kù"ðÚcïó4黀t”Gkn¾¹þÐ_ìÑl&Üu¹qÖ…t‘²r&˺R:9q$HD¤•$@ gfJJÏ–Ñ´”Â$ `N¢<„Šåšâ ÂH"’;’äèS)Í”0‰¬ðÚœ8•E‰ÁÙW[Ñ9)=Ýמýl@ m¼ÛU~SˆŒˆ9#a[1ˆrí…qw³2—È¢‘™A¬ÑUGH%B&õ•ŠÎx|~Ñ2 Ñ÷ÿüîûüÓñéæéWovÓ]Ðl4ûúpû“»o¾›¿¿<>ëN~ùoþöíýc§OïŸOœXççï>¾üæOßÞ½-oK´—ÇÇ÷öðÓ:—uÞßÇ2ÝN~ÔÝËãùù‡OÜbWÆö<¿\¬Îs]?اaœßª¯ùRõ|Žv®ë9ÆÆe9) +âl‹uÆ|jæ,Â,Ið@l úôÈÞUHÊH"…»fdº$C)‡ ‘„͘µ-sž œëb 'ÖÌÏôº¾B}¸ÿWs´^‡äùyöE?j=\Q®½v*×TA4+Oëý›ãn*oÞÜJ.·»ûlËù‡Õ°ÿãñ?Ô?,'¾)ÿæß~3üýéŸ~ý½É)¿üå/UùÓÿøô”Oµ4”À¢pIäšF ëiùþûÓz¢ íŒãˆ<3 ù¢»µçúHËSùáÃnÞËn˜~qÀÜüRe­´Ã°^V/ëiýبYÕõló“£êÍáxs;=?LG¦ÒÖv)EÞîn—¹=~œ£Œ/óewÜEXYƯßîî¿™þÇÿõïo:QÁï÷‡?ü.óî}º|²:ãådKC”VŠïvû›Ýâç—Ëù¹|º»»{sw¿¼Ôçççöìƒ B:Žê‡ñ¾àx:_–³DÚür’Ú"×p@èr9eÙ½´X.N‰!1Ít¼=è0-«Ýpµeº(R°JŒ;Þ}=íîǯöov·Ó§ûùîð,~˜Ÿü#}<ÍçùùS°†Ç÷ïoÜ?>|òÌaÒý›ñîçüög7wß܇KùÝìŸßýê£6šŸÖ5žÇéîökÇî|~z~÷§">ènØFÑqEÚürzF3||9ëhR V²–Vðýå:¢±Ýß½iYs‰Ÿ}óÓAhT.$wo÷ûoÞ>=þpy~Ú c)z‡ŸÜÝúã³½4猖áP2d$'…pl"Ä€Ðß’@MBŠÊ`®s‹:ìÍhµ¹ˆR0T`±¡Òà1ì§f+5_ê9­Ét;Œ˜—²Á$÷Ó~¼Í”ºz«i”T„D ðfë²\j›¿úê>Ó#mw”DËô„ë8å°¨21;Ò2Á2»a<º–uõ:‹Õ!.ŠYa»Î&¦ˆˆ &žzû˜ JNIJ˜¬™â"ÁX9ºDζΪ<qF­–™ªCЈºB™KFk:–iœš'u [ïafB0Œ:ì´Öy<Ž¡h˜Aܰ,::Ñ WF‡Ý¹âö8­±T'pY“p^€ËýÍW—ÇçúøóùyÝ}óVߦ²Ç]VÏÀ\A“ìnsÅ8y¢­v0…G•¸ÒqØ»ûùåì…77ŸÏg0O‡=ƒ/—-P˜­. ÃTHÔ3 4 C8_æyšö­¹›7óÍÃÌ‘þr L;$(#†ˆrÜ1Ë4éHk¨`÷x!cj9 ^8a•sö¶W0—f;FfOjÃpi~jvö81-’3a‚Ó#3Ù 3 ‚¯k±ƒAD’–nnš²Wø`Ø1¦]iÀÖçßÄü~ 3%‹h’C,f&}¬ë—P?7G$â®éÉ0Â9[:Ò¥ÆmóCâ͘ªTâåà烗yNT£åLç•)E•‡ZÓ=)È™¤É#ë £ºPÕÝhdB½MÎã‡6N5ä ™™C=qIøfF€&i‚‰·"2)d™-È@¢Q_ØåÎ9ÿÜp÷ì¹YA·\Ce]OAGAzw!¢S¹—L%°SÀ[f³$ ˜©9"€UÖ¡¡,E0*)aqìJùz_É8¬¬OͪJK,¾®€»ÂI鿍¡ybØYY3}W”3-#‘BÌÂmÑŵ ôÂ?3«5UÖAº58"rëp “v{¹9üÅäè3Ô€¨ƒèºoC–ÎpæÖÚxh™ nª!ò*  )h9BcÛ:Lo‰¢¥¼ÔÕÀ&ÖRnf"ÒÃî ÀAŽaÀ¤ê×fK4÷.bˆ’ŠòVEôõycà T™™Ý#ܸ(1 ˆfðÌ$kBfbÈAº’…GMbƒQÑqm«ˆ„y[b×q¬Õ–§|3H\Zº‡ç’`d0£€×ÖÌBY¸ ¹‹‹·,Â2šE „{pÝÙþܧNÁò£ôã ¦¾R k(ʨD´,­Î8ìAUUUfñ>ï‹IeØgÈ^‹ÿhÏÏËàÏ¥ ‡ûqσ 7Ëôéaá6ãùrf”õ94˜ÖnŒ]ÿ‘aÍsðtOJÄÙÁIZt’¶¨£Ô‘ì,ƒ”68­KÅ´ïN=Ýœy@F´êÌÄŠø8ð1˜!µyY—e]f7¤Ã|Aº*/]ÒW·û9þ?íâñgVõ~8\‚áÑgQ=*¶i§…$ÀLX’$g_d(=¬µyž3ÄAëf‰T¢Î%£Þ˜«µ…µçó)ÓAa[E”™ˆ2rHc•qöÓÄ:QNÈòÝ»6›¯FfY•‘Bž¬}‰ÝÈí°ÖÝ”Wº<FP$È ¹R6ʉÀÛ3¸+b3Ã)@Þgý-Ci‘N¯aé-Ü}4°Áq”,€€UÀðDSl@ØÞϤNDË+Ã2Íš;ÕLAʦoJF’ïx¤²¯ÍÑg÷1mצ»A$›îâ9aéTÁ‚"RTH#ÂâŽËdÞ•äÂ%÷èÓ-0epßãIÙœ?@ ”#ïUFH—ÄFô O’ìS30‹B@š*€´t䌨K«ÄjfÊ–½óI’D‚L$X“ð`KwBëó*ÇÚ³L¤+p1, •¸²š„q#:Ax;BHŠŒŽZŠHJ¹»(,ŒLÇÔ0”WV?‘?Õè p@¶êä|Ucò•&Á ¸uf8˜‘ ŒP’hOtÜŽtÜ—²§å.í&«yìX§±‰[4_×Õm= ‡lá5ÖjÞ®Ù o°L$ B2€'°¶JÚXŒÈhS$œb;õQ&Î G'?‘o‹l ‹®P¡m>„mˆB}d[XèuÔ„ ê‹>JJER#(£ËOÇdíc%l×/^w“òŠ^I"²w:Â8`”ëg‰U…kŠZæÊ´XTŠša”`QÊî ½´älò@2y?àsOp"œ˜¶ÿà5lv…‚ô§¾gÊ&öù³›è‰ "ûQOÊEná¯nÙ–m}ì/Ý‹ƒ .Òñ»²åÇ6Öõ;y‹ KD $ÉN‚^é2˜ku%há" ŽV-[¶\¸'¦=S¸I€ë#&bÊäîÿ"ÒPU"Êø¼ÉãH‘mbHEXÀì$£ ƒÂHÎæ=j¢ª†®äsM%GV "R ,Ü'á]œ'›¬Á3Z³ˆ0"KXÂ"WXßÖãûÌ âíy„«4²ço_Mdè49ˆpï¼3Ó¸¿“2)º©*A¼5Å_¿Î56ÙÃB9'"(¢Â9ÓxÄ÷âû ÂÌP&‚YÏ!9® j‹\ÖF íƒ7&f ¦œ ‡&ØÑ¥É¢Z„–eq3By™Õ ` c¤ÁZ"‚(Y{$•П>ŽcžçŽz7‚%ˆUÊ e°yMJŽîê¸óŒž{C""A gB¹—žñxHŸAõÕP´Ö23Â!î*½ ACĈO€:=Q[ÎïÚsaÚ‰I¬gßi¬`6·Ù¨’Ι¶Àª^Öýnª//Ó·å—÷‹Ý··P²Óúø§OëãåãÓ»xWOŸ– esz>{3¸§ƈ€5SFVÓÎXôðÀšäÈ!}d¡ˆnj*™ùaÊ´¤–¤”+ˆ@-#@u˂÷ÖH"“‘Eycú.0öLKZ“n& Lf—m<ÏÚ›*üß`Eô7ÂÂÄB} 3û邱ÛíÆ±p®Í.§s]Ö—ãQoíS[ÚòTsÝc¢P¥é8ÞÞüô'°ááãK]|9_^æL´ŠA =ׄ@á…rCãfÙzk$ÈZGÎ*9ŽbO¬†ÝáñÛoovû±rçÓy-„¯¾:§ñ«ŸÝ}MÿÝûŸ¾ÿÕóé”öÍ¢ª\h*Ãn*(áî­R0OzàÛ¡ò¹¦†—OkÉféMëáȱMwåkìÍŸþtn9ï ç‡–ј@%!K¢B‹A•#:$ó•LÝÂK†{'#D:‚ÂÛåLôQ-·À ÿ˜õ/Þ¿P¼â­³Ò¯ÑçûÌ_ÿw¶ôÞgì9òʦï%R0_s4ŸÃr=åø®¼:–® ]€› ¶‹R³3Ö¨'¤·¯£Äbp0®ËI fî_Y$HÅÝÃA”Â[þ úš "{„™ H•¬YT7´$5Õ0I’€ 2 ¼µê07r÷ˆÖ‹QUd¾¾e¯ Ó×…­Rh(%3ÍZDPJÉfWi[äu²GWô`ÒgW&l›Cböv1ʵµd2OŽÄ@Rð ÈânVÂdAæ–Â4¨Ôטûê¡‘HNN`O‹ö‚è[‰·eÌš’ €Á×0KkšÔç›ý ÚX’Èø|½%'(ɯ~àÚLwc­3ÒUhG®œHNÙÅ}y6 šÒW+3ÐQ{D¯Àž°.á&éÑÊÌT3kfˆ ~CPé*ÓÈ+ëÄ<ÜQ¡-†Ãq­³¡‹¯a&à¿þŽè§?~ˆg+UÉ@I;Ù9ÕµFkÓíô³Ý777oÏu^N/oè6ìLs,tÉ…ÆÝX0Œh”’˜%•F 7«é¾®Q’(ÛŽW¿7B›¾Vbâdôi9mÒ³.ó lBá ÝZë-&Ê…$+Heë3é¦EÈÍ>œá}›à_òý+ùb&d÷Qzö0íH­µp­ÈÅàùöÇÃûëåa®KF Õ¸¼Ì—jõlÇÃs‘öòôt~y:Ï3Æ$( !f+”TDe2:Ⱦìf>ÏÑZÀ‘"µ% qz)ûÝÀ“æ|ºJbÇå—?ývµÖZÛït·/?ÿù·oï¿ü»Ÿ½¬¿þÇßÖOÿá‡ßç;iÇø?Nûa iç˜×¹R[Ë.Ë®ìîÆýí(!ã„6/—ç9Ÿ.»}9”ñxw|3·ÝÍ;?ƒ'Œ„·eïMÍë0•RJÑÑÙöÃñüð©.2ØÜɪxÕ(…’#K£‘ j‘®•À4`]‘ B†2íÒÙs9;"“2š×žl 0oÞÈtK )HÍ)ÖµáûïOãü )]Îíùñ2¿€'šTvá`aÊÍqß(×lãÍñîînËy‘šž‹ú ( µxŸ`p¤èêu^Q鲿-7÷»é›ý»ï.'/+(Mv=:ˆvötCd™³Ë8Œ<ÞíߎÇéñüpñ3žqiKb¸Ý wûX†!‹¬…D,RÀNž].÷Zm'zÚt|c…ÿEÄîjŒ!¢Œè: œH¼/Pö¼‰¨3|¶ÃÓfpñlaáH¤‘¦oË–É›5)@ÁjH"HlL+g$rn@„ÚB<°F]i™íŠFB¤”îØì="¾±¶¶Jqµ-ñöü‹aÚºŽ½J‰Ì¹(Yëë&ÔCçª: Ãìs—†ôœ½€"DBÒt`‡&ŠG¡,B"Ù;óID²qeˆ:)yûnS27ǤpfaW`Îiý Ôª£:<¡³Wž?ÊeÜo‡Iw 9ž*ÖÖ›V)©¦d1ÎLÊBšëºfFQàfP\«G¢Þæ­Kí’+ÍJT•S#ÈúM½;,"‚û‹gî䔢Þgb rýg4ÒÞî`CpfHH‰U‰šzJB¤ÈÀÏXÒgÎFiHç  „¾’ž "î™ëM£Å LÞ智…„‚ L„Ã8 ÃðÜ–gϘ¶w‡“½ž8;ŒýeþysCD ëˆjÈH&S'e’Auǹ+0*¦© 9°V«ˆ†aÑvq3ófn›®´×ÛÁ + j@‘΄y6óFÑzN.=a ½ñ|~?2Å•ƒÔj¾m½àºÇþã{@~önýõ빟e{ì3®V0¤d—·@…H¡õ£d$#“6p&#™Pš.îb.ð‘éP†[á7#û2' „-â¼Ö%à%šh‰è?…díÇùNDÃg ^ßyÈ+‹­£ :Bzë¾:‚¾÷ßDėм+BöG 6WÅÈÐöÛ þjnÅUFŸ3]q³½þº-ê¿Gz-tuZ÷ïÙ7‘uô3ë4°.3ó ˆq,]Ð<`Â(E½]Ñ)L¼á27/UÒVèеÂè4Æ~kÚ¼³~ïè/tÆFccRÀkö Jˆ+s¹.ŠÆj5ºË!e[GÖÕ7l3!"=ÝI¢ÙýKE2³ËÛœÑ"=:ˆîÏëÌ«…öÇaÄþcÿ·Ðg‡¥@U™ÙÝ;U´ÃÎ_­:ýåý³[úüÚlM¡!Š\2Õ|qOOpœ/ó‘…1D`>TìÈ`ÈH4tg«HŸ€ð 2fîÌ?’ àh áÈ9-#4ya7´4[Í…ADFÖºn*6ï}7»‚Í6õmtì±äP*ë)—™ÊV«˜iÛ6ì?IÊHaîŠ$J® F÷ðé QêÒšèo´L §„öÄez_bBCr†ŽbPÉ*ëeÝíT·¹‰pÂ~÷Ão —!i}žyÎ=MªÁ»a««ŽEaOþðÛ‡åÔÀ¡ »¶?/"+}÷¦±¼œ–ùrVf[ÙŽ.œÑß.I q¾Ž;}[Fg•+ø56LLì齘¡ÎÊʾ˜JÑiÛÒ  Ä ¤ Heã —Ì!³€ 3mœJ0§G§×EOÍå¿ú‘P_¬¸Þ`)‡2£µ•¨oÆa È)Õól`ãjÆhœÖ…΋öÒþôî‚ñ‡÷óŒVA‚››äÏ 1'÷;)é@…õ´bEè:IÖŒjhH8 ‡é ‹_n7;Úÿê~óðô´Æ\½Þ¾™.öøÓö“»ŸíÆQoŽÓ×oî~xsÆ ÐÐG5ûñVY7[|~A£E|Häm`°©Öu­¶^ —ø?ÿáŸÞþüð¼~-Bç§å|Ây¦±7¸½®ëåqYÚùýÇZçÇ—8Ü 5̲*ÎëZWj6"!žÝÛá͸ƒì–ð«¸ÛßœŸ›·%!»éx8+µ5æ6(¼eN‚¹uÎÒ²,ã®°p¦ív»››Ãy>=¾Ôÿø?{Œ°,È)sÀsu&Ž7·©ôp~bæeY>¼{ÿ|þx^—ò›‡ãñOJåüCž?Ú‘lžT=Ð ܼÕoÿýÏ~ù?ÿâþéÿúÝoÞZ]‚… H³Bs,Õ((ªI•AÆr,9rJA°%»Lª;ÒƒLwãÍ·‡2`­2ÖÝóÉw‡ý¸[ÚÓaP?ž/—ÓÆ;¸¶t™ÑàüÛÂsÑŠWÕf£dÊø¨Ò¹“‘øÌ¡dîhª"ªiäôLëN§D_H¾ÊØ„÷ôÃuˆã ¾°`¤a~Y@Aa‚€n+‘§ØöWöwWˆþ™ÓðõÏ‘LÉÛâw’§|(ÒO+@‚•DH²ÝÑ™3{-‚ ;˜x³ÖR*Äj .2š…µ€÷Á‰E7nÿqξ« 8!ÀÙk¬DGsSSòíñv®¨´:\ˆJÖ/9Ô:ÈÍímÙI±fàXÙàÚóIÌI $˜Z[Ý)ój.:¶è«ÕÛ·µmu“ ÄÊš$ U.0 ’˜«yïcG¼ÆU2{D䪼 ¸Krl-f((ƒÒuŒ¤.DÂ<‚ 8uÌ60&``Ñ$ _k[5JãlO|£Áè|Û~øã? )‘g±P$Ešg“ÂmHµL:$ËL¸‚…;ÿûuc Ù\GCP]*퇫‚ à•J À^±/<îK9Žtß…•hJ²€pæa™5¸ >°ƒšPÚ.Ëìïºî° > ¢lé‹k‹¬éÈ`Ižd‰† ~!öY´Kx¯Móú¬Ê×Jü-‰Þ"¨É}Ñ€²óî$ ¥tòS‡Võé5ŒÆ@!  !³Dj¸¤™Ç¢·ãp? ·©kbŽpÀ-±²h ³DsXfô×#¢¯ß{ïÌllXÚ$˾ Àâ:øm¨’¯3¢^rtf 1Eößg³ðÃöaçøGº¡+—ëwtChKcõ½”/ý«}V0÷ª~¨F¤™½Þµ¶ÃÑg ÂÀ|yŽ¿ž‰£Ûu_ÿSO/&S?Åz8æ v!rÚ*ÆìºOÁVT¶HFr‡•$Ò;%˜<23 fÆ%.R„¹ÖpS¤óÍÉBÃÀ)šð Š„{ÔL#€áµ!ðgàüØõù÷þ…=V:©’:8#Ü«w~TAÔ[½Rì_¢¿PØìô*å F"JUKZ‰Ö VŽ$T¢•RÀÖi‡á%c`ŠðU§aäDu«næIáD²‰c3RodXgòU½e,È“ÄQs—ÂÕ ÏAÅ]Øo1¢ïwõ»UgoÞ!î»=.[ÊÊÐvÜ¿ýÚEûðô 󜗺î·û¥L£QT·Xž/ïO£î½Á+|…?C¢qå]ª.‚q7ìK»Dò„ÛòÕÏnÞüìöðt#>¶ÇÕûQweÇ5ÄÓÎxï—“G¢@_–ù|Zkx­†B*%G–eŸã.K!f.¥ãh4ÖÝC>ŒûÝý›7lç1oGÜœNá>϶öbƒ€þèëZÔ¿i—h›r\ãÁHî tï=X 铿N—íú„€ä‹>‹•¡u l-á–$¤%ûa›ì3!‚Í@‡Yfn'LtLŠìt¢¶RÃ|ã:!¡¬„Ñ8E)©X~ïCH‹"l6 îgsÙØ;Û8ÃÆ"ì‘"Ê”Á ²H¢Þf‡#Ù£!#Ü‹"ƒ¸KK-A£µôÚ¶$a?µ“So" zý_Ã`œ’æÞÖe•ôˆµñMÇÍ‘4!*Ö3îR*Sá‡5²¢rŸx¦»‰‚€f_ßRRAvÓV!éû6ŠîêçG.ª¤a™F–­¥°ŒP"r£“BU‘›æ“ÀC$o™Ÿ]’)ÑUHp°Pª°„¡CÉ)u`E¤™-Þ‰ x?ð'uúHâìÃÅ ç•ÀæQ-D 7ÏFFøHÈ@!¾¦AuY×'«U±ºt“q÷Aâµm_LP·ss¦»³S A ¡$†ÌQ²L„µUü »¸Ÿ×uá¢HÈÒ–@KoAœÛĬ€‰Åáž á‘Y‰ÅZ,•Zrçì:ÒáHßr,}‹ªw¾‘Ú³—=Í…ì4ªWÎqü% ÿöml'¡/*Àì«N€$u6·$›‘–3ýßÏ™äÜ—4¶VB\Î(ˆB1&¡=Ó‘y§"5TD"×È–‰AHÕµš-ÂzÝ ä5m/þÏÈNb&êhÄ×a^yÚý.¼¥z· "6"+1së+…"ÙeÅìŽLÒÑ23 ñv”‹PzJ Ü;} l‘ªÒÌZGk%Yøâè-¡/tùº)øg©Å/ŠÓ×<$óf<&"²V{€R•ŠJôÝ¥W¦×vdß^väKe×ü!9S5U#Š&Á™”2 ´ ŠÎ´°–v; ‘ì£ ·¥°™¬ÆçÅW‹FNÐ^ÿ‚#gX5%cq;µù¤1ŒDœB RÕA¹{(m»þ)±GÐÓY‘iÈ >™_ÜfåKzÉXeÅÒãÌÄÒÏ‘N FÉ‚Ï~Ú>§/JOÿQkM†"}Ô]S—‰ì UG¦g‹Ìî["™XÓÄgªfYID&-„ýÎËÈš$Ĩ¬4›7Cˆ“g&“”™³ÙÚVóg©þõt«©ç/5HÆaàÒæE< É[z°Ôø•ÿŦ\φĕ’ß9Mœì¼ñ#[äxlr¼B”¼¹ÊÐ.øˆ()Ñ@9tf†&êƒzBÄ6{O@h£ÿþ«¯ˆ6,?À¤Ñ™®HÿÉ7o¾ýÙÛŸÿâps“oˆ—ÖNl<ÞïG¾§¹ž¾ûðñaõu!Ý!åÍÍíü² œо -Ã4Ý}uóå´^žÎ¾ZE¶5mm9ð4î†ã`ÙV¦:&W”8 ÉÉ¢=w=5[[­§_Vanȼ>Êï)ëLJwÿéüðõ‚‘ !”rzž¡Q³EƒÜQ/óܼ-pMZOEvu™înnLJžVÃüؘÛ~Âòˆ›IƒˆqxzynÍ×u‘qw<Ì|¹ÌóéÂXÑ$Æ›róö¦qk¢oÊO~yws/˺ÿôý3árþp1Ó e^yˆWâ(Si—j+¢¤`+T%ÂZ3r ³P.7‡›¯~²Ûô«o¾½,v:–Ël _ŒÝq7MS˺ž«Í`,»`ϵ­ÞŒl(#çî0•nÞ »{]p^xÝߨNö¼üܤdæ EguJwïß …Q¶Öžžžyá…ªÞ2'IuÈ•-çÇYà‡RÚݹ¬î§çs)åþþÞ/ˆY†pô˜Kï&3˜s{°þ%RÈ1 ú%Ž»>L?‚5$%Žè vd„' þ_îÞ¬G²$¹Ò<"¢z3ó%"2+Ébq™ž¦Ÿúÿ¿40Ïó>hô`H›dU.±¸»m÷ªªÈ™½æá™•E€Ä¼T'‘@f„Áü.ª*"ç|§ÃLA"!‹J„: &P É{j êfŒåƹIïÂèè1Dˆkô˜Bï^ƒ(¤A“jj„’™ ‚Ìf›úe›Ž©æ¾ÃyŒÙÔ⛈ËNÕž´ ‘ ,aº…rÞ, l½ò”±»‰v¶´Ê$ÈŠ‰é‡ýäU¼j'ÔöK[ØšD(ÑN¡*Ø Í-J×ýgYÛó—g.MÄrVBÙÈJh ¢.¾^Vc’`žrb ž»ËI†“ jÒ¡…CÙ›½$UM ­…i oh 7éò! ’fA0œ ÑÞ+ŽpoÌÔ ÑÜS¢ÝG‚W+C‡-èàkëlr¾ñTXï"›T½S,‚9BÂG`6Û3eQޣ߽õ ÀBDä†AS'{£w›‹ À¦Ñƒ(áè ¥JÄÝçIBŸ./ŸÚ²$ÔðhÛOœ_"úzàèíÍÑeWÖgD³c愜C§ˆbâ’y_Ø^Ö(IÝTÒ³¬Yá89qum`@;B_ÕT*¶ Í) bÉ] SÖ-Þ¯Ï1]é·vJÓÒÒ9p=9ôgâX¹I~¬üyß]^ cŠã&tÜd(FQF¶¤d7ú+‰@?!‡°ó¢•" ªf ‹ Œ,8XÊ"C´L²¬-¼6íž÷V>ä0[ÈEt*¢w;”ºiúEã¦[멳·0§^zoj¹î„u3Í-lWD{Á°­ZÜ$‹±-ž"·MåAò[bZ¡Ý”±¯×•º£úµ‚"y£§ÕêÝÞssä}Û‡| y­ á}-¡¤íD×+öš7±­€P¥µè_R“u«Rÿ¥ šDͺ s‹|½¥3©X`s’Š )) MªGCˆ8”¢!BäœÝk™Ö¨•“-M:jsÀû@F¤¥5Wˆ)Dж:óvùÇIzòdz:oÅÚËÔ¸™ß„†)"=Š”"?Hx×aËÍ!yD¿·„Ð0%BÍÅ)jÂ^ÄL,YC ¬Uax”U`c&îæq‰vmŸí0†.Ò©W3€­µSu+„¶ÍãœJ‰•^k£¨©:¬FsFxÃ*Tì¿­nWJˆ)ÀÅcpÚWájÀn¢˜;­!"èìbô$êáŠkWo ï—NÅT·iªšS¿¡J¸»·Öz*JÛª‘ž:!@ î‡a·Û–˜âÕKb’6tŒ®#YJiš™$iJšsrŸ “M–lاñýüà5 kUµ¡à É¶bqSÆATM"¼k^‘nï« Ú-7¬9CºG44™:·Þe5oU£©ä[¤So«0Q˜éY8GÕ!"GdB9uù:[tg()ÐÞ>öd…î Ø|¶æ,ÖZõeœ4eGª’Ä9óaÄôùŸ×<‰r("ç´Ø 6æA©ËùÒ%¹Šž )¥ùÛw¬Eó©EYµzxÖŠë±N¦ÀŽ2qþfͳ~ú§Å¶²–•1§‰‘ëÕ??]Æ!Íû±–³-À9¿¬õêïCÚrlçO`Åœ1¢ÉåeÑU5Ì%$%ÀÕK ./8íkN¹¬ÞïÄëñÏ:áeA-xwòpWÂkAiËRK­eœ5g¬Kíºÿ¾gNãîñÃû+ΟÏ&bÊén|üæî÷ÓõzöÂë¿ÿ>³NÞ²{´Õmõœ=g›ïöë¥i[4#fD€)™ ÖZ‹Ò4™<Ÿjõ¤¶)9ÛnÍlÞ óЊÝaš†9%eiOY´a½”¨°èbH¤²\Ï÷‡Ý<]ã2퓚ƒežôán|/gGc)¸ðꓦFh´H)ÄjiMdm—õê‘}n£V‹â»ç —eYŸ–a‘ëÃl).Ë‹ÏzŸ³¦ËRJã²ÖeY `ÜÄ;½.rB•pùF{}MÍ£nBÙz¨ñUc`C$pgê“nÙ§AU³R‘áP‘~nÞ¨k›zKM7°m2ÑîW¡ÐèÎîeÜ¢„HQµ.ðhÑ:â¿z­^¶¶ì†Ð¶ª6|†mµ¢w¤ØkÇWy3FvPQôX‡pF8(5 j Ù"+U5¥$ Í4Ü“"gLÄ.»qw˜_>— q£GñmÎÉ6Ø2‚:gÁº‡ÄÑTls ¿¼œF¦œ†œ,s–`pn|Zí4HŽB¥¦lfÉ‹­‘«D’F¯!B3œOk‡íu/ÃV앚§]Ý d+Ez£¬‡™{kâ™JÕœÌÚÚèèû &š, ýqë¹Úí8Óhè•*•_e—o*"2 CÃࡤ2Q'± Ю¨-\`“ÎÂݼh hP·ÔÔ¾5) Q©J"‰¶n¿aÿ8jŠˆ—ey \'´îþW…@úF­""¥Õí@|«-Í£%5#”Ô 5f‡û{Ì;MwIïR;H›ácc‚°Öˆë•'QŒÉÍZöµauiïÞºPFÚÍ’D±Qr GC ¤sÅ)=~–Ò»§"ª4ëœÄ.»åí¥#&6K4oj¤·¤°»ä7—^¿Ä½þ7bÓ‡€½²6²‰ôæŒ#·þå²}ŽˆB’j‚"‹j³ŠÕ°¨±´UÄ0ZUSm¥BB­Š\j-”B6²›˜„0…Âàª_Íëëø±köj@A³×˜Ý­ØuwöWóFYèëØ*î^J wf†¡Ôö3ÞéF1 ¹$K–“ªò–øíoÄQ {Õ i I[œ(bšÐC­]B…FÂ[-^ú 7ä4}I$LSNBKPÖ­Ì4K=¡¶t+?•_·/þ[ÒÅ·~°·w¶¯»yÈ"’¤ú[kÝ…”ø3ÄÅ×ôÒ[>U| ù¥JGBݬ¤p(P *˜Ô¦aLI³A#¸\B•VËZ\œ³¦löþÝci륵JÒÔòU=rÕdɽ' Es†/lÇa% ütYšS%[¨…Š \\C¨nÑÛdrF_¢·et ²™jK] #Y¨èTtä^hgDµùxY IDAT¹m‚Þ±êãD÷蔥ÐDrÎÛðô}’•Ú”HjH¦É¢ !49^—ÔÉæ’RjY.-f“‰dá¾®«DOšg(]h£š')­­E…™23J;?½¸sÌÃ8¤—e)î»ÝŽ‹#Èïò@ÁI·éòRêÊh¨»Šº¸v âÆÍf :5Ã$ 2¢Aó¶¥+áº-ÔÈÄœÓNto¶™Â†ðÜ\ÖiNìM½À–òÜ57Âÿ |DÈ&«ÇZW3“­ÏË—>>Ï÷Þ¿?]އÃðîÝÃýüNÚòßþ¯ÿ7ÍEä¸B\ž^’àn· ‹‡GœO¨ Ó>-Kùò|üðíÎ&•W¹œó€y¶IýrÁqA\ê‘Ïï7üçÿò¿ïæ@þþÛ—þ‡ï—c\žÎ§ÒR²²V'Qm©ø0Ýíças¿¾üáò|õðYaDvÉÉãËq< »ûy?¦u]/qYj$E»âýC YfòéOËz 5dbÚ ÷‡CÆÎœN§OO'4ãòRÞýfýøüÓ4Íiw9žÝÛ`ã0L—ËeÑå݇»åÓz·Ÿv‡9i—’þd/‘³|þ²hÝအ¥$‡Ã¸›çãÊ0Á¦f‡»»qÊ­µu]¦ip°µ¶®ëéå¼®õþpw¸ßiøæÝÃ8-Úwñ޾~üai+ƒïï-*£>¾Û1ûýãôùÇk3\_VuóµuMŒï¾½{÷›wy7zZ§4ñùÓû»¿›M÷Ù>ÜYzç<#KܽÔž_Ž6!gÓdÏçrÿûs)&Š|mëÃð8ïÇÀR^ÚZV†Aý|ÿõåñßýæÃn÷nžîÿþ¿ýãßÖ’OO_®×­ùé5 š“´ÒLÈDû”øµµaH"âkëk=#”–¶žP‹ŠFŒfD$º2DSLwwá…LáÎ…ª !Â¥-·í?n€o1Ïc)îµÚv󜫵^×u¹VÐÁ@3%,H¸[ÖVvö­°ÖTMÛ™u‹ÉëãwwGgD˜Ù+ @´Md,þBU!k«–,w¨©ÉZe[W˜ÀxõV;¡áz½xHƒŒ‡ ÚnÓ´Û'¯k1Sø0CklÄ`×Ë*²O” –ª9Ót9•L ZC4@á,‰Ksªª6©®É|¹â:™$’­6z4ªÄr¸ku KYóùx¢/!Z£é8'I §7ñîök± 7W”RDÄ$«$µÌF:%`6,KQm–¹œ/j–ÍJ)`2ÌT-4ÐØj„Ü͇Xžj)Öu€l’6$]£SÂÉJ0tL2 D»D3™SÊ¢ô§aÇñÝ»§åúr:¯—µÔ‹%S –)cH޽Y4›^ëd8¤9¥tmåÒêY°&°³•Ü*Ý{®ªIíÖ¡¹›E$k"ДÒ$6`À9aP ³ÊN®c½–ĪR…HfÔ!A]jc[Êd´hÑ ­!–l°µª×9c~ÃNŽ /ëÌ4¸–vB‚fµâ\[»º7ššY×±DDswçÚ|+‡z!Ñ*d §oçf¢#¢ TEчMȲj¥›ˆLUM$ØZsPbRMiOD’¥¤šIñ&¢b¦`2I0s—`‹æ”¥Ëqr²!w÷¹,•5UI–’˜"Ú8Ž…^kuwUÅ0¤”<Ê6ë~Ðë­Žˆo"¼Ï×±F#©DŠûëýµÛÐá5¿õKè–ìÛgÉ-wØdE±IÕ¶rÐývúRatû6Z€(ÑçýÙ pœRDô`$ò•=)]®Á÷>ý–Mó×-LÌ9§D÷¶®e{úC¼!õ€Üá €w!ž;j… !­‘\ksÞæoN’F¨YkˆVãêK,U ÆK¹ h–T· œBɪ–Ä4™j©¥Uoò¨bææ11!ôºÖêÑО*Úƒ¯Ð³~îØ”×ÆÖíNÝp<¹D^-ѵ†]f(@2 å8ŽÕYk%`*¦háëêã˜)º™Ê ä§$9'DsÂÀ!å GYwã°W±¥D½`-k­ën³èdÃ;Í-†¥ár²Æóó8ä)!(mi0­9-ó¼›ÇD_½]×Å™hɆ|®¬Kr™à×…Å鲘Ÿ[‰ÚdÌ©£ÞZ©–¬w9¢µµ…L)ßîœþér.ë:ݽOw»k­"bű²µÖ”’oóÉy¿‹@m±x­-HíÒëœóÚ©Yó0¤œ%Y€y謹ÚZíŸÐˆºÖ¬ÖµóÑÜDE • ´æ¬k¹VîD'áê­Õš‡Ëº(©Crª˜¢rŽkckâ­¬&Å‚>£×Âæk-Íáª: ÔËH€” Ýú&}Eì'U‚gÐ&At#æ±sÐÄj¬(*€!T0ˆÒLt(`kÑ:^‘ ™Ø y 5 …$0«X?5ÉÞc7«lêlEoøó¶iE´—€3ÓR_ãÚŽ—ÅÒ˜%1‡é~H‡ý—ÓõT–ñiÌË¥qn—aÀ»ßØý{}~ªÏ/íºþ´»;@¯Í¯×빂ã#¦Y†¬ -çg‘Ã0¤qSÊã÷óLJï†Ý"g?a©/ç3`ÌiÌ9Ù$²ÂQiPæË‹›A¤`qp]²%JŒ»iÈSN£%• •m­I°³|7ÎÃnV ¹xÓiÃ4©^ì}DD´!AdÀË/ç'w˜¿yHuHLÇç—ziç—óhö‘-}¹[-ñ/G¤úüò‰ŒŸ~xz~:_.TÅýÃa·¿»úq]ŽíK;ŸNÇŸŠ/h ãØÆ)c†œ’‘Þ•¹%¤.¬ËŠ*µeÈõ¼<ÞÝUÔ—ã—kYäÚÐÐJ)ÎFÒT4‹%ɃzÑ»ÁBÓhû»ñTNaíÚ.Ÿ~üôéås>|kï~÷øô‡ÏŸ~:}üRž)Ûݸ;ìæ¬v÷8w:&4N/Ã~\Ž^Ï®©Kò» ×sλÃa¹/çÓrt ¤€9êŸÏ§û¿œÎ¹žO—#ꥮ§.K@r+[êgïãÿ/þ6BL4œœ½s‰žeÞàÑÔ‡ˆ:èd(¬C,…jš8t‘úf%½{œd) €< fëÚ¼Ûÿ¥«µÓ]ûDÛ EDÇ)ê}ž›±~£Ín+»w ÝM. v=Œ¾Ò¤ºçJô¶ËzôM°ã«¶6-‰vK2ï H x8"uLc¶D_ÚÒ3N¾†Õ«i²”RjX : ᯰ‰Q6JA¥8Dè@­n’’ƒ^ƒfÙh~5¯V‘zêGq÷*¡ÑÀ»]:ŒódYà¬ä©èÕ´€Z°µÖ¸¥†ê–ƒƒ¾ëöd£^ù6ê:’ÞßÈÑQd]5´©J;Ö#67Dá&P *b]2×ÚÛ{Ã÷£lp32†àÆÓˆžwd¢"àë=â’" SZÿªppõX€Ò܉ž"¢ÎÞSíŒp26[#^‡]}ó'òÖâ×ýÀ"|CŸ“{~þ.ß¹p]Éù ðï³ï¸Ñçpô߃€áW"²¥ƒé¸Ñäå ñ,Xn_þµÎÉ&ªÚ;ò34IŒCâ/Æþ¾YüD‡;Ti&IW Û¡wK,ÐZŠ &¡&1*³%!4ë1XìU¥RZ­›–¸[‘Øay¢ì8²:Q#D{Plâ!é#å~¿øÚªïÙA¿vûÅ¿9/jÚA€i_ØaÔÖ¾æºÝ_UoiL|¥íoÛa À(«„O–%gµhMò4>¦ô˜SÖ”Ãl?Ëp<Ÿº ²´um‡»ýNï.§³‘ ‡¤¬V(^ce] g8UtÌC®QWB\[}Y1ˆ%Kƒ"daT(ÄtîJdQƒjèöŠ+ÄAÑt\® *û»ûéþîÊ0ÑišãºRB(Y *I´Ô (UM3 ®€)Î03˜¹Â#ÖV³ ù-µèõ½‚JžF½iÕõ«¾Š%BÅAÑ‚è®Ã„ E˜¡µÐ×v†© ë>\˜ŠŠ"€&áŒÖÕŽÑ{Ö§Œ¢üöLl/£cÃ{8 ƒ®ÈÔBj0-XHkW³«9 Øz†Fo:@ •Ž™¡x²k’T„F,W(ü&3è¢èœúËòçï#êmCjÝ®½»Ïõ7ß>¾‹o¾Ëóž+×q?—Ò~ÿÃS)S¹ð\ë_.×À7ûݸÛþø“ eúo>¼ÿíûïZÁßÿ÷?,ÿ÷˵±ñr¼,ëÑû½ØMÓ˜E²þ Б^øôñù¸žÇÉ~üøOûaš'£+qþ„g`7ÿ›ò8޵ÖëõTj±iöû4ì(.ͯkoÐR¢¹·æ¥´¬¦bØتIБ¢ê˜ê:ÖäKƺw¾˜ŒÑŠ”RDJ©Çâmm óæÇQ¦³M¸^Ývúxÿ—Ñ_Ž×uYÒIÆ]žî§i7•{/ëõôTÿñ~üòåyLvy®—sÀn7|óþqwø|ªëËóåÂK”¶)ŽÑ.— É1g³Í:­´º¢5xYÖu¹\ñ鈻§ÏãnXÛe­  ( Ž/g®êl%ÎÈ5w£[B*„ Ã<¼{·ÿÍï›ÞçCvµõËéùŒæ˜g¿?×r\ÛËÚή#$ëh¡,q‰kcašuFº÷÷wÃaW?Gýþ 6Jh(«U½Ûß·eÕjõ”nG†)-žÒ©Š_N@«˜&¼ÿðWgÿøå´,éÒ¤ž óï#ÍõùDoÃM8£ôVY…¡Jh—··á ÆWjï¡¶X—ÕdÑl2ˆPD\ƒ!}LµØ˜ÓDX[m^næõ„ÍÇÐЉ`ïýu_ÿŽ¢¢JÐÕÌ,õª¼Ï‹H+×[#œ=¨B@5 ¯1ŒN^ë†M!Ú–³Ô-=W((uh‚ׯNhH Y‹,ר¨‘¬Ö@TxEAM) )%5›*ÕQŽÞó€jµ_z9)Ô¨ I-I+-Mf(ox A«!Îî.Ë‹êÃÃÝÝÃÁ².ËâÇÒÔ¨[6Œ ]y$ª m##nLâ.4…I^ùKز(!7_{†ö”“ö+¢6žEóö j¢Ú©H*Š0AŒ‚±áa°Ó~oÃÒÚílQE²ä¤† ×Z[€Óé´ÖRJñÚ¶„Lé l¤E/LÙÙt©a ÜÃ`Óêq¬uxÂ*H ™¯’›¾nž¢ÏK!ÖE`áx=ð)‘ Èé€t¯q§~¶“6måµ³¸‡w/¤¬ζT_ $EwöËFbžu¿ÛK[hS,ÅSƒ zg2ƒPIÐèwð^œHp“]ýæúw5*¯DµÍÒ¡·!·lSƒ&Ò„˜ QM¤£ú<¶waBÕ#‚hoõ¨7S|ײ‰á¨ÁNžµž‡Eôœ5b­¾F,îÕ¹9m”‘®áŽžÅDÇ«uMþ8“MÞd/ýñ¡ºß_˜ô3ý«"Žáä`¹%³ß$…7’ù×ë×BÞòN@dCïwÒö–@ôfæ­FŠÛgtíêæy|MOºý•®†ê#ñ¤ŽÒÄ÷ÌY¾½ò¼i¿H*dÈCÑÖã8{l¢’¶ºDH‹Ü·X+¿}=¥t½j’—e[þ›‡‚D°•°[Ë=ªQˆhP íáUètJpÐÔ"vD·ôi'G“ñ+)Â_T>[­H¼Js7·êí¿r•°¹S´ÃCInÛ*Lê×Ô'’ðH@b“RÆÆ}ê´ÐÉcÊß »‡C’ê-*Ôtžwûi°´o°ã¥>½œ—UÅ$ça¶o%L);j­¾®­î†‘1;K6Œm¹Ô¨×¶´VÃëhi¯Ãhš)͹8šˆY F‹Ðc϶,2² #"EŒ*–ò0ŒƒZ»–²¶l.PÀj¿BŒö55SMYÀ #¬ÞÖuŘUÕ=V¯¡ÛN©gÑÆ«´¿Y)eð%ú „hIˆ>¾ …Ƕ&pPuZF)ðQÓ”Ça†‡Ÿ®õR®um¢»qr¥÷`6rË[ fÇ×"ºŸm6²Hº¥GÁ.˜wô4cuJ¸†(<€,]gÝËvöëLJ¿ÈÔètzZß# ë¢zË ¼=Jzs(’7I3¸ÅÂþÙWDÍÑÑU¢wúÞï~÷wß óyÿçëÇëSÒt9ú÷øüås´•Ï×õÔ0Ýçßþ§¿•‹žã.áïþö·õþ·ÿdÿø¯N„£\Öv]®ãÓ·Ãþ~iánHà »‘ïö¶ß¢ðûúéç4àøÔ¿Ó‡wïï›F?î>]žÎû íÂñÎãx>Åé¼–Ò&•<êÝá^ò4ÔBS–VK)u-áMÜ%rØ4XN£îé©\¾´â<>}iR \Rà ÷yCL—Ëå¼.K;/Áx÷wûßìöïw?}ü¨IÂÜ·C“ª›º%O³ÎwãáœÏQüùTg\^Ö»½%f£©.ÙÔr¨¹šk¦ZÃ0¨H¢{„/×p?ל‡!眽z)%VO„ Ä¥,tA$šÒTRh‚—Šc»./-Ø ‘æ¾µ”Íѵ b:ïÇÇ¿8üåÿòÍ%Nçvýò|z¾ž›ƒå„Ÿ~ÿ2vŸ~<~þˬPýr⪒îçËqzކ9íì0ÒÃpZ˹6wÓ$ Ž(¥¬ëZJSMãÙª6˜JæNCëÙ.pÙÆÜvóá/ÿò/¯‹?_þI7ÿ™E#xÓóüE)@*]$™G'›»„Y–Þ¸‘”6ÁfäÅ -&HÑͧ¢Y¥zz‡ºÝÎ!BÉ7¼Ž@BmK_•ŽÜˆF'üë•· gËÙØòdDxD§`˜ç”!ú*¾@½²¶Ðvµ¤a³©÷”¶Í¢€FhÚŽÖù3¹`¦ª±ò¼,×rF {œ@ÝT/@°E4ÕÔY=½$„L@8;* ôèÃhTBz´°Ð·CLDºÄh:äaœÓþçË Ç“ìXÛZ_žƒ9Ù†´Ë K=VÐû ªD­ˆ‚aVíáÏì—¾ï"µVƶ¶‰jçv2ÃÐÁ]üêÄ0¨Ç¹] õ€ÀªhÒúˆx¥ Ko+ Œsà>å‡q—g_Ï^N‰‹Z@báŠ|zúR¼ ÄBÄ6±“¢‹7©`'&%#¦ÀN³ª^Êrlk5¯É˜¯ÿÄ uÕåC bÓ\ö0¾&7¹½“!T…fŒÃ^|‡uŒ%sUuÀIwzxk%™*Ì[Y.«°Ø[ÁtÊ&ž¦yÈjËåÊK¤b£Ãˆ´bŒÎ÷Ó%p÷™¶(o²}DCl1—d¨jR÷¬`+ïoóyÅɰ÷.ºa0"¤—C=8J´‡*[›!!ê&ÍÙzâaèÁ-Ýâ Wéq±iÐ~;ƒ ÐÑ–`´`(ÁŽß‚ˆDÂá†Rñ ˜Æ–jú6bI^ª[œÚ¿•¸ú¦ÁýêðyÓðþu‹¼Úóû4,n4ùùÌêÍï§›¿BµéÌÿjÐ3¿nÖ¬ ÒhÑc8»EÊŸ†±ÿÇ ;Rb Aªmû)T “.~ìË$î`ÚsëΣ…·ÖÜ»ÎÃU·T+e§˜÷·/ú‚AêFô#…á鈊ž Ñ ÖùŸ¯©G]½Ù¡6ñZ6oáTÕmœï7éáöK^M_I6_3´7Rß/j¤þåͶÀ+YŽ|¯ûõ–GÔ3ð‹ä±×'AÑ’× œ…S„Ö:¨ˆèÜ¿±ôÝá -žŸ¿œ.çâeþæý´;¼³lãDÈQÈ–§±ÖººS(•Xé§¶^êp; -êš(ÀБæAwÏŒL!XM¡*u§7†«è =³N öôijׇqW5µeዌÑ"]W mµZÛä‘[@D¦yжˆpgq÷@Ȱ¡[Èl„Zk]¤¯¹ÎŽïQ2º‘¦+v©"MQ ÁÈHÇÒFÓ ³D4„Aš5Nóø8ßíïsàšÓ)^Úy ÷Qº™ª—°Í¦N*ãµÖèQÐñúZ‡ÝßžªpiÂDi„Q z hb[_ µ~ÜQ v2)7jC'+Ù$S3%‹ä¹H¡Juv¤ÃvdÙÒíoÏ$âϾ"Â+FiÀ|7Ü=ÎûŸ¾¡ÿõ÷/§Sy¼÷ñó§À?/O*˜ïd¾“w¿ýîðíãO/ŸÖ¼¦ýÍÿú×ó׿ÝËô¯¿?žËÑ 9k¬žLv»Ù><¼?ì§ÕÏlܥ阧ýp}˜wiÿr½œ—ciã„X ïõþÃa~7=îïfÌ?ýó×Àº ÌÃܵuÍP€Ty|·wUY‹¨ZNQõ|*«GQZëÊŸÝ4še1Ð[i¨OåÊϲ×ñ0¦Ip,6ì‡4"I9GYC6Z;6T ãááðî·ï.8Ÿ¿œø¼æó|9^ëZ%+ãÚês¹òzúr:_×ó ׂu†¼×Ã4Z |¹ÖåÓçߟ—ùÜ€9+É“¨öîˆ L$[Ê–é¬K]®!ƒ š“;—ví³èl:HŠq¸J FNV¢¤µ*\eK€«Âv»¹Õõ’¼ŠÂS`tÙˆõ´žëõRZ LŠÙ†9MlS]ór,§ä†Y%Ûr6Œ–/ìÓåaÝYZÒ¼Ÿbõ–§ÝlSZÚåãS+uwãòõósù²^+³µ‘=³)'4­”v½^/%¾ò^•A:#ÉWw쿳НÞØ6œmÇ~Õå«ÅkE¡@ºÁI ¤,[·Ús‹*шl›=UUUÌ6?Fi•Â5õ&j?›èëž½Í.L ï'¨[ª¡÷Ælë¼*G‚M·´Jª*¾³H6³a«c›@ÝÞ#7B@PúÉ6D´þÍ+Vx!,Ì0§q—ÅRD”s-×3JÅAÆo& b‡uU4$¦>À,­¸ô°Þ^€¨PAQÍô.>ŽÓD Š"'`;^¤!§.×jµ50ó4MT.ËÕk”ç34 ãž§?v÷þýûý‡c=µä^ØV²:œ…KÔÊ ì‹>¹ë—Ë[¨ôFo(Â÷–o. [ФXR5IIÅ\® D3QÈn27lþìÖÈ7\º+™€1M³HóºÖriålz‡Pk ‡7aXï…;Ú ú1-å¾G+XÖÚc 7ˆaÄØ°‡Ðˆ¸¶r _ÅT¢ÛÎ{šå­¶ßÎzoôÀ-¿I4.›®’‚ž m£ø(kò³´µ"\Š7ÓFÁ”¢T:|©JDcÐUÍ’‰JE\Y5™´æQš¬ÈMRØà>iRM«Ã4’h6ˆh7ÂGøkUÐ7]÷W Öv»´ÿ€7‹Ü^ò'•¶ÑgÚólTÍÌIJZW¥Ø)a.ê¢nh½ƒÊèÄÎh@ŠXƒ¦šDÃ’ôœðÆpT' Yr•FFcÿ¶ˆÞÃPnçÙð|7¼á/o²1Í_óRõ#†œÛ]¾ÁÉ:@¢cêþtÛèÕ[¯²Ù‡zÆëŸxÊ lÍ-5úk%VÈ&eìO•¼©Ê6ÌÂÛÙN¼Ùâtر[õÕ‘2¼M±z0%!eYû&ÓוµÝyzô‹ P˜‰u"éçf‘pèé :Ø¢ëG“$Ò{T#Ä¡43ª´Ö6Ök»^D!ÞƒgýxÔKº^' ¿–¦ðë[ØFІ½¨mçÚ·¬È›ITÞ*!ûô[~øíM‚J[AÜ'»7›½´eÔæl{á>|.ë¡ÍÕ¨±Ôº.ŸJÙ½û0öw´é°çéqîw»çç/ëå|¼¶€‹JN™—ãu9½†S¥9 =TÆaNŠì\[]J½DôðœrÛ´i ‹H¢CßçÈXoX ³Nq^Ên·»´öt=Z-ûýa¶„¯ž\B“g†@l{‘Izóh}ì®2¥Ù¡–’ )«Yƒ[–‹»Ó[­¼Ý¶u]hèjº­5Y’zùçb­Ki;Ù–Ô„¢íM$RÚwïî'¤™—8±Dƒ„Xb”ôéͦ¸iµÙ±M7do õT®Û»ƒŒÌ¹!(ÖNyR ‰$ÚóÝ{."1Fð+KßD釨¤6ÛKÙ`ëéA Q’¾aÄ[ëR‰?ûŠH³ ´9nÆ4BS4^ítüôrúr½Öo¿!ÃRñã¸.øßþ3wïóMQÿáô©äöønzø«»ËÇÏ_>h±Î;hŒ^9ºZn³ÎÉÕ[2g›Æi9/åˆ3–å%.õÚ”¢È?¬_äôÀßéä¡1Nc^—hî×âe)¾T8rq? h,”E­™2'i Ká0Que)î®ðXIÅZ!ûqȃ]–ëñtòÆý°sˆäÑTS„A>¢µ&)ÒN\ÊÓå\>a¼y ’_üôñr-º±R IDAT—ô%gŒû!×áäÍ¥Á—±ÑcHR^®¥Fi†at‡ ¡9½U$™æœÍú|Vèˆ%Í,i–æÉt‡1æ¼B[e ÓJð.Bl¦ázi]>ìežý¥ kd÷Má”óãÝo¾ûóUô‡-œ“¥]Nò”.@ížÑy?íïvåZ|h%›,é´ŸÆýX¼¼\‡ýn?ïÇÐgá±~D!²2ÁÝsÊýÜ7XW>?¿\kÔZ;¸·ï¥BþÜí­{Ç›l½#f¶è ¨Yî»ô«Œ~KX7 Toñ„ÑÅ4¤Ûšæ½£‰ÔÞ2ÑP3U¤¤¥ÖætK=¶îB3UÛèk”­~ëÔcD@è"$:`ÉîÝ_°Áp¼”ŽÐÒí¸ (æyüÞu;8„¦¤ïó¬M¶o2( hës¨0Ç4ì§y¦KYj¹®85ÀLÆ1O ­é³æíûÔZC=zõe KC%9ÚN•èc1Àt#š+4™ˆ"¼¡ óÐÂ#j­ê5ç1ãxÙíAƒt`MY¿x{y¾ÿpß¼¬çæ­pmƒ†ŒÖ^ÝÁF I¢:˜ú„+”"­W1®fJ߸¶]?‡ÖšÝ,\]0#ÚCý(bjºeåé)Ú ádgöƒ® ,°7Ì0­áKYʺ ¯ ˆ†Ü`º TârK4B—¿S]ù;ÉPéB‰0b Fâ>æQ¢\½^áâAbëw¢÷ûèê烂íl½]èJÐTEa00%M#§»yÝ5îѦV,ªHDx#µpGÔ s´¥–kH=H˜1iË„3t®CNCR(ÒP|XÈ|wwÿòôrzEwwwyž~|þò/?ýËþ!wù_?ÿóßþ|üÃËé{4€‚¶¯â WNÅÏùQò„yž9 í‚ãz¿Ô`¾`V ä ?¡§OïÏû»'1½œd-Xpñ³¬um%S®!q­×ïÿÉ¥X6L€uÁ¥ M˜÷Sv¥õénÔVëɇ‡ûwé}>áTSÕaGÅê¸^âx>Xt‘æ©Ajh²)©9c¶l åZQ*¤…I,1ÑY/uõ†Ëõ7ßýEN1D;M¸&ôe?ÏI.j° ULó`óÎUX庞Ý=HÍÚ¡p¶âaP¼‚îštòݼ?äky.^”Âë¹¶5Ç"ZÕÄÔÆÁ,­åºÖKõ"ɆyïRÞ©Lq\žŸ®ç/ÇõåVàü²~LÇ—/õÇ/—kQB‡ÚÒ¹úõz¾?ÎÓ°û0Ž<=~÷ðáý‡qÈe¹Fó.>‘”uÚOQãÜšŽ"œa;Ý{˜dاóºì÷w]ÅÓ˜øéÓñ|>¯Ž¥.[oS»n£CjÿÝiD·ëWN IT,!¡ëƒ:u)©™@`$b`Gq…³uœHˆ$¨Â; È©PµMÁ á¨lUšÀ!¢n*7f5I™š{ʆ±æ­dJi“_x$ 1Ì£t5•õm¯öUÛ[ïBö ¾‚"6 &ê5Ü›ƒ!˜!™Rƒº©O¸¸)Œ:XÞ ©K­ËÊ´,I÷i7æì^[+\¯hbLºyÅo5Xg!ª‚ñÁŒøÿ¸{ÓçH’ìÚïÜ{Ý="2‘j馆CñÑž½g&ÉLÿÿ¿"3‰"ùf†Ó[UÈ%"Ü@õ2šD~P[Ywu-™È@,w9çwZX?Ô´ª A`]xBJ=x[‚m©‹ÃT¦=Àõ¼Ô¹2•D‡”S\h>‘B”B$c^ºçGD"ˆS‘®Ã¾Õ{[¥»šÆÕÏqõ‘33%ï~iHAÜ¥A=Ö^@®èˆn-`ˆˆˆ8¾’1 Žìs.àhZ×UÍ-£%ZÂêc¶pÀ„ŒÑ—zè;‚[Xê&pÂ98LÂáNž Ur&RŸ[­n°xTƒá:G¾¡ÆÞ¨¬^…U½ï7 Wƒf0åËÈe_lÏ2†  N‚_´u„Akaº°¡ÎK] ktVÀ8§<ìYˆa³ÙjÅ@dލ÷C ÀÌ;›c[>ôvÈ¢ %q]0lë/ßø²¯ ¢·3x ¿1»ú˜Ó= ‘ BÁ}Áå T½…Á….’Ôå…}¥vw¡_D)z IN FhXë‚&#†'&ÜÃÝû9ÚΘ„‰yƒŒ÷‰þ×7¾Þ½² 6þØÛ]A¼íe6 w¼µ!Ñö‹ýïºÇ«(Î;dåZÁ¿F¾¾‰ô½b̯_â/‚oÞvS±´· Go¸¥ë|ý[Øœp›AÇúJ¤—_B[[‹ È=a }–„kb´oû¬ˆ¾ƒï"$¿êysRD «é8®þ´WI‡°ÀÌÕÜ}àÖ[†ëüÎ{°8¾Íò™;÷.níЛã³m‚A_7E¿ªš£Í@u]¬ÑÕ”a×C× :o[£kŠÓö" ̳ù^ä@©¤<¦ˆÁôžó=ÒPk6ER•âð{Ïç˲^.¦ç,§zŽÃÝÃÝ‘í2sN¹ÜEJÓ­¶ ÷’´°FøÚL}0%ŽÈ2î*Ûʦª<yOsåÂ)q œ†Ni'·è‹žý{œ¦UkV}¿ßÑ8—umžË ‰{—"HbBA 7uë’¢héG`J",¨j¨ö(­ÄlÖ™~טÓ@pÏv¦-½›1;Oj*;içú9‘EIb`‹ä3%wbB¦Võr¹êD 'NW—àv9ví4Ôƒ¸!Ù;m‘(<Ü,Äݰ lïëmLÁÄÿèÛmËývfÊCÉYŠ7Ÿ¦©Ù¼0šò}–ó €ñ€ÃýãxØ!Å—ï8þÑ jÌå¹®øÇ—Ëø˜ñÍãaX–—}Ë®— ç9lŒœóSòñÝácÝÿA¶†0&Nu?¶ãð|^OŸÖ§Ï³ñ—iŸN‹ªIÖEááÍ(ÀZU› XÐuoÆ=¨`z?LÓÝRÛ:hk3,­µj:Œ÷ﱦ£½$ÃL/°ŠzF«-mzy?ªEm.X÷EòCÚ¿¦$Bv0ag–”$\¢qôóâóO/’ÊjaÕ"EÀˆY •– HPá"QOXÜNm=WÏ€LeŸï’„y;ŸÉÁõp™J’ARÇñnÚIiççuž/ÌÐóâ‘™…YXÄŠLSž¾ú~>6›‘¦ÝpÿXöß`÷<=y;­µ¢¦q/S;Ö?ÿxÌ6#Ê0î˜xç«ÕËlm¹ÿŸv‡,ï~ÿxÂiü¸cÕõÓ—ÏiMpòæÍa’)sâ™ÖV'sõe(÷÷»Tj­©ÊãããÓ/ZÉ«|úüüòù©ºÄP@ Âv¤>_ùkG•[V}¼VHÎ@„,‚„Rf"ñÎPê6†¶Æ–ÍpåtH•“…Á=:ÈHÂBÃWÐR–$"îîj913ºfÃÃ#Ð<”Ý=j„u|ö•³äN`º­°@$Ì쎾¸ïŠ»‹@ L,Ò;"tKRÓ°éç#@N!öœsWÍY <$uÞ°èâ=‚4qáH©$bvoËrY|V88K*RÆ’klÃç`† ""—5¶êòõP§2"D‚cK™!oapØ=`Þíìë2—aH%[x«µµFDî¡k…sÉ#)¯ËÀ˜&÷§?ý€‡ñáðnFò´œW‡[¬Ãn·Ù ÃT»¢ÌhÕºœ fðLá,œ»u€813uä’“Ü#Ì‚ƒ)Xˆ‰u5„¼i&¤?R{° !ˆ2¨¸ï€c?efž-^ÂN„š $a¦èæ]Þ<"Üa‹áD,Ä©gÀ[Àƒ‰c{ú@€äÀKÕµºU@™ªGmpÁ å@Ïz¿Z@âšö¾–ÁØFŒ´8(Å>±åÂ<ùZlüR0g¬Ì-D¬ÛR×þ+8H" 5Sp‚S%ÎyÌÓ]fozYè4ó‹Ó ҌɅ›…QóXÜÁnµ,®a (:7cHè-- Î}¥Ð{ÜëbÙØûe ¨gù…E‰"C¼§Ï3ºMÒLäLä7Áeexr3q€ÍQ)‚H¤‡Ñô¦\­áÔ7!]#æ ê©Ñ QÀ9b3 öä!xÊØ`î†É_è@~©Â’kNè–,ôvBôæL¸æm‹âMwI?_ÝòƒüúÇúÄÚ_“‡®/=Ç1¤w´I<"Ü:(úÎ×Ý•˲D  ™@ Šý~èëÙŽñínGÑfÖ¢ÇE{„ƒûýÒºç“6 øµÛ¼‰†"^átÖÑÄ|5¯›ožP6Eå5 kþ3­·X a‰Ð[ƒ÷Ʀп9 ëR?~±$¢7ñ|\zzn§˜(,æÞýD)õ§Rß½nã:#R‚Õ¢v0¼K2ç Q¢¨Ë\ö‡»2 f}ØdN¹h„çÄ …5˜[Óµ’éàI8 N% ƒ„Zؘuu&”êjKÆjƒ—<– »­‹Ek—Ý0$¥,yåLDi(¤ aê47rƒ[M².³‹|üøMÙß}ÿé3–åñÝû—ã‰%±•yÂÈvZ’ õ¹Æ(dF·™9ƒ¹nUô§CB¢%Ffa8;{# Úôá]¼ç‰Õ$Ñá @Dzk\{»©tÿÐNæg +cñW’×ðÆf÷k"xhxbay=7oénxx~öI] uøþŸŸÞ=|óÍãéÿZj+š±£]NŸx>?&<œßûwß_´žy=Neú8=xzþÁŽn,ž¸%¸ öãÃÇÝïï†Ãÿüð®|Yê’1r½ìë£/m}8 šGàð0ªšîÊ䎺4Ò:J)]1oêÄq ‘ÌuðJ³b­,3€ e:åû 1'©ÍN´Æ½ÏåH«ÓƒÜÍß_Öu}/šbÃ~B–yI±ä]™—Ê{¼ÿû‡ÇÿzÃ|>¯²¶;E½@ž˜WŒ)XêÉÔPÆæÄkF#g-CÈäy<·f:¯­áÛ÷SÎçv–ÔÒ–OUý’D'Ù§)»²IÐùô¢+8u‚\áÞ\Fnm~yYvnwÙ¦„uÅÑ €…A‚á` ×Z//XŸcôûZ[â<ß¿ýoRÏB5~BRì´LËh³žãY3.>àîÑ?&`ùôùÇsM˜ö¿ýïÿËêK½x”ªY^æËŠviz÷û‡²å@Õ£ºµËÅËýC]WÓúþãžÆx^¿(í}÷í#Êð㟞~øáùù4—4[½HdkކDBucMoý[Š2P(I:LŠ„Öص©ºŠŒÜ”)0k‹!xk ‚R2“` ó^H,a¨@+SÇë\µ-è4'îYââîÑ(’H²{낞æ}–çMÝÌ$ g'UEk€# R­f½¼ §­;9Â(„‰zµ£Nãî.XÖuÖË î>&éë(iXhÀš„ Ęï&Ê<·'øS¾;ì§ýÔV]/k4ß0T û|ü4ÙpØãäŸã"jm©Šˆ fÀA,Ã[«¤”÷¤k^MÑ1ð_HCÙ1x^ÖM㘈k­‡é^UÛe ‚©‘w»ûáMœu±ÓŸ~¼ûø»ÓÓù\Ï O»G˜ÙâyâqÕ½b†Ûj J™33)÷†ÚÝeœZ5¨Cr);Aj ÖÕ&êßq8\D¤RQ7£K‰ ®ÕÖad«ŒfÁÖq4É,iL²§fM̃ëã[ÐßæéÃxçDßùú]Ž„.’ØyŒ¤c€¹—Lº¬ 7 ff-ZU]»’R@Óãa_ÝZ" Q³€,)ys£@“ŽܰryÌ·i ™Œi-e*’›Žëò1c ädr?´÷|~äãǬ 8“'ÜïÇã™(ÒXŸ½^j˜¥@ôDY0… Jª‰”½x=öCJRF­»Õï.TΑcš››Í•T».ÅC)<ÈÐÓ=™ÃÕ7ÚÄV‹GÚÜ çŽAfÀ‰@ˆ~`mK$¶­ð-,TºÇXØYQÝV׿®"@NN²Õ!ÄD9l€Äωޗ„IH2ÓÀ­Íó™88•Fô|:Í‘5Ke6p 5ëåÄÁîjÌ1Vš±È ¯ël€1R`ß@€q/B\èU^õjȱÛӤ݊„MP_ÅnV°¸žv7ò™_Uz}ÒëBÛ$uÄÄApeC²x„‡Ã6®1˜ºËî¶Zz#„€@pâà ï3†žê"PDÃ}C’zP_QOI‚iD‹U·Õ]írg€ áæˆHëÙ^Ud½0Ké‰t-tû¢Ì"Ìì æxk*…‚,ºŒˆ8 QÚj-õë²Á"áÔ;?Å]ño¾]”Ü× þª¬ÛÚÎèMQ—ÑU5FÏÍåí+tŠt0D؃oe'AÕ^ŸÖ ж&œˆî (»ÿRöïØNûñyhOç§”Ëó<—Ùr†!QK*C º˜eNBáÞšµº‡Þ©=$*)·/ÇåE›òdå_|=VÃÊQâ<ñìÝ|åbÍ«ÁYÞ•r3áä¾ æÄÏVÛ±p°g‘R˜´µÕèœÄ÷Ó0Æn·òán*ÃE«ì‡j6ÛʪÌS—¢œ,¼¹ª[K–!œSm-Yç‹zLãœëªpdI®’rJ©µÖ´…:oa×ñ¦È·-•)­ç_‘,à$C^[[ÕhÄXj€Ü¤eý¬ÏtÊ,‰¼ß•[m*Ä™™ƒ êê$àÄë€Í îà·0‘ÄBT['‘䔆”ÙàÚ”™)D]ɃYš¶DBƒ$‘kVÓ™½ÂaÆÌ$”'–‘¥0±wx”;ÓUÜJDÔZ³Ø“n!ÄR¤;„ä7wD"üܾÖö_y«7ý+^åwËÜ!T.V[«8åwûÐUN_κ¬w>ÿˆ/ŸO§r¡Üž¿kOŸìKá»»¶Ž¼žÎº>ómº¿xh?V‹f„œ±ßwÓݘÇÌI½QŽ2¢h†?Álð»‰öûê±Ö–ò ks‡ÖÖ}Æ}Z/îP ó$˜a¨DÑU•€"ÁKµ|1gª Cˆ³@îx¼/,||z®KÕjaÆÌûiÒQÁ¨ÑØCJÒ¤–»œLCkqÁ½˜Ÿl¢¾^*ˆÐÒ–z¥l^Ã5ÝÑáãn8Hm󺮄b>®•Ûb:`$;‹/µ-«5…D®ÍNŽD¾.Ö:œ1(y /zÁ¥./ÇS 2C™ZI1‚&œµ˜“ð0N)yN§YùtQ‰d†QX„H”ÈhVFìG¡a/ml˜ÕaŽhH¾ý›wÿýýãlöý'þfúð»Ã0}8·goO—Ó<Ïç3._÷—]Èìxz®X:zužç0’;dšõl± e—d´ãúùéò¡qävôzYÅYŒ)((ˆÂX»^6 ]‡ò?WÁýš'•RGXû•‘/Y# ´†`aKÚàÆ#8ƒÈ;„> ÏÂÑ«†¨‚P0YÉÝŽî,!…ɉˆÚº:sBGð¢‡dSxDC„E„Y ˆ9¥ÜUsfªjpG¿©pf‰ÖfwßÒb\<åÔ‡È79„Y„ù¥žrS!ÈHá¹PJÖZÏap0‰‚5‚¶†’ËDÄÕê¼úª=‘§ÃÈ’ TÛ¢ÏúôôŒu& pÁ!è ¸“Hʬ¾ºXbÖ¾šˆ%ËØª±u 9u+A8e ¢>æ‘ð "vUW…Gs$6½©Ú€,φu…Ãfå w’€ÆjfÎ’ò eµ§}oÂD’™3­àÈ9 2æÍ½…7uBhÇ­uÍ Gwý&pWXqÚ1‘öÄܳÈQøÌ¨Lä$ÁNŽÙ«×aL°GŸ7ö²·®‰ºWIA¤b§è<-¼…5…;³S‰“m“ïÀ¶; ±©n¶Ù7¨a›GqJƒc$ì”øžë^Ö]èHSsxBXøi™/K#kºžµW\Ì*r×O0ZĬ@ªCÆC÷H­rmÃb÷&*»$"tYÚê´À/ÎênU›šR*=ÈÜoê üzËGï–ý_p(DN8ïkp@ˆz°œ uÚ€‘2ŒÈ‚BèjÔ wÛVÍÄD=‡Ä¶dCxBÇSmä%Úå‰)Œ¸ÇÿRC(¨Âk` Ô@…ùÆ” [§R3H Gäˆ¾Ç St.Š\q½ñ#þ Yô5£ì¦šÛ4r¿½eß6Bñóÿ7;¢@۬׻˜‚SíÆhøm“çWFš-)áÚ.¢ËY¯Y€ûyÜm<Ä×°5ûY§qí%¤s®£ozã•'þV·v3ò͘v½*í fýgëN¤ åݹ`Ô/àN»ö m•L¸LÝDq?;>›_îÚ”â퇽UtÔ3¬ز 7ñä†\xNÿÆ ^pLŽÉ>|n­¥ªŒFX(ÎêL1sc'X}1=I>UÕÚöœ¸Œ;äƒò-ï'B"¬u:7,Ö¾¬ú²Ó™=Š P«†6wgf$aa$v„ZS´…t=H2âæ@…»ÛÙš/ZVg‹Â”²P"w_“¥9‚Öu¬+„›jóÓ¢MÝÔƒ„¹VJ­ó*·Œj à å*ê]óÖš™DdY[~4ß"¨ÐsÎoHÆm»%ümjÞžxŽê-ÈEĕѧ¼9&9HÉÑú>ßéš3æÜÎN7†þ›«r»N»[2œ2]³&ª¹„_™—‚è¸p sê¦)3‚){"2[‚»d‰¨ghP÷t·ÀõéH jëËVîZ”Î%qîöT¢ß¦oÿjÅöÿmGôV:¼-Üÿý¨bSl7:w˜µZ—y9¥ÌûݰŸ—“}÷§§çÏÇ—ãñ|HyÂ͸ûáÑ”<IFéøÒt93@yON–`lH¯~™OŸ„¤ÜSPÙïÆÝ8¶—v¶“TÎ’Ê»a|˜&Äe©ÆhhÙh«›ÍÄ 7„³a‡¦ ]“¸»·°”Q(q÷°Ë“œu¾øŒà‚ç'ÏÃI„çy.‰Çƒ4U³Vö2æÁÜ1ëeRK\~ÿÍ7¿û›Çø›÷'·öÓÃS=´Ë%öe×^¨ˆîîÙ'9Ü5O/íøÝ—ùR)x7NãT´­®à@kx¶™(xüÿæã7÷{ïÅ–óò§þóé‡ÊsöcÁB¦Éu’¬ê5 ƒ”ýÝÄ”žÛ¹ž/ê0ì-å})¥ðà|ðA¤.”¥»$ítž×Õ›z%$ª.„\‚û>]ƼKé4LØF½ ^É‹©Â2@#¦a‡]°Ne|w?î§ñÃý‡¨8¯——uþt<~:>ÏVGÂáCùÝÇßÝ¿ß/v>^¾´¹"óPJ]t]×ûý»wïÞ™.—ó…YÁ1RN)UmÇceµµZQq‰Î xíôþføïÀ…DgB‹H)‘Ф\g¡””ÙÍ1Å5÷¡ËÝHz¶wÏË 8d+!I$7×Ú®ŒNð&è‘«×`Û¢»#B{¢Bç¹tg‡pÎ)wD,LA9‹0Qtv®ÓÂ+e5€n•¹Î>n€eR·Óª3‰GI,9ƒ‚.—Sr÷D(fNMšÀÝ IDAT *Û!MiØ »]ILZ­Î®•`A›E*‚Üɉh¾¬~>w›s·;HJU¤÷ž7äoÿÒš* ‰H8yï˜Y5w÷k ÛÏu]ͬƒs$QDÔZUuwªÎ÷ß}þáK7½ ……ª´Ö(93RÎ RµërÞa]µÈDD©$F¶vQXP’± æ7¹÷Á+0³”$§Ìà0¨…»ÂÍõ5¥°·oyb8…€”E2å,IDª5uÛî«d7ñÒö ¯€øm“Ó§ÅÌ]¿´q£²dò–cÓË% ‹ˆ™©êÚZu3Þª+fîµ{Ü T×óÇcS}tä6u(ñ<:r„0¤€'È>ñ~´"–MÉœÜaáä£ÉBœÅbYÔ×`g!*I ®îLHw‡òøî^d¦ÚpnqlrAnC »„Πè1#f°ð( ëw÷†»¡|-Ò¯ùîéÿy{tÍŸí×äöCzŠa÷I_QD8H’ °ðÍ „§<õDl­ @Ì‚€™©µ8ñõ²ìk¾0wu´p5Ú Ð~55'âØxßAsbJ›ï¹Ïƒß²Ý¸¢¯×qõXwÀ×Ò,øUœõ«‰ ¿ÚZý*¦/nrÅ+› ÷6Ä?ï1¯D͸¶å_Š€›9oêýS_Áñ7O^ñÔ¯ ±‘{-~n?Ü»†è¦Žyæó5ì Ô9mo¦É×w¿Å&}õ¦[7OWïÑ©h¦WµõÖ8m!Øòˬ¡7_Þ/uƒ½f®Lä­Ø³WT7Ýöcò5{ýÆ–¤ë_Ü,“8M`M2ÜOûÑ+NA”‡K 7g³ÙWA{;%‰qD­ÑVá¸KùcNy¼WzæD…Õ¥®gõ ºF™Ü£ÖÙ›‹H†qÊNáî\؃I}d¨†4!Ê…%µf«¸k8#"–PjÚY*¼­®¦X´Q0'"Y»<š(Ô܉ÈÁ¤Ä`éì¢>©Ì,Ú‡ý9~Cÿ…yXÏBÛhæÜ¾vëp»ÛóZ?›A¾âýeß½ îY:/~«0̦ œDH›±wò}Wgo§Ÿ{ïzCÌÌÑÁQDÄìˆ0¯VáðHØçCΠ¾: „™õ¤ÆD¤ €0§~-€¢‡†ÔÁNÛ#°‘7 ó”ˆ ÁýŽÐæé·“Oÿ²U߬Á¿þÏ_ÏÝÞ4D—”Ê ã”ËÀí¢’ˆ)âø|üóósƒÊ8 ‡â±jþ~` )O©ìïöÕYi¹œ¿\ –üåôœ(99¢¢Û³¶Ã:/—ZÓ™ ­Ù …Þ}¸O»°Æ®ëi2@ B0ÇÒ@lSNàl‹632Ì+RÔܱذ#ì†Ý S(ΧóßAÏÈ †7N‰ß?ìïrÓåËËìŠý·Ãýý}«öôD§?Áîìðe)-Æ`E6p¢ä±, óË—X±ßa,%ïDZµÕv>ÜMµE'µÜ k`ÚÄÐ(¥Üß?üÏ÷û»Ãñøc]>×—ÅkE‹¨µaî¼[]eÖR–i,ÃŽïópQõ@­H3Æ<ä4°Ð8(B-V÷¦¤¦tvw¬•ãYÚy¶çg9¿àpŸÉŠÀ‰¨ySo* ò€»û=²hÕ?ÿñÏÕ—ËižÒtu±ù?ÿåÓÓ—K]¾œë >ìöiÊ4åi—'@-Îç…2¤w÷wÿîq¿Ÿ>:jè X×:Ïs¿Ñ¨#$Q.)F©—øú¬ì˜ný•³š™~•wdfN4DÅT²dChФ±( (È܈Ã#„PO'¢¦Í;.eá`¦®¿é˜5mí* 3‡»¤|{²ö{çù’È–WÓ£¯é@›U¤—Oª½0¢­ÖxE„}åǽ†ÉSUrÄf‘R¤‘²¸»­êº:÷·c÷¨:»78 Ë Lî¼V[æfÚ¹Þ©;›¹C\äÃV¬ˆ0³V%§2 )g)²ÚÚqÉfâälpÖ°@˜¶ºÄˆ·j£{vúCèJ\'3SòP_WWÕTTu·»ûæÛo_^^”K Xÿ³Ž¨¦¼U“W}|gĽ¶‹×,é6Õ@¹†•)m~-ï±I€©‡· X„ôh ³»õÍÊÖÏ8Ì]ÝBo ¥ðDRxË„T·Z—ÚZ4¼‹ðÞ¦½¦£‰…‰®VÚka™ˆž¼G "wªx3m¦ÍÃAi‹‚â ·ØÂS¶N¢3é«öÞ 3“ìÁqã"1ºO¬·ÁEƒz7o[x’¹gC…Õ©9kf¦L h=(Ã$»sŠPOJãŠé‚r-µ­i6œ)ŽÚE'Â$Ä íLcó^7ÑF`ºÁ‘nO?º)98¾ªº}‹þìÕŒ£o‡R0Çf¬óN¡pô4Ù`ÈFqpÖEA$=Rì¹ÛÌ~VN=°$zø—ÜA,€%XÝàØ¤ˆÖ%›}ÿp³Y™ùúš¡ÁiSnnœÎ˜âÞ"ü¦Šþ¶Žèÿ¶7ñ_WSÜXô×>jó  ˜påom$îm?qeuÐ/–*t½Þ’ãm‚¯ÎÉ_û\|[üàÚHªjüYçíaù*‰–‰yÛËôµ’]q…¤$Þ€Åû‡Ù²ƒz~T\iÚ¹~Z»¶5¿Ì`ýÊôõlÖµ¡ß²?Š~­ƒºò=¾Jº™5¾~í7Â¥À@#± Ó®˜„Hp‘2œ×c V÷ &ÓþéæðUà=c;Õºóò.ɇ4[õhìI$e‡)Ìu©±¡‚¸ç¤0qêV mK[ÏL^N–Ö%…NÈ9åQ†q-v‘\›õ=[µZ[ëfwgBX„zƒK“Þæ‘è‹)N0q“™‡mßc§W»[SwWÕU¸Kà_óš7n!_lüÌ#³½Q¿‰½î£oî­U d‘"2‘³H"î4£H®kí(;†³¼'3˯[™¹÷rÛ Œ(ÌaÎÌ[É$_î®[:C(ˆ3qe¢ïîë¸jnÉÝ{úѶ¥òÛrŠn‡#ûV³føíŽ(%ùÏÚÅ[ïPßÞþõÿˆ€E"„À9ÓÝa||˜Þ=.§?¬Õ3ŸÛʬ’c‚5pxxÿîÛwµô§ù/Ù¹€ÅœÜI>¦Xu7M'š~xú< e¢ J-|FŒ^îéÝßîí©Îß×ó·óK^smFÍŠ"«Wó¶Ú|içH6læ»ÝþéÓùøÊîö)Òr\/çã<»™iº{GDX–"±OìwDœ±HœjI@åÝn:¼Ÿ¸Ôåø4<âÛwÓïþîãÇ߬—öÓ÷Ó—çaoÝBú7fô"yŒæŠ i?Üï÷Dr9ÍË¢C:ÑÊB‘µ.H)e!"«ª«¶µÅÚ÷ˆ VäÜçaˆÖK„WÃeAp+åºð‹èó*láÔlÜÆÂah­11¶t8„»† RJÑæ‰RÎŒ´„£µª+‘”1ïî?<^.—Ç/BÌ€›5ïoÍ„‘DD=9Ê·»·PsƒÕLɲ/VÉ5Tל‡™±wØz°áfV½’÷ô eá”rUƒˆ€ÈÉÜ»´RU[[ Lìa ámѱ‹¶jP†z0Œˆ t6òFJ›n‡ÌÄà›Œ§sÛ’Gˆ#º×ÂÂ5¼F´ž?³Î ¦´¥B^}0¯À¯ë7‰™Á$ â˜È†°”ÀÓØAâNpW|Z‘9z¦±[8Ip\fÀ«]ÂŽ­‘é‰iÓ`PA0Š˜—s%õ±ÒÁó½ÙaõT1;5ÁSøÂW´d×c$¡€9Œ6ж_±rÑ1ß„P}ô,F¾ý{ë5€¬¨ˆé“dæÜG¦ý*8GUw„Çv[ñÞj_ƒn;ï.nQ<[?à N0“…y81¸³ö™ˆé–Ûcá2PĶN$b»:ÿ£›f®@0¿<Çìê2zSãwÅYO §¿f@J¿ÙÅÏÚ)¾×DéuFÑAlodpl®ë-TçÖ udMÌ=ø*5ûºéålMÄ Ü×ï¯åil/öUÕ¿mT‚Â| 2ú¹¿à …ûÙçgpw*õi…_{“¸ªé®™r׈$î³pîpG{ýê~Í» ¾JK5wëo»?ò[Xë¶ä¼¢P®n+ÂϾ±ôU[õ³ÚëJn>±j¨¦ê«yD¬,Ê¡)¯¹U¢5 §pxx,äóóg3;džP¦ Au0ž$Y6à…‡‹) âŒ(«ªFOu+,!‰„2{´5u'_€(Æáªçy\ó)„£Ú@)"V3»ö,ÍšªZDF€‰Yx,Öl›'öGôÅë›Z=Áâp¸WÕ€¾Ù m ƒ*,D¹”¾‡o­õl«Ãô+ßz»æh# õ.zÃëwµö³pï7yNºjKiË1ßD NĶ1H(ÜIŠô›Ö›.ä0µ­cã®[»FGÐö+DWxÜ›óÄ=˜ •œá7¨S¥É$dÚwìo9ýQJñ¦ýk¶›ò“è&QNÿÆç?~IôÿòT!0SÔƒ˜³$Ùá~×Öz>žÎOQgÍÈA³iÇeØ °š 0oëù´ ]ô¼/Òîòûo —§Ó%ζíDU„c¸“Çßßí~7¹ø¿Oë“{k) ”Çòåô4¯' U¸ >|Øóí1ÉßY •é0šó¢jó2ï÷ïöû. Ê'ûÔ´//ÆF2Ú\ T” a™vÓýn—›._Žþtl‡¸ÿÝîwÿõý‡÷ï/Ç5Ã?ýßS¹4ßåÉ/§ÓϰËóåi¼¿[Žmåþ½ÙŒå/Xx&6â§õe® €2ä~w—¤´Uëe^cíâ⥶ççãóOO»;ÉC°fêôhÊÁ„äQk§”÷ æºÔf)Ùs™`¤LI,x©Æb”Ú©Ú´G¶Á´O÷ïËþÞ_NM—”)3`‹­Ï¾>AŽ9ÁBÃ]™v2¼óq*ÇOuÌÓËåå»ï¾ð_þazÿðq?”Ï?þ´ÛòŒq ¤ŒÔJ{9Oøžaîò”†˜îŒ¼”\ç…™N§—°•8îï¦GÝ ñù<ŸÏë0ÐããÃ@ï^r}úté-5™¶ÛGÝTøï¼0¨×n@8\­Bµ5h#·0öꈒ8 9Áá`¤$$0€A’$g‘D€»‘‡nÁmî]ÊÔF…#BAB á,BÌɦŠH¹W¯`®J9ßj ¡ÃÑ® ÛjÛˆ]'R·õ‚»;U¤ ™¦û‡‡ÝînµÐÚ¸öÄ„l;s@!xœr)ɬµ…ZóÐîÈf&IáM4 h‡Ì2–2—np€&¡µR!0(‘H‡Ü‘”¬Vû@É¡Ln,)º.ŒzÊm„j€ÜŒ!DAF!.=ˆÙç9·ÖžOe’µ1R`mH#±€ÈÂÉ6M»çT°Œí5Ð1Èëm«xÉTÊ”„Ûê ¾ØWÚ»IND´2¡MWÒDN,®§4:GðŠ1¤Me×"²G.$‰á¡«¶UMi{<»‡ÅFéÝÖY›¾«‹AÖ®ÌrUO¹¤ˆ.fÅbž†1ç|©MÃ[Àú …7 –Pã½Öf¯Ñ7úÎkÆîCk;çÌ‘ É¡Ðá!ÅC¡‡“ƒMŒY¹ßºÄލ@3ž™×`íz$¢ŒaÂ~ŸÊ$AÕ¬§¶[J>b7Ón¥Xù…b&<;*u eg5 ¥@¨mž ¢^ôÄ«ûäµ"yÝH\vn5"G/b\B:ž&%æÞ÷àLƒ£KeLQÕ‚°- ÁÜï]LßµùgH°m30Î ‡ °®òÛzçt\ï*EP0^%^¯kCH‰|MÓŽžÍ`Bü›ÅÀÏVF¿½úù/ýl]t…ËE¿º ÜnÀ·7}cÚ×щ™·=ÌÍÃó&´ÌüË™/;¼\N`ÈaèÑ-ýç›w#œ·]ÿ­Š‹®j{ó‰ü:öæ›÷´÷ÙDÔÍò—M.Íëÿî‘PýZ¦mùÆ€E0â¶ù(üMëå`Á•$úÕ*ì×vbAò-p37ËÊv è5ØéuGñKöúWÝìÛÅ€æhöTçï.Çù‹ùtT[r f „¹"̽¹V×§ó¼Æûña?ž†ÚX Sw"uTÓ…lñ¦Þ'Ó°¤|õŸ€á÷ûýÝ®9!>½|>Îó72Ýù`Âkp5«ËŒ@¨†°“( $AXL\<¼"sòn&“°»«ú iãEplŠAhØu½ãd°›ÔT=¥Ž Ê,n<¤ÖLDrÎ)%U5Ûþúëù5»žÃv¹1Ùö! D„%a®õ²Z—ßb›ù€CÛ$Äb70Eϱ`üºêõö5¸{ÒQI‰A7a@êmPŸ]J@ÐçDؼÂD‰¸ßÞ^=„¿Š°º Ò2Kc¿“·3¹‡Ç_PÍýçøˆÞJnÕg[…ÛWê®dm^çãûw‡/_ž?}9ÿøãüü¤a´Íµú§Ÿ¾|Z^Ú|ž¿\HöùøÒ,_–%= Ó0B8ÓXöcÕs´.Õ0†Œñ>í?”>ý02ŸN'´êã˜Ê˜yâÈt9Õf€`ñáÛÇøïŸs~zz>Ÿ//'oѱz(D—ֻǴ{§qlrQj§ÓÓË3.ψ:1Föæfÿ»oßx¬|þôü¯Ok£qlŸ|869]–HIRˆL)øów֞ϟÀÓŒ¿?Aän?øçúrnX…1 Çdóe^1NÀ qä„“„ÜwÓ»éóçÏ/ǧv©AX×øé‡Oœét:©Õù§ã—QŸ‘Lï¦O¥ìœ×»wÃxW†il-¦kmURŽñP„§Ä!×͈֬9¼ÿ;¼ÿ0-Ër:†°TöË岪ÖUC#SJæõÅžÿÍGmÇÄV¦2ìvEJ "o~içççãüdÔK³ÅBD/^Oê3$DÓîð~÷½-ºžŽm¥½M4FÓÅØÖÜÜíôò”¾ùæ‹ðÃã‡D|<þ< ϧ£¨µE^NÏîáaý9EèÁä=/~cküë§z’rÕÐsÎCÈÔ·U™Ü›C+a[j|˜• ÌÔÜA f2÷Ý~‚ ïvÌšy3 *÷€ŠNL ÌÔ©> °Pg¿"R0{žè·V†4máê¡ «@­rðW‰æÌÝÚYoÆ›0LPJîBÆËb§—õ2W„ ’{ŸU¹»GSä`ÈþnLCb¸š™*\˜Ø%Á„¨;* Ñ"…ÒÐgM²ÄDd*ÑíÞnW;5³HøU$,̆^oƒÌ½©cf"Vu3…k„˜PUƒ±ˆ÷ #rDœ—óÿøÓÿ¸¿¿7v ‚ð.5ØÌ€_MÜtóC" ¬À·BÚÌ"įpsâ”RNœ{9,ذˆ° ï{ Ú;™-ÿ7AR’Ä „‰eL’%Eïžâ®ô߬ þšs›}b«ò#Ü­ó¥âª…È"YÒ0´Pá¡'¬J¡ œe›O_ =ä%È_Ë/ax·®DW"QPöØ@Tx˜Xö nž.¢®5t+XÂ<ÒÀäJÆf2x!Dæ”%djæ]NCtï’kä9ÒчSŒ•U©†~ Ÿ•18ÈûS+©‚¸£%¯Š^jú¦*¼m°Õ‡7!Ó† ÛògÿêÞ¤I²$»Ò;÷^Õ7˜™‘YYY €&¤AvS¸!WÜñsÁ%÷-ØBY•SdÆàîföÕ;p¡ÏÜ="# HH·Hw,C|2³÷žÞáœï Þ€ @ J„´¥!<¶tÌxæSßNÕVK 4Àš·éC¸‘_¦Â±Õ*áÎL©áÙ„ Û·ñ&ö#xs"ù£\Š ©ýðÙ¦­m#^²ÐÇQwëÜíÙðó±ÈnÔæ¸lÌžV—'¤ýš‰)ý¢üògG©Ô5½O‚´ ÒvÛ#Å68 'Ø7lŠ_Ú¡”/O¼G;û¥ëz cÃ@Û{{Ax;¼!NÔö3|Á ¶ =þÿåuµ¨¸í4ØÞjÁ‹:¹o¿H‰¾A[f]@ óÆê‹Ëâ9+•§–jÛEHÛ>¿&‹k}Ñu0‘Óæg£¸ð¶Û²Z/“ƒíw=…I]ìhHôúÍz~ô±&K º˜H¥=ØŸ‘ÜéÂc K CKWkÏ;›‚œ˜âÎz¸E£m‰vx‰ ÜÆMeÐbĘ‚ɉ›ùϰæþ««æ>ÉšûÕª9Fîr¥á9çfàV«9÷€/Ër<êºbß)÷‹1õZW=¯lÝw‡›ßt×2ÓŸÖwS„ÔR¦¹˜ˆ»®ZmÅXvCº½=|ñåË/¿zyªë«ßÜÞ½˜ôÍ$"××7û/Æ4Êáp­dçéÁàœ0 y¿%ó4Iê™S,k=/g„Ϋ.uÙ FêTàÃm÷7÷â‹?\÷‡å»Ÿ¾ÿîó?ÎX¹ÛvWIfÕòæÍ› Ÿãþn=½úËôïþão_äàõ‡7ßÏLJ·ËUzµÖÚÃj5Aò ä„x±ûíîÅõþæºÂ‚ýâƒ[ÞÌÝÃØÉ„E(B4B•RSÙµÕPǦ¥6øiiTd´©ò.G9_†»MÔÂe[/ÍÔPÚŸœl>·¬lSد<~{Þùvw}P“µÖ›.úOÿ^оx3 P4Ý[Ð'–Zí~mÅÙÓDÝ뢆z^–ED°oÜ;ŸòZ9Î]¬Œ0ë…Iò,âZ2a$$ɦÜ'(›‚ªYq%’”òy=r]“j/¼O|;ŽƒÝ¤Û~š:ˆ ¤F‹3Q1s­FD"ÎTÝT)1äF A”ƒB#Ôƒ)‘‘™o´{G3ô&$Q‹–$.ÄÔhU[k¾2\Ž×–Ð#žÀ…ñ)UJ\Hˆíâ`7ÓðdL0¸G¸õIܬªÂ£ci4z"^Õ »IS‘# Ñg‰FÃMcÜ®ƒjÖ¥”7õ5j"3ÇãÎÐã#‘c››i„Ð&Ö0"ˆ›‡µÅÁ¹‰0>HFSxU¸ ·«ÙS®t´ØŽÏ1Ü>CÁþÜÄæsÛÏ}ýG3òø…™îSwH|dddFÕй" I̬›V¼y_—o>>< g »þt<ë:E–²¬ßþó7·¿ûÊ4N§å«ýî9sÞ“ìw‡> w?Ÿß¾ÿ“¼<ä,)Q·‹Á(4æYÏçó²,¥h€îï˲t×ÙÇ£eä]°üö·¿ûö»u.³*þøÇ?¦#â<-?½y3­°ÚZ—R ¸§¥.9¡Òõø-/ÿ¢ÿÿëpý¥üÍÝ—ÿ×ÿùÇïÿ c ï³ ûP‹z¯_ÿ¸à¸{…›››ÛÛÛë—=¤ÜŸî¿ù懟¿‡ßKÅÝù.¼_KÁw0ÂOßž¾¢½Úqª§ûãýí=å÷ép=„—W¯ºãOÝùz,§y)pG"NBZ¦7ï òе¿J/výÝýñê*¯k-˜ Óö}×ïÓzžîÏ!R­NVi9?×ĸ¹º.ëƒùò×û?Ø‹7'{Èt{|ÀÏïß®®ÝOÅÓžþðwFô/ƹÈ?üß¿û?ýãC0¼’,ÄH˜ßb™íýŒ$8P_NQ­¬2Ckp¦Nb^pŽ©£ÎEçó `—Óùn2‡©¬‹O§ŒIeÑׯn^¥_¿è÷}…v_|ñpzÈÝ:îÒ<ÏUm]òZÎûaÒÛ‡ÓZ1œÎ§~=oJðVu>–Ìñ«:"³3†agæ)ÉaÜ™Å2Û(îDàž‰ Â“6Õ²z5-àÜk™…ªº7°6´†iåˆÇ“ÚÝ- ÂI,·r6 B`¤ñÖÈw¹ë˜sÕòðð Z\ËÇ$ÄNŽœŸ´‰p³é[­0ÛÄuD”RNcη¢…îîïw»´@«¯,i£;äÕï¾ìs>ϧûûwÈŒ”` u&c¯óÙPäš#¼˜^_ÝÔZO§zñ²·±Ì«º!»ˆz5ƒtâ°†7uĸßE]«M+‚s?fÎfNˆh鉎àœÁl±âKë1ÌÂkœ0­ªB}'ûë·oß¶Ÿ¿ßïOZ*æŒûÜwÉÝu-„R—z…Y)p¢$>-`ò<ð œbbN"É‚BÍÌ–¢ÌÜu]7df:Õ)ÜDˆu]‚Ö4àˆ¨¥^FN;w€Aã8¤¢cN×9sÍ„ÌDn˲XxK°³ˆ”ròD@ÏÙ)øürqån- ÜhÞVn7„¹šÕÀHœÁM|YU–ix"gªÕªƒE$1!U£)¾8ˆ¨”šu’1…‡U«Q«3qôCÊ·9¿Èé·}þ‹<¿ˆjç”/1Ö(裣HóyN§r;Ü.‹ýøæ8ßaìv(eíÇä”dònÄ\÷Éd.|GrÖÞ)MÓº&O£”0#hÛé^ܾìׇy9γ¿óÞ"îîîß{­H‚¶D¹'¦È}Óº˜±)O&'bØÛ_]ïþò÷üÝ—Ž©·µërêú•ƒÚ]§<£[:Ic7Œ©Ÿ´’r™1±Ñ’) Q‚!¦öð^¥{¸¶wø»ÿ×óýén©e]W`Õ2!*2q&JÑ2 3ID®y—§Š”sF–¾©Òû|S9Ã""éA¹X=ž*÷¨ŽÔ#wØíéªçÃ5 ¿¿>„Ôyg¨W¯Æ¸?W_!(Q§åL©°yÌ‹><Ø<£3d—.ºŽÁž(û@ÏÕæ±“ƒÂ<#% CŸs¿ß)–9÷‰™UužJ)è9’P­úp÷Ð[Ë2/ç<Èn”èC•R U=¥4ŒÝ0$¢u]—ðJ EëZ«’1ŽÐ@Öóæ2§fãe&GüÚ c3Suq^çe™V¶Éa¦qØnlfÕÌÝÁ$)%Iu1‡“€ˆ,¶”òIJ®[GTkms·@18-¾™hZá0gj‚«¶»h€i8Á5j-̒sžÎGxAeâIY¾)ò.“ÞlFè$[ø¦¥ ‚pî»Üïô–3¼IŠ8„`‰9ÁS ñVláNP ðÖ~aCÀ]\0ôK_"ÀDF[.¬Dk;Žp†GEX8 Í{Ój6ñøå‹ ŠÝ‚¢yÓZxç&õ§§×÷1w—~Ñ­ü—”žà±÷ü„7ó3cÖG<7.™Eñ\åµ}nþ‹ÕÓŸ×>78íÏ›æ-‚‰7ÈÛ†z³ ìÌ ™àŸê—iŸ›¬}®Žú6ÞÖMùE—ûocL4ÖÉExt±¡?!|¤ôÁ&vý¢ÀÏ‹¼í»âÏÓÿÌçk)Ä]ÆVE¸)Ág÷ý‹[¯4"Ôe·RÕ|^™öýè”Y¬Z}_ʹԷ ËuwÝÐKaÙXˆ;I‡ŽÅP­æZ‹Ùê^_ݼZÖs}8?œ§¨{¢ß}õE¯ƒ˜pwEÚç]/Sð¹Î1öýZJ€ŒC&ÎàùÝû~HÚn?‚ÈÄ)±5upx¢à!eN2t¥Ô1³J˵Ø8Ô„ýþàBjÖ°ÝVjDÓæÔÛ^í™,Â̵3k³ªF¢kkÒ2æ-y—¶Á¹‰Èc"Ç&ç.€ óMĈ@ƒ‚“$w«æJAÎ$ÒF íFhl“M¢~õáiÌm'úñ&9ƒšó¢ã&|’(_’±˜mấ{·ü‘–ÄFɳ™Ü¸­1afGôk;–_{gþ—úùîh8µÖZ­/Õ—Õ¾þýW]ê)®ßþ°Nçì§#XÓ0¾úòöôíñtïÓMoÓ}©Å&SЙN»Ãáêê&eÒºž¦òæõ#Þ¿C)  ï%KÏM!@9A®¡“.‹.Ncß9ú}¾Ùå%¡+…VQî½¢pîúAÂòl§ºVÔ$Þs)>1Wô ÉÈ TÓZáVÇ+!äTÇ:•eÖãÛyåözøý×_}ÿæÛy^zýjÐ¥.÷ï.sM&ÔõÛ•Uj¬§9éü?ÿõ¿›M†YÆ~ó±ÛSI$”Rw¦)\µx)Á«Žë»ó´83‰÷ã2‹<,F$¹ÏƒVç„›;‡ÏuH>ŸÊ·ßü8îº~Øß¿[îÞÚý[øŒPPÔÙ‘Á’„º.FI»ÝØõ½Êz²ƒÍ6AŽ1¥0ap 7õ3N® a‚á¡n >nÇà¦p³¦Þh~ÉÝ\­Eì·`€Ý›2rëv™é| ˜Y"‘tÁ…Y¨“p¸5ÇÛVD1s!£P– À…è2Ã'¥V5µr­ånæ¥p aPfqG$㸖ãèuT9H;O"¨Î¥É*Y±õdç2Iɨž% ‰M|µ™)PÔuM™C”»…öSìWåâ^°»Þ€¡D×Ðp†s<¹{écVSË}ܯð&§Û¨t-W½$¥€E›“‚` ¨mC,ÄÚnÐHüÍ:Å›>Ü/ÔÅ‹hM‘cáD°öVQ¸i€,˜!òæc<7+!@Í‘oÍ‚vÃK“æ_v`ÏÎè–DŸceãÑÕM—¤Íi6Á ýº ì'Ÿ·ŸL,ý|®ÎF¤§Í´óEŸý{.Ú·­Ã  ­!]ø[Ñ<íÃnðd òØØb¸„}m®™ üÙ_øô"èrÑü+Ðäìë(Âbs¡]ÚóæbDø#ìR·G÷Gdàωz­Ý fË Ûªx„X\ BŸä‹ãùŸÝÎ"$…Ÿ¿£ˆ0œÂɪ“‡ ×Þ##(”ÖÙæ©T;¿™§9Ýv»d†5:ó!%éÇÁˆÕ¡ìŠêD”Yê²ÚZS?Ü »éx÷Ã?}[ÞÝè:Rî¤8sÑiìÅEËúPN…(R7¯“Îë.uÎÓ~w›…IÝjû$Ø™ØLÝ‘Ÿð× `¤¾ëAÙ]Ý̬º©E ¤àFƸ¤ s©V][P¸;¡…cT% $‘Ð´ÄÆ% ÁXÊÊDn0%7ÐÂADâ0¸€n„–"ĦÔqDâÖRoN¡ ÷•Ô =< ªMšNÄ„$âjàOÐç#Nç¾e»á™‚ûY„IDÚº Íjw©v83EØ%çÊ/wµ½á×ïˆþÛúGÑp‰!Äá4ÏëÛ·Õäþwõ¥ôƒxO¹K䔯nö_¼¼úé]o•¨jÔªî×7òå_¼ò«á|ö×ÿø~ž¦†]¦Hq5Žï§pR²µ ›ç°ïÞ¼;Înìȇk2wˆ@Tø¬˽ät8ìTÍV²‚ã]A B‘2Rêº.1­Í"Y† R­wçúÏúéå>”å:•åû^ouyÀù„TÓgõe¿g–ÕΕl9®o¾}S¦½z-2Äá··Û5ŸëÑ—Õíê‹CcÞA†õ´„Ô2x9ÎÇ»c9ãÝúp|3•I£‚ HcŸ3R[ÖZ ÅñŸþßD‚:ãýûðbWú8ti†$‘%ªP­ÎKÁp¹K¹£ýÕ¾b1Íøþ‡oûȼϘÏ,¼ïH ñ~ìÎwËÿ÷ÿ|#‰^¾øÍñÞc¯È‚´‚ɽIÔsÙ¼ïdì’MÅ–I$ÐçY §RÊñ¸ž ×>îwP×eM"ÃÐïw;0Mu>ÎAé YrŸÒÈ¡¬N.”ü"ÍêwûW7ûë²{û–îïßµš“\Ýî_ì¾âؽîî—éÇ®›ÖpÒ†ºÚÐL¿j"ÀA‡OS4pË4÷=úœ‘Yt]kqwµ2ô£›©Wß$ú¦Žd–rŠˆpr5g€,(J¹$ÆA¶’…·)P“Ü»·˜MÀô}×u"Me Ë:E¸ä ˆ4n °í$ÉsÅücRÝàŽ$ý0 ðÁ—‘ad(5ª6çò¦?Ìý0$idˆÖ ÔZã"Ò"¿<ÁŽ0ç¶ÞG­`äÜ#¸k^M¨B$= ;™A-™–AÂBÒ¸lÌIRPÔ!¢ª´%m¶ÒÝ›ÛÇŠgæÐêЖ*‘»4º»¹k(,ÀîÄ"p“MÎià@]êcû: ‚k‹%‡€Â#Ì ×T5¶¹À¦VÂÉ,`†Æ¬ 2lWqp´Ä¤Í—Ùè@õQ+̆9;w$ ÔâS+©2” ä€‘‚ÌI6¤ï£qÿgÈeºÜ«nïRB˜˜9e&x¨£Â+£rX@â঎ § %b“´)©ØƒáÂ’™;&t;¢›tºªq%ü"ÓM¦äÆ&(%à} £­ë›wï–ûª§ó(‡Ý¤e]ÑuàN˜^Ífó£å{Žlª¾„O™\‚„†”ÑrˆFž)ȃë“e‚·ø =øŸ:@Pc'?"õ‚çæŠ#戶ùQ¸8”¢ ^›½à"@!,ÚŽ:žÑf/AôÍÕä ‚„ˆj¸ºy€/Þ’¡`j¡6fN¦ x ÕñKà´Ô$¹ñ,è"ß`ÀøO>œþå þ9kÃÿš5B|Öù¿\³<ñ©éí.­·‡oPÄ¿jb»u†-ùö[Œí}n­.^ˆí=5ÉÓŸøa ¿øããÑ ôÉT’OüI¶§‡o„qާíÙ£¡‚žÇëzýTmÏkPúðíº$+<}yåÍ/·5EÛ üu~uB è Ì„艳tƒðZ ›FÃú ÞgZ‰ëÛ·”:tCJ]ª‘דօ‚‰-L’׎^%'ö°l#¨€XD:'ö œû7¯ÐÝÛ×oçâáÛkºí²²êbã~ŸÇ½¨—Óƒy(‰Ì˜Ë¼øzØ _ì^2KcÉ 3­jÈB&ŠS)J$†°äÄ)³!¤ 3ݧy­ó´”5¥L9ÖCˆ!’3 Ú˜®[ÆÎæÒÙ&ª­ù±íÈ‘ÄI¤±ã­F€¼õÞöð¼ :ƒX¸]A—uL;Šœ`õvms;V½õKNàð-ú}‹P…4œ.óbä»ЇJ›æÃ¯k#› ®á4£M™6Ãl = fSK—,ãçl7ø¿aGô9vÖç ¿_ËÚúãîs»#Ì/ Áµú¼ø®Êwß¿&"«Ã»7Ë›û·J>^ÉþºÛ ½Ú §¥Lõ½d~ñåÍßüû¿é¾¸ùö»÷ï¾›N>Q@B¬ÔzžËà ÀÅyLågw‚t!ùU¬¢z€ BuR¬þz¿ͬÖ@YÚ…w„BWK¤áp+µøË_õý¸w}{²i™ÿá–ó¼üýÍ»›|ûí^Þý@uö°ªê±Ä¢HÝ4—Ê‚«›œ"¿þæÝú©=SvýA¤[\ šsƵ¾×Eí=‰J^3¹®§éឦ7§å<Ð.”Owçó)p{‹<R×%»yaœ’ñÿûÿñ¿)Õ‡ûéîítzóÝÝ[KëýØ›ŒY"û¾ò®èx=v‡Ýá|ŠnXÕDd=ôä³à|ÄwĸTê|†VtÙ¦ãBŸ=m‡žmPˆÄLB3.¸{X„ÂÝŒ¨¶°T¸#xS£´Ïƒ·-é2@ÅEËÊíÙ°9Íî³1µ‰d¡tñx4‰Káv°ƒƒíRê>~ù†É &ãSqœ üÛ"âBo§x†Êx\¡5®~Ý”üb€ùE‡ôɇ7†ù‡µ—[´¡{[éøf˾¸>U‰|¨ g¿ˆlÛчïÊódÒ§ÉsÙ߇»¬_ô]—·š?gÕþEŒ7×…¤ÇÏ  íox˜)!±¡Û¤¥Åè>Ö-¼ÍÂZÎö£Ç(¨Ç×ùkãwvî Æ‰B<Ø=Ø0'–ÝØÃc¬>í´Žä™j&™Îguêºi< y^jéf«e ŽØ%—!['Ê´–ªjjTáÙ€¨KéË/sÿî§¹Öi^LÈÂ<ö7÷‡á7W²RŒÝÃÛsÞﯾøíí8ÿô§·¯_Ÿêš¯ÇžövœNq±üJæ-GŽÈ…$uìŠ$‰É=¡Ï”sbL¡æ€ˆ }OD«¹Ÿe›œÖkQÜ £èú¡ñ?¹(|Û#@í°ovëšRê˜Xˆ-ÜÔ¬ª«ED—rféX¶¥7#‹ˆÈ¢•ŒûHÃA XM”¸%ô¢êÕQX(8(µìqâ1/ I+Gˆ¢I‚— +ú¨_`ò l´©à¢¥òcWµØ:k{ÝØIAh­TiÃ÷4m7ñjûÍÿ®C­PSæFÅÕÕõ_þÕ«i¾;NLJ»úpWï¨#]mz¸¯^Ön7 æ”ãöË?¾;¥®O©Ó³©Ö¢ñ&~ŠÚ§.wû~x‘J]æSÔ ì†[xTEĪT™‘ ¶"÷ï¢N“}ưëçu¥„P#\c /¥hÅ0ôý˜út=œÖ٠߃ŸÜqzã:”*õâ)`¸?×µà°ÇÕáp=^N§»»“Yt]—:*ĘOó2O+'é®:¹ ž£LZê¯TëýÝršÏ4€¼úòºTAádç Ûu/VÊ!TL}™Ã–~àëWãîU—Gá®JzhhuCß½»C§×WÔw²»N_ýáæ‹ßýædúúÝÃ?ßÍS êÁ9÷æÓü€´C9Á ܰèñ|³)Ó ï¡7ÑÝä+ß×5ÊÆ T‡W¬á!–’Æ÷o¤°´ØøêÅííÍËa­AoÞήÖùpØúp IDAT NÇyž5¢OT´œ¦ãn·K}ê=÷ã@çuªL‰-¬Ó<÷;f6ó×?þüÝz–ä7×ãõÍ.ç."N§:Ow:Óõ~=Ó4•ªƒDË6l‰ÝáñëDóM2%‚”RΙS"Jddj¥,µ¬àJ‚pÊŒäêáAÄ""!&YD¤1Í înP¯áäª-È,.…“{›äøsQø8à »€šY)+TAŽœˆ;_g0ovß ×Ç1G³—l´¹d¬1 ãØ÷=%‰ê/µž)؉`§Ð›@b…šªNÓ¤ë$‰û>‹´‡\bn ‰G„©XT´?ÛÔçÜW-U«p–!UuQÉ933%êÖòÅ%g)7·-«^ÃÔ™R—³[æð»ÙâY+ÈúLÿJUü'd~AtIÉþl?öÑî…ÛîçÃÈOªÂ œ>³#z¾'yŠ\#ð%í_ùZÂ?ݹý"­dkBÿŒçù÷>.îñΌÔt«Š´ÍÕ>TÍ}ÀþÅ´:žÐê|ö]ý7YÉ$ÀRˆ³99e£¤Õ„¨7í´ìÌ÷=L¨À_^¿TõžêU’Axu¦œáTÓXHV »ñåa¿Ï#ó»îʼ¬ˆy×Ex< wôÃZÊi);É}·“#~ñûßæßdÅòÜMÓ)J–Ú_Ýì¿~¹>¼>»þöËÃÕ×_NoÞŸ~xóúýÛÛî–ÁD¤ÔÔËÌMËZÜ)ˆXtS øÊ1¯Õ¹™‚4˜RJmóÆ«€9<ˆ$ ÁtKÚœ3¨*bU‡-Éakœñhq®¥”ÖжÕPÓ°Ibxì‰Cÿ ’éAžˆ Þ´ÚŽð „Gká%ІCMq/ÂDeî.n;~i(Ú\“ññå·5ó›Ö¿¥l]2½?*owsäݹa>âßä#úoˆ¬ IóçPιZ1¥Ýþú¯ÿð·ß|ÿ÷ÇyZË´(ÁK-§»ŽSYæH¸1 ç‡?ýø§å~xý}1†‘ŽsÔ`Ætï½(RÞ]ïv¯†i:•õÎ2Èþ /g?×Z=”RŒ;ìjWT‡ä§¹¥Ac7쮯o„Ž)¥Óé4Ž1:rFh<ô…#¥äŽRJŽ~·ÛqtA˜–ùt>ö»ÑÖrœ æa×ß¾¼‰„‡³ÏZàÆ‡£±ðuž§éê㪦«NÓÔž8Ë‚÷úÞJ>/5ˆ¢•rñì€ô_)øxÜ3¤Ô‰d–Ü–¦îîVàD¹æ\Í"£÷l˜ëmhchG‘?šîQuó€´ßÑD5Ž@HJ­ z”¾pD@û¡[ª6f%ˆs&"¢²Î—³ßÃ@f¦LªÆåm©›ÑžÝ¹ïº®3³éááx>y)ÈbvK/"+DE“AË4E((ˆÄ=j5É=HˆYÒ"è-ˆŒØúAæÕDH›÷&'0¯k­®cßç!a­ÛL·-¤Cƒ[„N0…Óötff'ok¯Ôå²Ö§sÝ/ùLðª¾ñî¨\f« œ…˜`¨pN§š5Ü»®K`yß×Z)„7§h¨*8qpf!'CP´ºÖñÌQÍ—üq¢`wO)‰T¶ª®$(·µ«4»”»£é5B,w[ËìîÖ¼FLfgæ Ž€ =bè©¶ÙÔf¾í,ZŸB¶8=¶fi x *a83ZêÒÆå ÝÌà eåÍï "y¶.`PfÊ’ú.Ò0C©¦qèvý)aµ²êê /@)¬è:{Y@šOïŽùŒäÈÂánì÷ä=åNDÈÝk5^-f³³¦•’"œV™± À$ÔÈa‹¢–´­îè)O“Šž‘ (¶àÅ .I”™ZËš¶)æ`âfÂcà‹#šüd#B‚Ÿ§”2>RØÓßÎ6 ÈV” "býnMÓÂ˧¼9›²?`7ö†; ý²‰I/×.P~–ìùg`Ÿý9„?ãÚÿÈMô(ûüšžã¡[;ô¸Ôû4sšð¼÷¹¼ÉæŸêOžƒ¹/ß{áÓ#bîqÝ´mÌ÷h 4| yø<‹¯ÙÜ.—_örñì:io2ãÉÔè®Ý¿Ôn=oÑ (§ùÚsÇ+ï™!êéÚˆÏ4±íÙ*mû"õÈÛŽ|Ïy'ùÝt–.  ë®{It3Šuµ¸»³Y°k>¯8\÷Ä©ëÖ~âBeÄ"¿á6ðL¸²ÎbëÉ£©^èé–çKf ¨šY¥PÐ÷d…µld¦®Kë²®eEðÕáÁfÞžF"ˆÕ´ë‰JF…ewŽºÜýtšê?ÿøÍŸrŸw& ÷­ÕB#"Æ~÷âêV"½£“º¥> 1¶¨ôÔÉÐíÐÛàQRòT–qÌ"t{½ys“‘º® ÅÍÍa5ÎeÖ²’‚ )@ØÂÉ^|qóêëWÝÿ4ýh'3¢1ÉEIÓHÔ÷©Ô4ŒÓ´,g}x8ÛÂ)²M>¿Gߨ!î ‘à rdy¨FíSN /ØgpH§yYj*”¸;ϘޟkOi—$‰£æ]'ýNòÞjgưnLþâ¦sø÷ýNJfV)Q­Oý\õ<.Ü-Ãf8\ÞüúÍl¥žÌ'ã î$ܹMçã8žgn®†«Ã6ç»I\ÄäÐ ÖÏì=u”7Ýæã¥,lÈ|_sÉÞùwµ¢j©Õ¢Zˆ«\˜‚¥.÷Ý0t‘°-µpß³»yäiY=܇¡'¢€…·BŒÕÚxŠžÒÙŸô ÒÒo|ÉNø|>ªÍQ -‹ÔIMÃ]òÀ»š…¡Å„˜jdN)s'ÁáðbnHIRBò¹Îwq:Aºn· ®,”„Tóf×;x]þ<­2p±A;àNŒH{\†U|‚„ pr$á €y4O­=ÀsúZóžð%Ý@AìÄm:Lq!ðª¬ä ObâxI\X åQÿ¬v¨ÁºceÀ|?’èEå}Yßi\‹Õß3=[qПõ~".ÿs„øsÝÚoè`å?0xѶÑ*1mëO~m—ëÓòfÕ+^û±Ö”qá}1Âý2z½è0¿½hŸõ{‰O?  ¿øbãg ñKÒÃ÷Àä*ç«M¿Ë‚ C/¯9¿}I|XSªÖY‚®Q´:Swu8ܼùçó\Y¦àɧі¥à<×Èc”£Ís]úÈ)uæ ì…²ta:KrHP‘dðwÿûþaئáôáá|?ÞÇÙÓ(ýQîKÑ´JØý|ªØe¾jY.ÂB&§pWµIç«ÍÀ x -™pN)uTmÇeésfJ9¥.ç®ë ¥.jê\/ŒÓ H¸†“yÎ’ÈÝ=Ηt.1Õ²pÊÁlVÛÜ“EAÌ0ÈIÃ=<œüÒË®ƒŸÞMB‡EÄjXe"°º5WhãÖ† —ÜY„4åf4}? “]*(!Øj7‰hh±L q4Ýq½\ªÒú@¸·07&´”¬ÿf 犖®8±Â+Q@Ðh°Rübª¹ŸÛùüX‡óÕ÷~D‡{@:öxþØï6ÔÉÇÀ*±¼y=”óœ¾;úõ«¯öÃnûêðîöïôqÏóònsøøûã×ÿ°x:ªâЕa×ËëÝñƒùŒëÃÕÃtžæy~XŽ8ß={trˆ÷·…'N¡S=º†áêpÝõnÌÉk-ËŒMúN7\§e™$¬Ño6]è MâÅçìsåšRλ×b©^ÅX7åÄw‡üfŸ®ÇÓ2=|DÎû]AyØFîˆëé8û8úä]€¦¶)t#xBf$”¬À4-çÛG[†4úNêòC?¼?Ã>0žQŒ©¦è>{ûú‹_í«Oß¼ÿÃwå~ùxýÄww·§ûÇûc½évÛùT¢8«,è‡k||7þíÿùû±è?ýã‡ó7‘PF,S [-ó¢“ÎE‡!ÃpwúØÝÔßþ¯¿þÿÛo¿úíõññöÿøßoÿîÿZ~ÿ÷K½½ßEŸ­·Ç´÷' hG¼ã~ yš¾ÃÛdÅ›Ãõo?#Ä?þÝî§cˆ˜£ËýÐï–ÑœR¼?i!õ¡žºˆðîÃÔÛô׿½¹þÝëøw,ón;¼~susµ3«÷Ó8{™Q±ßàÕæêÐí¬zö\>,Ó4y¡½o…‡½ìûŽGÑD£Ì!Ô,èÆ”²[ý1•Åøè ¨: Ä‘@°Zá,½t™¹.U§‚²ÌðÜwBd¦t)¹»ÎyðÕ6…a¦¤mv“,B#(Ü[a I&f6˜jA)`–m¿í;[ ŽL²nǃÂÁæ-ôâI Jèº,]Ö0Ï$»¤\‹NâM—¥Ðét,w#fOi+Êˇcþl·ÔqÏÈ䥆2-óøsÞl¤µê\GÎfçP7bf$……¢N÷›ë+"ªç3¶²Ù&+'?Ÿò͵»¾~û†nðûø²ÛßÔSY¼0r‚ë B%ó¹ö›Ý2Ž%f0O}wÏçÞÏ%eôb…—î›x†‹zñÕŸÎAV1]TšmHG÷yáÑ¢›ã…æ0,Ü&üÍLòäø‘6M³ ­{݆Æ%¼È/*»?âÝ=O™ú¾ÏœžÇ(½\3F(Õº- Þùò†è‹.áYKù¼—Ïz|t£þ|ƒ¤JcQ$®¤ãµV Ëiñ|R>îÿt>ÅÕîýqB×ín穞;›†è‚Õ§.õyÓMEo§Ç·Ãv›s=/å´¿¾â7[ÖcýÛû;ëz)ú–oûã]½-ënxýÙ›í«7c-ß|ü6L·’Ò«yг¡¢CÎ!^½Ç²MÝ|™m±Ræ98ƒÁ"laÇéÁÕ˜eÓm´V‹ÒIêr×7’¸C63‡!˜ÜZø,˜$%!"˜ …;5“c4„³µQ] I¶ 5kŽ” W8Q‹ê¶ËÒr% ¶5vu#"Y‘d0¸U" ˆ($p!vGŠyFôàµmº‰´z’ÖÍ­GËÃAX“\'ˆˆ`3:&!F8 Z EíEøb@A•¼ ¥J¤ S'†pú¥:œï]ÓN¡­e„G µiZ>~¸»¹yu:ßÖyI „L±ÌS°ÛöžJõÅêTD¼t…µÛ'{8Öëkl‡\æ¹\¿¹âš§²á<Õwx_Šîv›ÍMÿøøÀS™ÄàŠTÔ2²[‡¼írÍDÅÓŒãññ|V VÐyùXDbYf-‹/9‚|‚#Ƈøðþ¾{ÛW™ûš÷ºÿL|®s-‹Ù¢âsˆh……OóbË\êl±8)1(»¹ Aà%Ø«QÆÛÊ ®)“F¤w)e f„M£š%–äÞg Ã~xóê°ßv½@©2Ÿu<Û< ß–ùŸ¢:Á‰Õ}Ö@5¯µz f¼{øÞ½þ8*øáV§{‹¤X¦åhlU—eé%ý6÷CIç~GWŸo¶Ÿ…÷:ßa? Wè·°;DÍP8¨K}¾éÓMçâŽûX¦´`“ûCÞgé–:*Œ‡Ôï·o¿8,³ãñ|4M·)s…yŸ{×X&sBÐ (º|xø8z¹‘©ß’Óy™Ý–`%²Ý–ö®6‡}Î>ëtËú("!]ÎUá54ÅB‰hÛ#"–©gÊ’39\áJµª'Bç1'\ ¦·VÁ`!»ôÎcÑìØ;N§„Ý&³™00€WáPÛ64i`ø…¦`á!ôŒ@«,3eóÆ p‚‚ªFR¸5ê0  8ÁÙ H­§=½`ƒ-µ²z¦á!ÉU¢7»n-|ðåŠëu·qîíÄK±ŠªdÈ‘{Þô© e/ó‚Ç6a©³;;ÄŽPª$‹ ‹tÓsÂãô ¥NªEÁ‚žÙ»Î;9-J¾r)8ŽÐ?’¯…]Û»2‚Lp'ø>¥ÄÂތɧ’J°UnµKnx†hȧ†svYDǧD"‹'tr‹’ “ðDèÀ9"àpsie{ œ‡ÃÁja怓7e4gü ui)5Oj´'´þZaÐsåÆëLÏThÜ:7Â'õ`üBµÆÓëüéûgMlŸ-vž‰úV½}/çûú±—y£?-Þû·-Lþøƒ¿øúìð­„·ZÓ}Ú×á…Æ›€p¬É­í/.ÏøØO@ÔÖÙ3ïÇ ÉøéUÏ¿õc‚¡=bq ê„; qï`Cñ-üÊiG‘æÈDÙy»ÉÅèÎî ;—zwß3ÝÛBž!B.œ†.o†Œ<H˜ø8p½é6»ƒ•ºÏ5…Ä,1#ØS¿ëXçåÝãðå¿úÍyt¿yWO³ ÛÉÑ×àÉ¢Ö2Îp/b®ê‘ÁÍÉè‰Q=؃7¹#RƒZD5¸ZEuÖîj—ÜÕCD¤%ø¨W–5XˆœÌܵZ@Rד-¹NÁÖÊ MyÝü§í¤5sOÄÕÂM¥èxú¶Má'|Tu4¬5.îžOË^¬±XÚî¦å]EpR‹<äà¶l†Ü ¶Øqòº^oâvÇÚ—ÛåL*ÈC¢ÅæáŠ™Â£É /ØD4ðf€ 0"%2¦J¨DÆÙÄüŸœ¬ÀÜþ 'œÏÓþðõW¿»bNÕƒ Ê=«×sA¿x%uLÄÓ2/Ë"=ØîQI”ºLÊ|æº( ¦ÉÆñtój&Ý0Ïð@U¨"±ÍËHØ‚`ö˜ÓÄ1TÃqZÆâì)Õãq ê;Ñi1IKbÖÅLw¸ý×q³ËCþ⦿êöõÄßÜËùîƒMTÆÅgßR–e©ªfÕ\N”8'’yœÁÄœXz"!TÕq¬9QCÝû÷I:É6ëñNëá rFänèkøétª6ÖE­b9…Öññý?°àj>#„#›Ïªýp-Ì]×ñ¦L_¿Çýfã’dÈ›ë(…éXǺUC5ÎPè9NÞa>–Óm™Æ)SbÝd®™Ž–5LœRwŠ%áIJ¸2hÓQ'iØt²c•åXŽ¥›·7Û·_~6äí7ß~x¸»»F"¤½t‡«éÇš™""Öï'N, A¢ä°bj ÄI€”ûÎÜÌj'N’ºÄQ-:j1¦´Û ª:ÇåᄼéE˜S$â "ó…¼Í¨k 5UÛúPcj.± S(HXºÔ‰¤prGÑhêFãchàÔGŒ»~Èád#}ç€Y$ÙåMÇ”‚,Åœãä‹T­ãt®uJI¡2HïAay.»<\súüðÊГëòÀ°/¯¯oæyþýݱיÊNfÓ(éö]ÞînÇêûnøêúlj4âC“ÝÃÜg]ì8)_ål.>.03•V߯hc]pšjNá(„rŠÙJð$I9gnD I)¥Ô0t+*Д™/äɕ׆$fö´‚}$xÖG|‚?²0^ÀÓŸgCýÀãyÙó„$}úatÉá‹ËF±µ7†Ð5l AÎ+ºnÅÆq‹HD¸3‘_hší¾@Í…9(„b¬;y0˜"ŸE´o6ƒ«”a€µ¤F&b¡ŸPÍýR;œï×O Q!D`Ðé_ÿþ›Ô­ ˆfºÝoØsU¿o-×°Øì†«îU—%…ûW¿þÕ¹œªtâåŽ"åmç¾Ùõìs9/:)–/¾¼.už§r~Œé 3Ìe"€RO›]ú\‡Å*J8 !g_ªÎ踲"*ú„]G÷`‚Ÿðø-×öÙën÷êŠ`ïÏßœo5 tAˆ+¢Ûq­J‰I=QG©“.!+—åÔI戨no®÷ºè¦©Çî »ƒçƒp9×R@.D#ÙµÚwwï¸j‹‡O¼€9P `®mÂé¹—ª³záÄÜõ¾,ãˆ]•ýÍa¿?ä~Ly>ŸŠN6ÅŠy«mŸRr–)=~œßO»’®yÀÂTÌÙ™”mË©ÚRižkÐq.¡áÖ÷ý«Ã^RÔ(ãøøP}׿>|õW_ÖÙߟ¿›Æ3ÐgÈývØu[›ªÖ¹*„ üö›;¿½ã u‡n—v™A»ÝÎÖnè£Z &˜qXbïTËö°ûö-"¿ÿöþî<Îó\«½<Ûñ¬`ðŸû¸Ši/²Ö,áÁ €E$#¹G˜G0çœ(±FX„_Òš pO)ÃÌ´V·Fséûæ}h:w†P…€S‹×tS¨¥”±æÀñª› p°jiöaE"ÔÃ뤅9` Í¾ßv“Ë63?¼UŸ°€£ÕØfæªÅÌÀ4 CÃæÔb”R¸Á±,eÓïº áŸuQðZu7K€ÕbtÉ×¼LèÉŸÚ¡KÉÓÜžŠÆæX‰5‹¸)µˆ)IBpÛ9³zD"c‰Ô‹ â[vº²²M–©†«…·v)Áó<óì›™?£Íg9—Á#ÏÚÍUÃÂ!ÈCÇäœw‡>Ř}Nä;öb¨PE%R†2 P¢¹ 4Æ-àï%m 04X ì¢ÜjF©Ð B&0)r#(€ÅŒ¨ ä[ƒÍ’N3DæàÚµ¦‰p,ȶôFSÊ¿¨ZÖáhp8Gt$œÁ‚(®m†ÜÈrëBï"NkQ‰ ~ñ‚‘–Õîê¦ñ œîþ<=ô…ú ò¼/²uµôŒyðg7F/«5ü žÍ¿~ëž®ÜökÝâ)pϤ?¦Õý üíy$iÄOvn¿d;ô°«O{ªg‚Àõʽ(åøÒõpà WúÔµêöÛÝûm\>íÏø¼Àf©zÖè]r(;¬f !!„U+"9åóBî=°Ki±eäÖ%«z<å„ å‡s‡à¢¯nn2§ÔmJ^:Äovûݰ}T£aãce«ì´„O$ži/¦\™¿=?Ä‚·ûMâ¯?¼ßÔdÓIOE8ˆ‡Ía»¿6³Ñµ”R¢PUrc£¸PU¬ÑìDA”ˆf­’$e‘Ö‡ûz&݌͟8è‰Ø‰ƒÅm€>G<íô^ŠŸ\±ñ' ’u#úg\+šÒOùCÏ ë¼ªà` ¢½&·\xr¸ ­?,@O+¿ O _ýlOWœ‡_š" hãvúº¿’UÓÌíÁäp¤DT RPHj½ÿôôm¢i-\-ñî›Nãç_^ïvWç“ÞŸë~“bsš§"ºúé¾Éf¿EqfiιC§¤Kø’¢l®†$ݼÔÅ–ÓüÀÙ^½ÝýÕ_ÿ…»ßß>¼ÿúÃÝÇ%ÍÆ)ÓÕÕ~è6uXÆéHâ7Ÿ_ ‡¾†ß?œo?œÇ;ø„ΰÉ`·ä•2Ûr‡‡?Ôï¶ãr/auO»ÞS6…·´$ʉ*u›”z)¤¡‘Sßç>1s¦eYJ),ÄwDÔݼ~3Õq\yºz-¯Þ ’JÕ™m‚G”{ gDbĨ§më·¹KÝt^Ž9æÄ^»m·S[D& «‚¡O»Í+Ûòñ8¹è°ÝöÛlt¯T»îͰ{Sc©På‘ç ¨y®oóy¤Àú²è·ÿ|ûúu÷¿{³¹ÚÚ©×Sø\ØV75¤L˜¢z8×0%’¡ëû!ïv›±œ?ž?œª-‚í|…ôŠãŒØ¸g ÷p±¹Ì\àE‰âj5l{%»==ïµ¶¯ã°Í4>ŽÝ6n^itßÝ~arí8¥„^ºl&ZfŠ©¸z-¥ÔRîn¾ûîq9û<¯p¡uæJXkm~îómmk ’ˆ“P’`" ê³0õ$Y '–L)¹¹šyËâ 'âNêy ä7q1$g‚¤¦7k3úˆr÷›Mê$%±Ðe™ê²@+Ѽ-m„dMÖƒåœ0²55…¼uàà «@d“»̘ÎÅφ°Fæ D^]y¦;C”sƒ!¶fÅ’¯‰ñNæðH)ÇÊø­îf¥š¸¢1çˆXæZ—@ê:%wa0‹œûI–0s¦v¥€’±V+ÖÒåH HÀ‰á!.Ÿªy¢Ž;KÞZta¶_$Qûë8Mµ¬óswP5e„Ip"ç ¦¾ë»Ý»îx<LFaæj5Jéh—9¸z Ó”Jzé6ž8SÇ”µ¸¹Aµ†UɉYœ™¸…°0G8PÁ‚äü¤$`cÁ&KGÑ\jNg–D’¥ë¸KS‚GѲ,M$ þ"ñÉ¢áq‰¨q'B8]"q?qÎ[TóYÅ:? €[ãH¹7¸‡‹@`в$‘޽“è{Ùº«7[}kW§ó—C”lê®jÍ‘µ?ì­Ö>ÒÖ镦_óîËEN¶|3ºÌZ=¼ƒ’€!j!®ÒVqcéyƒ´0þõ¼Œ³{!xCÂå.„ë¼Ø:÷§öàyåæb¿HxÍ)H‰¢#Ê™82óŠ9f®D g{ÁØ9ˆ³pN 'ÂÖè±ÕÓüTôøúãð”âÞ¶C=(÷ÄIˆÝeÝz8˜šÁ›¨ý¢9Â!LáÌôiü‘¬íµ| €¿œA?®’z^.Ó3øÓ 3ÏK¨ÃŸAVˆÀ/¤öÖ½=u/??øc~÷O½Oÿ¨5Q¬uð§îEWߦó«.aMi]u—Þå)eõùvèÿŸ5¯iœƒrPrd‡0jTj…sVõ²¥~¡¾h‚€±Ù;à ~"9úÅëý©ß÷{‰î´ôD„#/¶u>HH|á”çŠÓÔmvS=ÙâN8¹«eçÌåîáä6¼ÉuÇýa“¿¸Ú?¼><ŒçùtFêdwˆM_®¶aöz')óQã¤ÑÂå(„E£¡aö•V‚ë«+Ùä,©.ËùxZ–™€ÄâU•¹Š8ÁÝÕÍÝ(ª†øÞ˜@JéÙôaå¼!@áüƒ]Î÷,nq‘BÒóÚ{½ø%W·¿À•`±ê #ª5úîo#åó_~vØeÁãýw$¤VÑù_þÍo·ûáÝß½›o'€h³Ù€tçWŸ¿ºJ‡wßUŸ¯®®jµï¾>õÅg§‡Qgg‚d¼zsø‹ßýê¯þÛï¬ê×›\¦±”â ˜R(¹{-áÆeqNÝázõ¶ûïÿã7o~u}œÆÛçüÛÿô3¾Ç08¤KATáŠûw%üC¿½§ÐMÇÇ3UtŒ”Aè³ôéÐm‡mN©›çÙ̺®Ûlv̬a«VLÕ`‘ÔQ÷²º×¿ºþÝ_¿}û«­úññx7LJþôx[Æ{Ì\—¹ëå‹_§¯þûáoþæ·×»ýýûñ_þîã·ÿ:Ï,觉ÔjUso‡®ßF'K-ÕˆˆÜ$lc”¦3>~xÜ\½yó¦xYŠŽÓ£Ù@•–ÇåL¥¿êw7;g§E9†$i³Ùïv¤"¸ÎB!³>Œçúþýé|ô…×õ¹4‚âßp¤|v—–ÄÁ¬S¢ÝËŒ¢Eh·Í†_Àš,"œ’¨æœ…™‰W+¤»¶è€–ŸÚîQ´nC’Vgæ–(P BVk‹KŒË=-<Ü­ë{ƒJ°¯w!T8I×õÜÕ©ÔE§ã8Ȧ «ik%Ð¥Älö›¢Ë2º¨k¸‚Õ’?-…ÖÙõZ?s¦$Ì©oQfÙ]=´%8ED- –"Ι’„lÂ¥,šXrî«OájBr^mÜ«F2‹´ùh°ÄÛBÉÝÙy li¿÷ †)'¢¶ÛX·|""8¸ßý"¨‘²H_2ƒ ±=ìMcáZômšÀ,”Jމ9Äj'%éSêÜ(@nîØ1BZE¡e°y{áÄ $ç$Í£J‰£K)»(¦“Ugq05“Y¬¯y ÁÄOáŸLëçdúÞXqÅ¡’+ÜŸÔ­§ä°uÁEOÛ^ÿLä‰P˜gP†‡W<‰¦²d­7Tnà;òŽÌ¬ÅâQùñ|æBÜ¥áf³ý,vŸ†óh÷gÌàbD&î‰:I‰]•Tev9CNʈ‡RG6¡"di--pU3Xƒ8R|¦„ž®"†³C€ tŒž" ¥@’!šÎ Uo8 %H:±¥S‹ÕJÑ´öh€K;ô¼bç11¡'é): ·cAÜbZ9bå_Þ93‰“s#)¸ÓO<«Û†Ä«™]2v×3@q©ib%F#+üÀá|9~hî94!~¡Âåù[{¦z†ö~ ˆû³²†âþÄ/á°ùÿ\€ýq#Ù*ÝõQ/¶WñÒ¬õ´&Šxa!zÐôãkŸŸ§-b0eIe¶ ‰¤Ž¤“HæQ«›3î¶,uR–F¾–ÅUÔw²ó4vÃd;뾬µÃ¹¾¡aÏݶã×`RsätÎyNV8X’?éRÂp>ùðpýöºïòx|äCýß~Eû®¼ã|?š"ÌÆR-ŒHÿ§_ÑÁyñ%æ4ƒ•Ã<È=-*ÃÌoB¥ÌCOÜVÞvq{…·ÉiØå¶Ú4Â^Ô_vD´Z:Åñbyé!ð=¿Ü¥i÷ç+¢Ow•K¼ï÷®Í¸LôMi[yðkdyx8Hˆ0 ¯w ÒõÞѲùšp:l}ÎQp‹\I-Dha[«=ŒÂ@5Z*ää)à…^†üŸ~G'B Bù=ÑË‚²`»ïn®ß|ÝÝŸçsYFÙäW_Þ|õ›/¢øÆßãÙÎÚs¨ÆÖoúÝ›WrÅKeÈwww•¡T—:çžöW}î<÷¼Û÷,–„™Ý¼‚™„ÅŒÜi™1O®W7ýözóæ×ù7½}õ¥œK¾¾¿®Å>~óèóMº9pg¥Z:j893b9Óǯϔ-  3v6[XíÔSæ©ô;J v3-K)"œ™.áµZ„ºÚz™ËÙ¤nˆRÚ]]^½yU¼w!7ÉCô›’‡FíFOiØÅásþÕ_ó?þæêõwÿz*zþÖ/Óiœ¦¹xÑ€ÊÂçZ–‡ûÛù¬Á“ô»¥Xa¦É¾Ñí†-^¿í^¿~m¾}L¬Ri¿ÝpEq®áÓ2cÁéCùšïOïðîó]Ò…Ã]’u} 7 -¾ü¯éõõLJr÷Ýh "t*5HâæfxµcíÍ{ŒãôûþºÜ×»?h™Ñv]¤·Ð0„µ„uonfÞí†C/Ü…/:=ŽÑ…1>¼¿õl˲ä]ŸúEÜáæPCÎ-#1>Mn˜(l§Â%1hMhNšÐ¦^0?Ũ¹™º<.‘éÏêSÞôÛ~æ§ÇÇ2r‘”2:)Ë‚¨è;ÊŒfVJ™¦ s….¡@I+;éi%ÔpoNÄ`ɉW µŸÏÇ”³PZ–àÜ®„ˆ¤°(SáaÈ9׺Àõ© $"À™%%5×PõúädogF(59‚V¹RüpÑFáÞuîäîáâîí’¾ï»./^Š•¥‚ª¼~ý½ˆT ÷´À¦–ˆ´T€8%“êËR laါPÊCÇà¶Ap¥Ëï‹ÞLOæàœ‘*‰3#8@`XŠ`7 ÷pµ˜ šÂ 0-e¦¬îNäæ°p‡´%^‹Ü"»ìÄPŸAÒ:W–Ɔ&"‚ÑÓSvç?¯Å[š9@©y×`mgàb8:Šõ¹›Ì:[ú²ì­î‚B"ªÈÖÒýXh /Ó¡F©‚èýq©O˜@@îXÈm`ô„žH°ë7;Ê;Z†(ƒr¯”gÀYœÉÝ ö‹ÒhÑQ â j,kötZ³ÿ˜¸3ÅCÌH@tL Ô2Q ò0'„'‚R„šŒLʉs2¢ª¶+„´Ýί€š;úYK¹Fö"RPÏÜ2¡%P0A‰)sjaHßëè>)¦VQ¬ ŽqºG+)Ü­›/Î&…~«M/·COÿÕÓ¡`úÙ­Ë“ÐÎ[Eðçªôý'Z4à“|Žð¼ôzÑÍüÉô‘ï‰Çþ£|DO¶« .â’&À/ÏÐZ è?ôœúéuпŸ›`–dU…×.IbÙvý.åM©|õÕ—ÇrúpûÝñ|ZïÞ§g¼ýl¸¾>Çïîîn?~ÜHò7¯ÞNãé|>/2‡‡ÃÝsΜr­ÆYò†(ÕI?ÚÃ’†žòFºvT9§í7³žr'¦.$!Ù)j)ìà ¯è{ÜÜ`»¹:¦£Ÿ–Ó8Ž×¢Þ÷ç©`®³“wÃF£™ÙÍ VaZkÊ”6¢UÇ Çû»ß]Q‡ÅÆûûóÇÓ|,s1†RÚl$mQj©:©-nUë´Ìãùôøx7Û’§e6£ú2.ãUvI:F!!†%–qòœ?ÚxûÙ9¬I·ƒä”çí6íöiûeÜü/ý—ýåÕðö÷ÿþ\æåÞ¼š.5®^í^}y³{³7ñ»ùþãéátwÆ þˆÈv´ÍÞE9ÙbûÍÖ«NÓôðð á‹Ö¾ï¯÷jõ8>(jÊV»»} >ܱÙl¶Ûaº¨ó¬¶t½äÃæ\;¥83__ï™6§{=>–ïMøˆ#üÅšøçvD«|ŽCD('^’+Aݵ‘NëìpPJL=3GÔ–“içi²è2ˆ(¥ŽHÌLQ‰ì-²Ý#œ‚¸ïÝÕªƒ¬ù ¡^ž"2›Áàé¦YêÍ!ÙŽDSÊ™5ë붆®Ÿçéá%R¿ŸÆÓ°Ýæ”-™ç,”Ä¡ªÅÕZð6œB­Ñ„Oé„OÐ¼Ä °ªV=üYmSc×Z g&r ˜QÊfêV»®1WÔª bLÖ¬HaDdQR*AB=…Fun¸‹°Vüº@¼åŽ·º’¢ ˜ã™iõbO×¶Â ÅÊ,°0 @—eÉݺ3;³3gÎîÿÿgÌœÝîѨ%‘*²ž23^înfûÁ#Q ›b·fÅV«>à<`¢ n{—á‘ü»Z2gz:Ám_µ+9"q$ pÞÒ<=“x ±uw—ªÈ¿g’nXUS‚ÿÑz[lŒ luÙÓ¸!þ—–?X<ÍØùߨ²ÿi¢û?Þ}HYuð¦!Û°‹å£ÿ ^hÁ“RxS ÒL¡/f0zðô“KŒM“„J^Ü-©–>mÌ{an+duã îTלBäÔq ¡R¨%1í‡_]Ý·”rê¯c×kFñÁxG±W k­Éà U]EÎc©^ J0ŽQØK½Ïs<ì®n?Õó÷_}›O2~»ô|oW½¤$žýán,õh‡>\uãùažîs™\¨'B`3˜µÙ¤0‡æ¡q²hw-+9¢Ä(RsYk†91›Y[òX[©ˆÁ›„Õû¾y…ñ§í]ÿy©/.XAæ"¡P6>>|-1õÉféQ8Ór® T8„tîâ‹lpcƒ™»)¬~@ ­`€-8g˜Ác#˹ˆkí»)a׆½!WgÛª ÌäÔâÿ<ÌOMbøá×q(ŒÁ¹f †* P1ŸðO¿þÚëí'·77ÏNsê*`7ÏoîÞŸÎÇñÔY‚ðýÃxuÉdœN)}q¸ÞI–iÝñìaJ’bHœë ð<ÛÝÝÃóÏÞ½{ÿðpZ˜Áµš3rVMëqžÖÐi þv’_¿}ñY—†¾®‡¼È0 SÄ8Ž!h ¸z~}|^ÊÛ‡Ó’s$v9»»Ž3¸›‡ëk e|ÈèlÎK'—€«çÅøxLy=Çš¡ ÌÀ 'TGY^ã½èv»Ý·ß¼{ýþDÖ5ß½—Ӛψñj7ìbçqIÞ};ýî½ÊãáÍR– Í"5ì‚ô™”±Ôõîü­ØWè„«gN Š©;Î#+ègúŧŸív}=®îíx|˜B8Ÿ×iÂZJíû.˜Žçòj¼«3×¢ö±êøù‹ëÏÿÃõGÿ÷MÿQÿb÷âÝéaxÝÕeúæÛóÍŽ%Èþúð_þóÝ?Û}ûþíñ·ãéë)¸L¯õšYBz·ÜOÇÝÁtòC¿óª×ÏžåœÇù¼ÔRÅn®ÅêùtZk Äíú>¨T\ß|‚ÇCïïßß¿|ýâÐÝ^ÝÜßß%u}¯>–lóóæÓ·"ÒŠSrXU† èk¡?nXüŽh¡UŠëR×Öî¾®k]!v¦º¹ÌµÂ@ ð@à6OFd,$¦„n€y­Öu€eÎ^L† r’ Ûén ‹»ºªjQ­æææ­òEl6koÏb?ì–¼ŠDjÓê``ÔZ-O(%\]›áíëw:k×ïBŸÊRºÔ•¬ËºÂÂÅÀS×Nç-1P„$ ZÌÖú>#Bˆ}_mËë47®U­€Œ¢8I”—Õ IDAT¼R”a¿é˜F̼L«•b )H§f]ì‰<çÜi}u: Ì^km“!fi€¸ÃnWŠÆ~ßD E˲,º®d%¦.i±œ«÷}O±ïBîšRêúXJÇѼjõZUaf„D]sž&3 }×¥®xq‡P8Ÿ¦ÛÛ!vˆö×§Ói~÷e<Åݵ¹¯ëct‚W¥¾ûÅ/~ñúÍÝû{ÌsuæÝUAõâÞÍÜ™(@˜@%¦`YŰv–wPhÍC +‰-¥JíûÖµ¬î£ÙjŽFn#'f03‡.USU­ªà¾©7>‘\ú¢?ô=©ª›^ Umó$¬V›÷DÐøI!…¸; B‘*ø°ßEvÇì"ø@ôŒøyè®Ù¯waQCQ©äÙË2 èúúJ \<Óýií—J0t)8>Tù WxÇÒ§ø;ÜmÄàHÖ¢yÉ ÷Ä£4‘GÓàó¶ ÛbD Ðf‹,¥úrˆ›¸Eçˆ{$$¦—ÑÜwæªUHA9—óœ³#:†1FYk9¯yÊ¥Zbb3Mû¶ŠjíxUÜls%3CˆX-0u!¤@€6Õj1WÀ7Y."v%‚—Z—¬Kñ…A!t]‚ÂP™£„¦ÒÑìwQxShÍ*òµNø¢¡yúÔMÅ÷tš°Ñ¾°†3ûáÏŸªšûcÞï½¾m @¥ïîF~0zõ»¾PûËv8ß/ŸÞ:ÕËÆ«•Ôòd ò<žÐH3mû©ª­úgüŸ‰ñèÇnÂår@#ƒüle²r`Ù\ª•|tØÞ$….Ú¦›HýîÍë÷Ï^w}s>L‡ç/l·ŸÔÖiøz·Ïó² ôìú&O+ivâSÇ uYj”ÄVÖz^G…=»9üìó/ι|u<“ÛèÝë‘ÊgÏÞJ¼ W‰‹‡|viw˜JÖ‰"§«~It»žÝ~žwýo¾ú§xóõÏn_|üÑóSy(wó.˜ãy‹ª¹Vvy^ŠS pêûšKYW ®…JÎÂH!©jQ33߆¢ð§AW@Å&«Ddc™mÜKšj3¡\P­ùw¿$·‰(‘^ü¢›Ê¼…ƒØan-¯›™°ªíYOäŒ-¡yõ‰~¯^rw«y„'nê¾më­ªdΦ]LÚ6¶î 7sö¬iЇØaBXs1SUX­jkpéû· oA˜å'Ï#úIs.þ zÂÝàÅËwÜïÏ]7×v‘ªæo^~ýÉ'ÖuÉggµfÄ(!yu]ŠNEW¸ÂÕ˜ÑÅ”’¬yGûæåÙõw!„·¯ïÇ#ÈSHÜ'‘üv\úaíØŠOïÞ™qÊØ¿ÊW×'Ø||ÝîÏóœk­ÑŠ*~þÅ—§eÊã8×%$yþüÙõÍ.Hy÷öe)˜WøC‰ýJêŸÅ'¬Ç>ÒÃÉK†:Æ óT9ÔÀ¨u[1šA »®®%»N Þ¿_§üJ‰bË’ó¨u†etêr´¼èÝWÕßááÛ¸Þ}5¾Ÿï¾õÓ{œ&×›Cøè‹ë›zzw<¿üf}xƒg7ñ˜KÏÌ)RìâÐ:ŽççWׇÝ.¸ÌÇåîíýë—ßNµâîáaáRˆ±Kׇ¥Ô|<ÝU«È™•£÷×éöóç¿|ö«ÿö7tEë{F4']êœýæözwœl—óݸ¾/ú!:XºÞ=KCïë›ìJÙËœgEß%UÍyqq'7蜗¢•˜‡ƒ$q#+¾;ì‡ë. ´.§ÓÃÃôþ5Õ¼¿NWÏ®Mu©KVÄ´ßâýûr>Ÿ…¼Ö ßð’pþ®ìâÇfœOß©B›I2¼Í~…°š©ëÜÈ•Ì"p !¶,°¬V¡Åajj b#’ÁØf™!— Âk~8\ !¤ešKQ!©n6Í}ßCÍZ(¡ÀÄ,f€™]ÂÍÉT·|GƒU«^•‘úÄí—µhÝ~zÕšµ>bŒ$%éÇòœ³ A8ˆº¡¶í½ ’A"„«™Íü‚V#oRH¦bJ‰µÖZª»Ç)¹ÔjUc»Áº>Ƈ¡›Æ“:Át;VÁ0g­Î€S€;Ì„B ©ZUh­æÈ®hÁ·ªÊÌ[ÌÌj¥˜™ˆ¨*È%°‹¸cS0hÁÅkw33u+ªƒ—%›8Ća˜ûµ`µ–l‰Z Y+¶»®§)„Ð ÃêDXPKAÔl÷¦pƒ³™ jÕ&l\ðÖVpË-'8A‰A\„«‡*0†1Á¹íá\][úˆYµ†òh·ÀV†’lœºGÙU;ô¸ÁºÕ/j£B£9¸¬éD°…—B›Ö‚ع­sœ‚i]JLèðÒ5®ïôþ4/aB'w‡Uת>[žëx."+|Âi¥cí¯9øbÈ}]rB|–ºëž¯9D»fNó”< ¨AY3ÕJUý¤ëY fºý…/Ë-Õqqäqë¯`Û|Ôˆ`ì&-öÈ= '’À$Bäp³ªêfEfÕy¡Zý²uQ.] U½¨¢*(NµµfÌäØV“M¸ú$Þ´mfdCInq¡f0³ªªêÕQµYé NJä¦^ÕÝ(Dfð÷×öA9öè;‚¢…Ó6 #„“»9}H.rrûS pû§Ÿºwø±5Ñ_ÊeýÛ].û+ÑE%ЄXM.åôø=8Á˜ luÌÜyÇ¡NÉ9:uFG`0˾/Å•øpèào×ånÍS×­kÉDJägv!8tg>vRs5›rÍ:)ëŠR4§>rÇû¸Û•Ò×ÜkM)½Ï´ßÃЇd3Uöc¦àãù4=œ†Ñd©¿ýÝ?^ßÜþýG·ÓúZë®÷½Öè³¹z`á rˆÃ¼í–7`Á¡ïC슕¦â.EiŠîí©+ 3…·ÕýæìbpI† ú#üÃïéå¾w‡7ƒPó<ý6yDZ?¶Ä¾ ø¶oÙ4õÖ¤½ìî«öñ2!cß:(¸=ƒ›±·Eq Æ&Ä5ÖrŸÝ!ÄäP‚PCn£²³ƒáâW'ßòàÌ-uFnfÛyæÞ8ŠL0wuúëö95•?^Ú6ÊhxŸ<ãt¿kÚÇ}¿W+Y}>Nc:{ÅaØY1ÙÀ‘S´äû÷|º?ŽÇ‡»{;"âH]†!%™)•¥¾=c9Ÿ¯®h>Á º€È‰œÅ¸|ù÷òó_}¦3Ý¿xóöt÷§bý1¾`>s7äâÙ_}û•‚Í’ Ç1q”ÔuƒÙœ NìæãðñÏ?ÿä£Ûç=Õeþþá×ïÞž–, B®H‚$è:éú¯)…_~ùůþîçÇã·¿ùíoÞ¾¯ÌL–J d1Öá|ºG5T¸ ÍÈÅ”NëkŒß"†i¡ ÛáÓÏ^|ñËÿé¿~ñË¿ÿ( ôõ7/ÿûÿõ~}ÇoúUTˆ»€ÐQh5¥ÓýÃ˯x¼¿/u=ç7¯¦»; bHp õÝ0ìbŒ1rÕjŬ‚œY‚ˆÇž¯Ÿ‡›OwÏ>Ù¿yÿÚúÝÿxõ¿þñ¯þOïpèRëyÉ´r‡Ã†;Ý''¥V]n7VÎçó~3 fźЕ¢5—Ôu°êкÙY\šNMk…ªW·â¬ ²P ˜+\a…‘Ù3Ü{€ØÙ¡´%ó9Yû76 ZfðKSr¾‰±Ó÷–¢Ú\FõÉlØšhPßôâÄÄÌBÄ@€GB€wúŽãñšpàºóµ3eÊê–«Q ixé!ÕܹŒÕÞ-¹Ë1efp‰ B*µ zˡʑJ)Ù hÜg_ƒç6Ut'‡l£oâ{jFáœ5˜“™²CÜÅ)€¢„@™š„°¨SUpˆJ¨dʆі‰sÉsÑÂRÁ«¿t¸‘Z9bÖF~-ÞPÚsD]@-­ÑÚR]]Ía†ZM}ÃX*‰5E¨9Ä™9j)°ÙDöÿ|‚ÓÒ?À“Àíê˜ÌŸøˆ¾+ªù1GÐ…m Ú¾$ç?&¡úÁ%‚ÿ)þGÞ¼Òy~ÌÔzüäGÕzöï¬é¹\ùw#F[ mй&nÐʧ¿8Àìƒ墡ú©ÙÔâ€-“­®+ˆa…‚fÇÎ}zb¦f@„ÂòápžÆRJphJæ¼”2-ÙIX¢²«Ûª:A…‰™å“jOÎLEÂ"½¤}ôBÜì_×u\ùFù–ù•bžëYœj™—qz©Ïw)–«d…º /hèâò›—låÓëáí1åé|Z×Áw}è= ªQj$B¾ÂÅTäP·HÜݬ¸±»UóªDd¬›ÇÕ,;i[;žÈ˜±ÚèûkÙ6»±§šç§•‰}ضQ l+TüÃ=ýÕ€'ƤŒ¢¿ý$¸[@]YÛ¶´b›÷50µÎ°m~*_ƒšV¹½T$¶Í¹ºEW´R ­HÆÌäÔú5áPÍ/8°·°Šmfð?ÛŽè§öýØX£ù¸ÐºJgg'JâÕlt<®!Å.v}L%¯×ݶjS¼’¨¼vS×G>O_ýÓos-¥«F#R/  W¬KÍ‹ZAÍX ‰PW@aŽlÊ¨ó÷_ü‡ÿö·Èá÷¿þzOï 'Ô3¦·Ø8'2€ì¨o^žú8EËZîßÔ²t!ÂSXœ×Šj>~üÅ‹¿ýÛŸ}|ÎÇ×Ç7SYédµlxnIäÝnwuÝ+•~/þîÓÿóÿúϦz>O/k1‚tܧ°§”0 \]W²•©C]=W'9p©" ÷ÜÅkgº_Ž75Ö°††=ºuYr©R´VD¯æKµªeÌåX<3pww<OD9†ˆØ¡ÔHÝnèú¦¥­ÅÕR"¸0 ‘û«´©[ÏËûó·USø§ÿ÷woþ`y„>þø£¾ïÿðÍ×yÎþÆÇqšßW­è3V[¬º?ì÷‡›ƒG­¹¼¨Õê¼^aÑ‚ÝÍ•$1²€ ânæYÁ>tÝó›>ïSÍcêÔgtò³Ï>õy?žm¿Wÿ(ïòë÷çiºäY‚Ù¹%&ƒôÉÉþG¾íЇ'Ø@Òî7ù>3$/#\É+L&æZÐÅ¡¦kæW"gi3u7ss£ì ©S©NÕ 8øÕ~­+Úÿ &²Çlv‰¤¦P£¶l ˜5å@Ȉa"wC×÷=»Ô•±YXk¬É€BŠý°ëºÎY¬-†ÚUÜ6+¦ ls|‹1ƒ\±…A‹‡k¡v°s!„&hÂ!u%7-ª¥Ý®Ö "#Vk=‹†¡ÖšK }i1£òaØ™Yc£©f¯[ÂéFœ£kî~ªMiß8 , ¢u]­f0·î±Ù²™³3s5’(Ö¦®æmÕâd@Vç¬ZáT–´çC×C ‰ÜI«°uÀ¼Ö’µÞÜ<ÂoQò‚²‡ª”Wj®pyT©møê5×Pv†y`!eS'ŸÍgؤ¦"ÎD$ä&D¤š¢Ý®ÜT5m9ÐXÍ æõ’HŒPJ©™©©°çnűƒ¬µàÛIÚ@ÖÄ b2c"qB®D†'ö]À³ÐÝç¥ÔU×âìU¼ç¢K½êv⩨U¶µÚû%óLÉ 7ÝŽM¯û´‹ˆUVëW §uWwûÖlk±JaIu±RüƒùxKFwˆ!ªÜ*äÎìL '­ä`s1(EâHœXˆÈÈÍ îVˆŒ=ÅXÝJÓq°¸˜"‚”jKÕ*T„KÃùeµ×êru2&<þúÜ –hHhâF"ƒœXœZQÝ7 [æ˜SkÅdógÓÆOLjúc£mdrÙ´–Í7-,ø’KtY?Ð8þˆšðSªîAêëÿs`À_ݾè1d‰.t…æ1{\áÑ“6]¼ríhØn”æùOÜ}˜A09“±ÜÞMcËbTޱ”P«£Ä°æ<ß?¤Ý>>»–œŽ÷÷ÎÁC±A –™B œ˜ŽYµÔ@,TÔpu5\}rm÷÷€:¡Ð2O–«v.×Ù¦q> ¶i^§¼*ˆïè£þgÿåWþ|?/ËÇŸò³¿ý¿ë9ÿÍ/?ßߟßL~.¨©#&WÝ÷C„ÍP×ZÕ¹1P–®5ge6wiŒÓvõ²¯kùomú4îi½ñƒÙ¹Ï?¬…[Í[iâîryÓã±yŒ4Íå“õ=®›sœ›æà;ì)3[D‘²éÂöê0ìâij[5ßZ?‡)¼Š˜P+RÝZìƒ;ƒ"K` Lº.F¤fõ¬¹FšrÞ¹Í0¯¶œÏó˜oO³©w}Ž÷Y–Œ}êo}ê².ån=x¾úôï~)Ÿ¦³¯:p׬LË«×ÿéË/÷?ûÙô6ó¿¾}ÿû»24°Ã ,DWs5!nVËÙ¡(E,ÂDÊ–÷І nÍϹžÛ4ÇÍ,JtßÒ;hÛÒøã¶ð2{øÎâQíò½dÞ‹‡ÐrZ“ÙÝÙ7MžmOÕwä æ3P÷|ñ˜Ús«Å= s»ËŠ_ÚaÿÎsƒÌÚ ‹/¸Êë#b¼Eo%sËp#1Û RMÕKß;ÿäyD?é#Ãi€äêW"˜”ÝŒ]¬è|^§ýԇðK?¼=îw»da=OÓýÜKW1Éé~®»€Ô§C¼êiwÆÉ*õ»½Š¯kÉSÍ+„ÑwCŸ†ç‡›IÆ•F+•AìÎ.Ä2Îë”×ëýáúfûüðj¸{8¢žq8<¸ï„•Ü)»31¼«K)ŽÝ€ëg|8¦s¾»dÅ~×Ç®K윖bÎËû‡7Ïna!Ëà¡cžÁÌÁcY×U¶°=w1$Z0¾;¿­ç¥˜JLî¹,«h)U +Õ"!0¼2˜BìÙHcäÖ¹0f×U±R  ÄÙêû‡ûüíù~y·ëÃÃûó׿?½y…PØ)*›ZfÁþŠÁr˜ÑCÒpåÆó4ž¯ÀÍOÕ TM§uOµ K›ÌÉ9`5|úóO¿ü»=/ïÆñëÿñU]û‡ßûø(à|w2<ÿä6¸ßÅJß”5cÆú¾ +n†ñãÛçÏ¿¼Š]ϯ‰'Üt¸®úqQõ\•SºÞ_S'#­î –”¢yžçY+"÷»´/KádÄ̉‡C<Ü\Q &twwº>¤M>dXKùîiüAGcô¯:SŸ +Û£nd5gri†¢ö3r)!3¢…D!:¨:Š»y¶NÈ¥=l$’“i-  *”ºÃÍŽ=<Üu^›Ä(0Á!,ÄØl"Ä.´áïh«vŒ¥äbháÁìsž§qÉ'F!HPE¤g€¥gŠ^׺,“.˜ú¢ Yç° ÕÙ~ª 83 Ä]ŸB"ïHTÕÉVuHŒÕÊ8Öéá´Y°ÔLæBÒ…¸,‹—Õ¤‹Ìì(¦TŠÁD¤Ö U@´1¼Ê¬jFæ„3M®-"Nüa¨¦väDnlˆ¾ï3s­Õj½XÍU1Æ ƒ\Ú»‘Ø2Sä.% dð¼ÎК%?¿}fîK†.Åá ŽÌ¬^ó²ª*i.P¯Í„£0eˆp;j6Z7¶®” Èeào@VÍŽ,¡:ª¡¨9U2&"q¢êÄa95År+˜6W‰·-Ä·•ZœÎ`"07tù™;‘S;ÝÉ›Ÿ›˜™š³{s=‘¸ëâpº’äëU]bžÈö‡T¬&c„ò´€´ªTªJÅ)Tvâu̱ø $®Tkª¶+øX†ÝH×Õ'Õ“ÙL ’@Ô+$zmÆóÐjüÇDèš©—8²$–°E¨›»W·¬µÀŒÉd5mxGÀÅ áÐZKQusR Pð²•.u ¶`w¦-×±ÍhI@Â$ ­Z} ®N¾µŸ ŽÌ­–2®ôZ¹ý¬Z«o/oþ]xA<Á 4îÓ†ÿnóÜÇÑî¿FVõaçð#­ÏŸ³ñÿí×ùk싾'}Àæ—êöò_ŸæéYSºn7Œ_Wp Ð|L›!Û —?þsÿ\Eܹi9A­²/ZbpÒ¥,J ÙQážÂ<.]”Ý’ó«»»·ãâ!*$›Ï®•4€L@LâØ‡än¾R ¤I¸YÜž}zës‘ÙP(ñ¹7‘ÐY7¼¨ù½GÕ\¼;t‡¸s+¶çÙN/ߥ‹ÏwË-ó~)7Þ}|ûóŸÝèÝzúê~]æ$»Ôïï§³r¨• 3@„®‰Eœ6ñ@¨Ž¦^ã¦#i{¡0êöAÿÝ0¨Í,ô´ØØ,ˆ-DïéÄÛ3|»+¾“µÚ¨—5‘=IÝ`f×ï°!Û\«=ÚÝÕqÛH×¶Iˆ”6„6ÀNDdæ`bµ $+ Ú„u§KôÚã߈ìið#C„vgòE©abg&bÚÆ-®®¾ZDÌ›1ê¯G´©?4º´1^CRm-‹ÇqHý0ôÝáôú4W•eZ£Èííí~×ãižÝ]” :.Ä‹€Å›õµæê•Cˆ‘÷‚Ã>Xp¢Ü … Å»»üò›‡2®vš×ål¤`Cb45Ý£²\'ÞÕeíºxµKÝWϺVŸh)…ë /Ðãr~¸?–oŽãW)È7o^¾»G~€O@¨V(I×üÜÇó<ûƒ˜éîõÝ74óë¯ÞÞßçå„å\­†÷lèbGœb²¹ IDAT€8¤YW1’žW½Ÿg_l¹â1.Zæs_úyœ»Cží|×µˆ.E¹ãæ–~õŸ¿óòÍ«·ïïJÚíU:’˜öaWkÊãn•Ë’'ϵ0¨(Šìv0 ±ÛuûëÔïeÔåáááÝ|Ï|„a¿/«Bøp=ÜþâÅíÇÏ¥¤Ð3ñÐuC÷r|¥¾EüHì “žm(‡Oö{;‰ÔÕ8«9yƪkºí?~¾K"Z—e:¦ˆý.®Òó›G;¨”î×ûÕõõë7ß¾yu÷çãË|fwÓ ù®}Ë2£?íd$àÆð!3¸ª›*+Àd-yD­Á#ÍœRàÚ¬Ò,ê(N¬ˆÎÑXà^b–¡ìH†Ý~Ë´j çqFˆOÔâLÌg6¢,L,dж!«*ª‚*úØ÷}H2.£=¬°b°Z3Ä!Œà•*eÏV¼®ZJ†$r1\ÝM¡äBcl¥ÜfçumfþRVB0³Z+!¥”’£[-hx³&»bbb8Ba‘BµâZk…Ábß³\ 0¦È7¨*U­Z¡@ƒ}Cšé¢Ñ»Ä¬Öjä̌ȈŒêˆ\|®!wS­E‘ÂL‰ˆ)8 ©jCV3 HÉVm«¦æ\кŽi?nvc yUL+´šUÀçeŒÜÃ-[Dà¸Ls$©YU+X,Hà(A’-À¢5C!lÜ!°š«ˆoñ´ðªŽ DÕ"…¶q°kË„2¸_ ‰´aÕ:¢‹ƒª& âÂæpת ‰Ö¶SbfbÀvж]µãö1Ñ•‰R )ùn×ïŸíõ™ãzÊÇ E°f_Í<¥úÄ1)wXb¨4bÍ(NTÁ¡ïýõs¹þìyw5®XÇTp•p:?\ Öj “J` HˆCãiš¨u[ÓøÅõäÅÑõÎ¥“ Ä—üßQnpeT£ÚÌmŒJÄÛB¥Z€,Їþ`ÅêZÌà,Å¡ 1«6ïÐcUËÄnÎ)BAr©øZÌM­VÅj5»©L.FYÒ²ä‰ID„œL}“ð|#¶­t¨iC Lí]s)þ¤N£I³>숞šþ=z˜ÿj×DÎÿŸ­Œ>ðÄ7Ó**}h¢ô‰8î‰äßüàÁ Õöƒì®‡.¼}õ-ß/;ßϧ5…ØE‹»Ç5pàjxÝc®Æ¹ÂLÚŽºÍÑZk[¼·÷|{G7öšo\tz"]{:~¥ËXåÑAôØ/m5’å£N˜Ülƒ+ØöÇäv~é¦>ü¸ •Ÿ.ÚÖÊ D7;j[H¶Ûˆ jæâpõ°™Œ¶Žo}Ñ¥üo½üöÐh™Kôèãm«§jp ˆÔââ-╈Üv7w ÙI¶ÑOMßþc㢠(sK XÝD¸™¨Îw¾ßM»>w{9ä%Ÿæ™Ô>úäæ¿úDu}ó?¿^  €ÆRŠÖ£¬´žsºó»ë)×’—’ @k.¬«¼«(ÓꥦRÇ!’ÓN¾úíœö¿ÿv)ëéÕz<ƒ»¬ËÉÑ`(yµ’I˜jàO¿üüê*JÒe}ç“Ùê.‡gϧশ–QµtÉéãi+¾~v¼¹Á»W8݃ BDw½(|úÙóØ™òù8žæ{ŒgLöæ7ßò/`!@PPueu…,¹ºÀjæHîµâ˜í~̾.˜ ’±ãÅ0¯Õ Ó¶®zè½F›;*Ä(WW¸úøú—ÿÇ/‹iw}ð_»Îåüþ=SÚ ×8Ÿ}>>tÒçuUä>u¡CLˆ^º`* «¾Ìót¼Ó÷çãËòN¡‹ìhw*§¬D¨ïW³öÃ᳇a`¹FJW¡¿¼ùôÝô¶ïºtˆs9ŸÎóz¾Ú]§îÀžê¸-®¦«NçÓ±žcèŸížS×Óùx~ˆ=…âþ‡W¯R‡ø69y<¨…ê<¿»{?-8/XÖÕV„˜v×iÏmöj†}@ö`KQüW?>¤Ï_ÖÆ¦P‡™‘ºª{5ϤF¦ìÎî( # –r‰1F¬Ôî­ž!HLéÙͳ.íNçóÈ Ä(x%br#w4QYL µ…½j¦†ºT­€d8 ×77!rQ_¬¤À¤(®^3¼"1´V[^¥f `Rrs`Y©Z+™sè.1 `BÕRJu”ó”"‚¡±šæº*Æ€ƒC` .PW+Ýn@áØw!1)PTÍAØï÷‹Õ\ÙÅ[’W©SÃóe óZkJ DìÛ¾DäQ%ÅŽØÍ´8°Ôtƒ4µÀÌ«Uw•´*±8Cš-Ý»«•e)ÌÒw(†®ëŽ÷Ÿîw×Ï_\]Ùñ4Ý×LYkd©% }·ë¬ª0°L£‡Ýj¥€¤’t)HŒÉsfðêR [—¨^‰Š7ñ ‹H$ à€êÔ a®Í"B,ÄîjæÚž¹o<…Ø|` blŸDw 11#ˆ.î^Qµ5[Æ€Œg·’c-÷‚ÌÉœ[&=¹S©lECÐĵƒîˆ©Âk­%¯ä¨¬¦ó¤³=÷¨¥ÐD´ˆTb€;nªf•¤¡ ®³žÎ¸Óü€ý8-㜧Ê+ÉBpBŒÑs%2Þ¬ÚÞ”œîî‰G™„6.bÕÞ©“X‚àêÖÖbnL )¬Å¬¨W5˜„`BÛ ¥#ÚQ8Į뺓Î'Ô1x†T‘£ûêLfMmrñ¶y0†œÁ<©‹Õ½(VC.X.í'š4±ySŸˆH3ˆ!2wd æ$—hÏ-»´•1ÁQéC´k›oÐׯäÝ2å7Îó–ÇÚ–çÿ•_’OœþåÁ¾è/Ùáü ÿvj—"[3 _öBD ˆâÙBô!.æ‘£ðô`Ó\áCÞî¿EïêFÔkæ2 +›ªˆÓ0ÔZ — ¾ ™„1pq‹uy¶ÄåøæÝrw¬Š°ÛP‹].Z ª2ì’{)ÃZwqOѲWÅÌ~·Ž÷cÐp»»º¾>€${8ÍŠpJ}Ý_c7øÚ¯5¯ZʲÚTîޤȸ+ûw]<„ݳþï¾øòÓÏ?Îïï)л¯Þ~}÷MOû>îxsÖ\–Ý>Õ@^i.y­ CÝ@®+U¯¦àÃH£&]6ˆ[¤7b©;i[ó4îrÛ54u»Ü ßDz÷æmoÑ ‹-e?ÿ¢‹Þn†máCŒœí¶1'WS'˜;[{ 4¤¾ƒ7ý;øÑA#'C‹ÏegxãÕà‘cæhBÂføyTÔ6Iœ¬ù’ÈÈÙÉŒÊ6Ê„ mJÛØŠAk™Boñeä ‘'æº?Úµ™ß¿ó? ƒÕ<¥¼å¤ÃÛµvSÕ(Ô¸åÇ7 +žß>'ê¼Ò0\…T&ºK-Ç7¾×x…õïÞ-Ÿ½¸aLNõö³çß~ó>ñàÅÒàŸ|’4hVµeáÚ•éxH7,ôöÝëë_~4\3ít™¦°¼Qêè›—ëÍŠ õè™çSÏ«ŸÐïR¸Ù_uUÄÉüj9Ñ”•$×èŽ ;–Q®Ó8ž<è0tAÂúnrEuÈç@ë‰+¸#évsoûƒÉçóí'áz/ocúŸË›ßb½ïTuìê³[¬Œã (‚YÐwUÎç|:æŸý⋳®>ÛÉÕúðîþ4¿Ÿ]‹CLHTx™j×£:° Æ9 ˆ¸‹äW/®KÖýŸíÃÍÐ áåË¡ãñÕ1.ñzw¨§Jgër*%SÒ] ¾ß‰ÈÃú,è"DpÝïbŒDn6~û‡—Ó9ÎkžÞ@€ºPYø°ÿ4¯¾Ì§Ã_Ñ“þì½Y“dÉ‘¥wTÕÌîâ[.µèz›ÊB™7þÿ@ŠLsºt-™•™±¹û]ÌLUù`×#£ªP ¥¥;BB²²"#ÜヲË9ßY·Ä?¹zµ7r¿”]wøä¿ü-Ýìï~Y?Ü1…ŸÜ¼º?ÎÑiYÖì1õ1}òªÜ×÷wÎ%Ï©WI¢4Í5/>cD캙ìáîCêBPì²WÕýþº<.•QŠ¿xýb¼yÿîÐãÝ»ùðÃÀe12‡·ë@Æföß»)òï}¤Íyi7°@Ù ¦jʦÎf–¡3êm’úؽrN­bÕ¼˜/ÎL"”×E©ÑÆ´ cÿòâ…‰/÷eñ…¨KL¹,pIÃ^E]͹é$L­5”ÜuDLk.Õˆâ~{©k=>¢Kéòêâòªª¿{¯§Œ¸Óz7‚›·hµB`w{b.Ebˆ¨µ®ˆ¡¶L& T5;$ øpÿú.R*‡9îFîvNîu ýnGrÔ¹”œõþ"–`9£¬ÚuB”tq}ùáp @k-+̈«Ðºä™„Bj­eÉyø™ 1ásf  ±UÕRj.æSŠ1(,%ÏE299G¡^Dˆjöõ 7@MÍP ¸ª*ˆÁb„jÕk…HèRAÍ) ;7ƒ¬>ÞÝJêÞu{Žýn×—W¯»‡÷÷øp‡Ý…w¦Ÿ~òéiyc7Ÿ¦°“j­ƒTaË©h0Ó]Ï!Ä)0/V°äÓÃá@]§î"rVƒE"çPA®¬…tC¡ôLWØ´ê˜Öª½DbWsG 12wNÈÅM‰"D”¸#Š!˜¢uOÙšrÑL@äŒJáž< (“„¾‹¹÷×_é=¨ˆ3û‰àqð¼^ Ã0Äì* áhe¬9×iÌÓZ4L±wr_–zW/_ƒö5§¼øJ¶ìC|Ñu7}àCbò’ø öPim ÛumBs5Ýh Q )hÎBèC¬nË)ƒÑõ݃i’ÈÑÝ¡^ÜŽëZ˜¡•P‚1‚\Û *€˜SEè¼N÷¾¾ ëkæD©ÂNsur1âã²9|8öàa@Þ»ªƒs 4)V×,\`¥"¢S4g¯Vµ’gA ÎËlÌ≪Z‚Ä“š:“)ÈÒANffnª«Ô"›kmÛkr†Ãβv#mvk€íìJ|ö´F}Ò3TÃ÷>7ÐãûŸý–ñíÿ³)û–àOÝ9ýÐ@åÏ„Û ·ÄëÖêœ[ñØPfÛ¥i7€Ø“CèÌîkí«=ç|ìˆè#›þxß×w0Üà}AˆNìy/ù’¬z]¼s¡pNLJ8˜Ý{¬Qö±¼;¼ï׫Ì7q×]ŽKŠÇ ³e âfÐR‘FëÂ1?Þë4v~v›_VÞ÷»¸FÏÓ‡u>¦ýC™òš=ÇáCµ¯ooçaXÌfÕÛyʳɺ1¤þ2 Ib¥0ûÍåët¼œÞœúðÐõÓn>>Ìeå±ë÷û¤˜Êz8=0b ábèÍè8Uñ»˜M•<¬jS­SŔĘÌÅà`0S† ¶¼Ab e&·( óÀXœ#uÃfm‰„ìgÕ“xÒ|³5o›‡ÐÒªl3B³ú×u!jâh'vÀLPc&yZpIK À†t5†m„\7s%vxÅ/›Í¹Í`ÝÏã6idw%ˆ=×ýíB !=­ÀÒ’”Z(ž â¶Ú²k…™-=üG;¢Fdú XŸ úQl€ 1˜…˜T• ž¹.‡˜½š*`”À½ ’^ÿl|¸›L°˜P?ö¡:Z žç a·ï_üì²1ÌËòö«÷÷ß,ëŠr*;Þ ©ëc:îj>)û'Wû1],ËI ¦œ Ž˜B X˜Qê:é“RÉúíé}`$ʢLJ%vý¸ßW;é¥È”3¤ó@„œò´Î4Óx•_t<Çnè®ö—/o®_õ?ùyw}•ÝÏG ê!ÕÅ^a»>±ÆnœŠAbì’\tãrwr–bµøF{ùyê^KØŽÿOQ‡à@ Œý°Û[ßÇRç¼”²àñ4»Î(U~úús£<‡\†*)ª³tCŸ—U‹—9ßOo×âU ‘) vvâÜT"è麮wIØ<ç’ïß?Hm]&\ï†ÈÁæ¬Óq-5;ƒˆs¢ÐÙ_ô—/.‡[]q8=^¿¾Ùï®üTŽÇéýûÛÓéd†b#‰sPBöBTãØu—}ÿjÄ.¨*qU­KñŽ»ÔwË<1ðæ«oK^^ß\2Yª! iÍs7¦O?Í/óá«™šnªØgÁÌ °µuÁïuˆòøÉ¸ÏMÅöjSp36WˆÁ†Ã+9“²™Ã.°è:=Xà†)™ÒqšUÕ=ÄŒÁ‰)¸‘VwsX+ “ÀÙP½”bm $TKkØ„pu!]× »\u:Îz\¤ÄãΉ”Ɉ™"„ˆE€.A"Ba“޹¶ØœË¬êµ©rØÉ‰àÌαàî\ÍÖuµªÁÉTQAÌII,P“ˆ„ ¹ë“35"³‘8‹»´aë­ ÒxgÌÝÂfZŠÂk­£™Y)0«Ì )%ëûû£6Ådƒú-ËR‹¹*…àöTJl;}²6œ 1Æ£«­ëª^ɼ”rV[Óyk w™WÕ,…CEÝÅ~•€j ‚¸“’¸J1ÊbŽò±ÚTÑ@ÄpA Lµe’Æ$"ê¨ØÛý<·oDÒ&, È­™mÂoM)w53WwG$dT‚‹ƒª±³$ „©æU]ݵx©$îÜ`mÑiÞ웜œ@îgŽÌ¥YÚ*ƒzí_ŒÝgÃòI\®ÖE漞ï3(£HN!ÇÈ Þ(8¢²ÖÂn1B v,‡µ–X‘L:ÝÔS!7Y),\WöBÔ(kä¶%‡š;Ñi5¯YÍ -ŽÔB‰Ô„œÑ-2G÷&Õ<Ð&dÌÊ^‰´åº @®dL@pô„Ž$±¬¦3toˆÉèèÜÄ)o±gô=ª³Óô07kp·`Þ›'r·F°• dâJ&Äíìdƒ©ùb—Ü¡.ä¦J`lä®@ØÐsàæúlÍýs©ðSåÛ¨Ùt®Ð­E;Ò¨ãÿÇÜ…?æóÿ¯>þð HgB>ú‚œ[úÊ“±ÇðjûÇeQ+Xo ó§y±‰ ``ƒWÎ$§iq5ÓµVà¹íàe~|év±ß»kÀÁ »­'O€0›R/&¡ëƒô\c4Mu–9ÓqUµ‘8òzQŸ\?À?¸¿ÿæí³%W–„XÄÌK©‰8r7RðC>¬ô~Aǘ–O«Èqµ,É ªDèêêb©å”ײ¯.Äj\ÔœÙ]ÍɈ«·»Þ $ÛáhNô”ìÖ¬ Ú<Àäۦȱäü¼f>ÛG=táìûaBmc#ÏÁtà'ÏæjN@ú˜_¶IðΡsì?ÉZМœÜy#*9ÝA¤Òó »³m—|ÃßCA¼@ÍõÜÛ|l¼ÍŸ»×Ú WFãò9kËàIžàöã;¢­Øþ<;¢-µàã»â-tÞãoQÛCjñ\—ºf"̇ªÄ»ý‹ñb-YgCÖß\÷”òÑlø”jwú÷?ùùú¢ºýêÿù×éËßn×¹ ½]_^í»ý‡Ûo2¬»¤Oÿê•té}ž_\G"ºx¹³‘:ŠT73h²‚Ÿ@²·Ø^êR¦I§ý~vãÕ«ë®—išº˜zN3Oy-y5Y¦~ªXÕy®"9ôµ‡oM§Uhz¼×µÂ#h$âî8 »*«$‹§D"œ$öqY_~®~ÚÿoÿÇÃkýú7ã/ïîK]sv¦Sž Éã.Ž;‘pájÇÃúðaž`á>ö©“y©Z2UïŽÿúÏÿ"¿{wÿ¸,ÆÈ¦9‚÷°`ËŒaÐÔ¡K¦Õx‚*æU—ãšË9Ï%;#úÆÐ…ÉÖy¬±! [^mMM ÛP@. À¬”b¹8I‘”tÍÂSžuòá§[ú ˜X‚}»”vñêx›]߯LW«12¥”ª×¢ x \²eX®Z×Rá¥æåþô8?|H¿‰Ë¸×ÝÞÈ‘3¤ãá:yDBêã¸;}r³»y½Óí7óñ®Hèû ÷ô³_¼úüïºÿåýœ÷«ÎåÛ ×±vi•È<á´LŒýÝßýín7ÄØ}xÿø/¿üúwùÝñ!¯%"kž¬Ëùö›Ûãñèd÷… Ãã'ãîbŒû$£|˜n¿úòÔw»Ë:“ÚíÃ-¼ú’W«TJ1Óæ‹iRæ 2/žØÈk4]¦”R%=ÕÇÓƒâÛþû?+ëû= Õ?Æ/¿þÍÃî±»F¿¿*Öüàv<Üb‰ÜXV†[DNºrY–)9ív»ëýËy¿{xx°R;‘««ëýÐ{ÉÇ _|þ“7ß|yûöðx»b„¤ñb膅r»$k©fªt6³mþÅÌÈ_÷d=<ñ]k‘««AÍØ6ØÏæ0v'm~ï^êd­“q7u“$ÎÄÑI\Õ U†È,bŰTÀD(† Õ(€8”U…ˆªºÂVwfîÔÐö «`"‰»Ý.Ÿ.e™ŽXgPä Æë-%™È¼ñâB”Tòª07Ûú ÝàS!ÄVZ‘„€gEi–¤„sevÀˆ¨ªÂ!Ad "Š1âc.O ½`¦ÅT‰A¶iIÄ ¡-ðM‹AñdèÞOÿpÖ—3 ·Z¦m8¹!W 7÷ʨg«0;I‹Ï2H5…»©n¤åv&6s’Z`k‘Ä W®»K‘Q,X&ÏTªõÆÄº„šðŒ ºz]ërPzd>š¡“–SÖ’  ʼn}„ŒÖµ²ÖåažÈ+)B À\MÅ©!ÁÉuë$H0t3¯%»{ìÕìfÕNn –¢¥- Ø`dNü_جÎL ‰¤‹]”èÌS. k‹ü þN<ÈŒžõE´Á!‚b„ѹtAœ9±µ¹ƒÛ¦ok i²*cbª’Ã ŽÆÕ¶æ-`Ì™©ÑÿüìÞ¦ß'ƒ¢ï™WžÍ‹þrqÕžÍÏ­‰ÎWÅwˆ}¾Ù¹Î7äÇ8ÿs6J=¿†Ú¶¶|Eb‹S0\tC€_¡¦SÉ´=þYŠ IDATšq‚ÓÀÝ î.9íZ«jÉuŠx'#1\l©v!KUc“`‰}ÜùE˜|^–¹º»£’ÜŒÅÕj-n,Qö1¾Øï¯S×årC,eäPâz6èÉæS^Mˆ…•j¥*µ'¬¬«•ì°v~úC#3׿Ù9#³…7ÿŒI ##3r3tn~z_‰(„Ðç<ò ½­økÁžj•vÁ0}÷Ú JJ}ß§Uu™&ŸfE—ÜÔJÄ(€‘‰ ’‚¤”¨ÖÚú!¡@D¼M1Œh392ØO¿²6ik#c¶˜¸W‡{&Òb-™šÀMæBfºI‘ uÙÞv(© ›™’2³£VÓRqu­»Ý~³¯º«*j…›ªj) ‚*Ü!²ýÄæÜœ§+æÖ¨´ÄÎÖnîNNÜhdÌRŒî¾Z…QÓPCH„Tµ ð›¦Å¶¹º® à5˜@ k:.Æ4¡Æ(Žj¢k^"s!… ¡±#‰Š¹eWUs-š»0ÐÅÞÜ^jU³êm/d V· ªê WÚÂcáMíæ(êiKˆpÃà2 æ¬323„•a!€”Ü…EH`ÎNL\ÔÏ+ ÂÇ4ô­!ƒÁ UÈ<˜'ð r‘ÒˈWæWd]9ÖÙŽë2M²J³q%ê☼+Ÿl $˜/  ®„:^òªsægñÝ|ȵ2 MÑÀ86Ÿq;qÝÉÉC}L$lfÕtƒ"š™B¥F?1Ô-C«©”áO¢¢"ËA€èÔIèb$p6]µèåÎm‡gÌ€<™<@8—ÅÌÈèˆlŒ¡F©¨˜2ˆ™ðêFì`%R¢Êä7 jtA!,Á<2‘×–OBç›‰í»š¹?î¨æÿècþ]>Îq^ÞfAç…ý†Vwúh¸2úxê8þÜ·~®FªÁ‚¢ª£*»faN‚!Äè\µ®`U¿0‘Is=œ‹ƒõLiT\q”‚–Îf³yÓòž²;ËJ´°#OòéùëwÓ}¹}?=˱ž*îáG«Yc©Usq†3ÇÁ.®%é|â9Ë:_›_ì/.vãi9|}Z†‹«¤ÆÍ\æf>M‹©v1¹`2ZÕ¬¡7 ,Ø9H`˜+Ef×Ò"óœdÄNdb¤ôœ“ÞÚÈ#Ö¼øðÖJ€Gœt9–‹¡á‹qz>Ø4뺮ë{Sgò ª§ÓÑá¬Ø]cÿÝ _…á²ÇÀjNEúNR¤e¶u±%ßz‚Œà˜dà!È@…¹å I{IýîäuÊæN´ °Aa0³Ê|ŠÇ#YºHzñââå'ñt aä˜øîvZŒr=}õõ·ïO“‡Ò_ñ»oŽË²æ¸Å!u©»B*V×»÷§é˜RX²VÇ×—Q½ûÒ¤ís˜Sí`…8õÑNË¢Šœ+º¸ÇOú_Þ¼CeìS?Æ’#bDzñ¾,ºž™ãÐí®ÇØÉTNÓ4iѵÖà5¦Ðõ‚+Å¢OZlµiÁØ!(Ç;›¨<Z°¿¤O®?{uùéñ5û:Uj­5géã0t¾çµWµIZóñpçZEUS'¯KŸ¹,ê•ȹ-jŸiéõãÁô£s—ïÜkÏãÚã­2Ôs\)¹0“;ÈNj«»+ ¬Lª\]3°"µ%J @!§Ð÷ݰëõP‰ˆ…cJ%¯ZòR9¸7Œˆº(5u¹æí!á†(ã8v]ÇD>|(Ëê§¹@º„)TÂIXÐ å@s h{:fCÉÔœÀg¯2Cܶe³â̽!r‰ÂÆÎnª0C GÏÌr ˜—R˜·ªôyœÊ&~30owu˜WWb×êf8°4Iv«kŸå6ˆ€ƒ„ ªkKÌf¶, €Øõ¡ªVšÅ`”sØ]·ð"°“€…ª1Ffnö!UÍ9ƒHU¹u“ÂÍÝ\S`˜ qR‰ÔjY—¼†Ôw1Ñ8¦R2Aít\£ ÍÉɉ8¦DFÅŠ%†®êäU­âú4B¦m/ôëÔ}K¦r¸µÂQ‰ÀÎìpvˆ„¸èHDˆ‰IXáHÁ¡¤Æà`Dæ°m†)gýUÈn'¥èê I– ÆŽ´÷’jIÂx')¯šsöb¤”YÅœv±!YP"õP H)qD Gæèè]zeZ}9¬P8„Võbµ‚Ü859ˆÌÎâ7ww!r¢_ìêjUÆÌn› ‘…B”6#_–Ū£ §ˆBŒ!Å®ër­[ëÒŠZ³²®(5HÇΪZss‰™³æs³ëp·‡„’‘ºš[Ëãvvh+0SkŠN6ªp5"f"†kÍ:ëÌ-<©¤á A©†å¡À¶"^AsÕÊìBbòÊO¡;MZ´Ö¼Z5„fýbß*jòÆHe&¸U×h¨éí|bA‹©5l­c[\™ – fbv"cLeUÍI‘8Šƒœ¤©'ìÉüú1R°i$‰$@š±–Òsº ¹ tAy(k,Y4 LŒc´\DC(¹–9—Õ÷jï°Ÿv6W_ Õ#‚tÔÉz[lŠ$;–$Ý•†±Ÿêô0›‘› £FR¯¬I †<…å†×âB {Y[< ˜rº­_   ªdȉ6êwXÉ †À’Sâjz*5ôœ~Kn€¸oß×ÀOÃ~>#k™™á¢Zf  ‰(„IhC'PãW<Ílˆ6Gr{:ÿ¸¬fÛrëO §³Hç-ýGƒógç zv ÈG5X ù áîFÏÂ:ŸŸMôgÆŸÕ/ zyÞ¼0`æªu±Ú‹GJ­Šv÷Õ=ERãbneÉk!.#׀й¢áREª "Â4³ôa`ó¬3a%}¬%šâüë~x¸[Œ(Ü+‡,ÈÄÅ–NB ±O±g µÚã)ïÀ½`€w¥†ÓLÇ©\(ÓB$^݈àV…ƆòªðjÕ\U )ÀI‚S5#‰:µ²«Y{4˜² UÕ 1"ysû<DŠ4¤Ðöü¢–¬@dЧýÉóM‘·¸ô›}Ì*ú/´MÕhÛÇPSîúy2¬pn Ìg×ÕvÉ5Í›ûSÔ÷S½tæŒ;ÙÖ nÍÞækjoßþ÷ïð¾ëƒzþÅ*Þô&ÔlHÐ3,Ñÿ kÎþB:¢)8Û;Fh´öfŇƒ~æ:vá ^*yZ§‡{·r˜bó>¯ê^,&CØ%ÁÃñnºõxõ©\ß¼äòÍoÞÞNk\ã.,Ëq6ÄfjÙ$°cF­µï{Uå+>©!xýùÕOÿúUººʲ.ïë.@EŸR®^\`¤ÝëñõÏ^Þ|r³äYé°œ–‡#H­àî¤ßu]Š^ÒíûužòiñbÙ"º„‹1¾z/C¸xÉû 9L§ûÿ~üí¯ßþúýþ.ûP ¨ Öôí»2/åòú¶.HÔ‚œOW—vqqY”wø¿Þ¿ËIxõ)~úóî'¯^©{žë‡o￞÷Èg­c—b-eÖz˜rÎywõž¸ò7úõíoû;|þ9tO!öÝ }?NñäÙk-ÌØ_ô± §&rÑG¾ÿGõï±#zÚ:œ ß&¸éߪ#JÎpîHI` ñ ›©k)SFb,D dr»_^w]Cr Ðè¸áÀóàø á’YBBâ.ÎÄä²@z §H³ð”K´Òe©oßÍ4Õ>2D‰\3*ÃÅ=š† nX[ «zê8²i™ÖùýÃŽ«ŽÅPŽAgP%&‡@‡ZV¬¬cêJ7xŒó¡’SŠ\Ís-ì,&°³5¾œˆ Ž*ìçwkz?63Ï)Mç% ý‘—Ó¦Úm. |7Ë AOuÓÜ…ð šO›  å»A@[Wó´Ç€‰çAðSÂl gØø Oãf{Jqþ®ïàÇlumÇÅ35fK¹mÔnÇuhßëÉ‘ütÿð_Œà—~à)@r†m<¢L‘ ìˆwÓñ³«›Ï¾øë¯¾œîîKµýåþÍWo¨,S=•])”ËË›W·_Þ®ÃU´¨W‚n?{ý³Ÿýâçû›O^}¸ûæ1߯§w§5Ëáá¸Ü«¡¬XOÖuãxœ~õ«_í÷ûÇÇ[ö— Ñ(ÚÅõøæÛÛ¯¿zÿ»_Ÿn‡‘VÔ‘—Ë›Á¡)òr|ü™¥»‹ð곫¨ÑÖxü×+>œ–ÔŸnv/Þ=jµ«ËëÀñýÝ//†ø›/þÓÿþÙÒ¿?Ö‡÷o¦ßþê›·_ayŸ|Š¡µ„¯_Ën(ô—ÃÍpn?ýt}ó5N0s+q>)å4&g/ãC‡¿ýÛŸÿìçŸÝ¼¾Öû¯~óõü;[ªûpÝý⿾ü›ÿúó¹¬ÿò)ë»Ã¿.TcŒqZïã¾K×} –õb=.ïl¿Ã¸Ûsßÿäç¿øúöÝqy¤¤:Žãßüô³›;çõ.²9÷CÖbµVãøxxHLDôúõË¿úùÏòtúöíÛß}ýëÃ#`H‚ù¤V!‚©n±ïÛ¡ãOWæ¸~x û¨¿¥šÓFÕ„×Ì-²ž¨•UŒÀ‘‰²¤ÀRˆìÁÔMµ¸)ˆ p ,ÂBµÚáq¶¹‚ÓÅþŠYN‹›ÄÔi©1ôª¥äµª˜)©ւÀ è"c7 Ãááq:œ`>¤ÁCg¥Ö\U+CR(¦Õà$æ^[Ob†uY°Ö´Ûçiö5ûT«M«ìF7Ó¢ g W­ƺ"I©ëú°HdwE]e¼rÃñáÈÌ)uÅI«‰HŒ)çRk…{1PN»§”æÓ#D†apG`a–eYÈÙr! ªªªîºÌ3[ÚÔ×î-Ã4¤ÈÌ×××뺮8WKçÖÍè4‚»Oljˆ˜9pT¯ÍÿµAÛˆDD­«®Å‰º®+–s–H€Ç%Fuä¼6Úýý}¢‚Žî†>!ª‚¤··ï_½zA.Ãëóý-¬ %ùãØ’2ïî>pê逾›Ž·»Ýðfž™¹æbd q÷Zµ¸¹§€Ú¢E @Á9 î¥VmΖ¦Hl–6s:˲«›4˜›CUÑDƒu®©…$kPM³U ¤îµª1õ)Yu"€ÌÜ 1âˆñ²Ó.ôx‘®úWã:„Xæ>åàèòRo÷;.ür@7—¥œÊEؤ®"Ìý‡}ï´ÿôªÖã°”ûî%szôåq.Å£K€“ÑRöêZ£Ë/HÌÛSX(Qu+¥TÓ”B€Ã\8›7†9‹9­¹žj©IÚá áäL rŠÈΠD2&‰J)s­Y°(rËÙ¨"›¿i7ؘÎ&ö€ÉËÈ{‘¡}qªà}“HÎùhyQ¶0B'ľcun€C'W…;3“}Õ´+9’ ¹8ˆE„ÐnÛ13¹óæ%£ïí(žÆ;þü™ø#üxéÿÜ&°ôC9Ù¿!†êÇTj?öOðòÙ7ÈËV_n²£¶6;o‡|ã5í¶ýi\ßÛ´¢4€À‚%wÀ®KѪˆôã°8¯VU)W_©†ÐQ Zõq™³8¨î¨^t]в°—žhG¸½¬|A’RÙR5IêZ£—ìe["AˆÒZ>¯_ìú$ÃDò;¯_ûR×é" ³Úïï%F˜¬™sQ÷êáf7¾¸¹êkÅrb·W§jÄá¡zÉeÑÕ% }êSJ!Dwª¦Õs­ÅWwZQðÿ²÷®?’$וç¹÷š™{<2³ý DR”@iwZì;‹ýÿý v™ù ‰”DvwuwUfFÆÃÝÍîc?˜GV6»I‘ $qh$ª³³«²2"ÜíÞsÎï¼Ió|¹L‹ÆÒ½%h¡Kå‡ÁÐÝâpÀLݨæèqÁžD^7€±:Óº1Û9 1!BU»Jß%¬<ëxÙóÃ=œÑëŒV±‰éZ;Æþœpd mSß]Zôæ"òp3 s½Ê5/žb¨*¯§î  ‘;}‚ Ww]¡s/ûÁž!/=8Ï_Ðñ›a¡Ú+Á£ðªž«Z·Ö¥?ÖÉNHx8\öwû»×y·¿}ÿÍOOOYRLGÕS=¾zôÊ) $ªTÏ[Læ˜O*øZúË¿Îçóñ²œ,4FO;± .'AO(VïOkËÓ“ªµä»›ÝþvÇIŽ—ãýã:ØtžOÈŠÀPOOq •†<óá)I‘ªK„‡7SÕÉáŽâá|p¯ÇËIJ=žëãÃbÚîÞ”ÛýM&Ôù´y“ñt¯÷ïpüº`,ð‚|ãà¶L´´Y-„ËfܽºÛe^&=]ÌD2¡$3=Þ7G*XFL§ééxŸ6í²èi9.VçVÍ@†¨FJÔ(9JÓÙŽ˜\ÀŒÂ˜¾õ÷㙦o¹¦§Ã…›p›Ù†K;§ÙÏË¢„§Ã·yó6ÝðÝÛÝá´[¾žæ³™×’™ïœïš¨a P²V|æp£ýÂ^xs»cÇV¾­zml¸çËa:?ÍD‡æw7…ÕsÐ_¿ÿêý»y®»Ý.—¡ª9"mžÄœr*»MÊØ\¶Ãy™§ Øfƒ!o¦sÔZÝáÿêãýõ½mˆÎR±ØËÞ$\n % _–¦Õ ’³sÓJd@F§F)€h‹ shÀÂ=\}šæÕž0 xS¼¡%.9%Ѫކʋ¬ekÂ0êNªîâ§,)¥ìnt­ºg3»äD¼Lˆ\DÄËz!c&‘sY°!眳ÛJ'7ÿ˜íóÆê`&áuÕ$ÒA}ãCD,’sîìN®0½ÌX<‚¯çꔞœ³ªªj÷ãQˆ€9¥¤îÏže&îCÝZV"ƒàЦð°èÅiòmçên–‡a½ë¸wfrN\ØÑÝÌÜZêŠ:CFD 5u!ç¼ì¶®A†¨¡hðE$ÛÌ„¥úŒ3T{¶Û)® µx^º…™Eº_áº"ìÇqu×Ü35•×ÍŸsúº;\#Ü0é;Q êöq WD0…\ Ï ?XƒŒ)#”¶¨ƒù€KL6ëQÔSlËÆ 4{À5¦óyùªþq™…ÏdO§¨ç¦µI8ejL TâÉÒE†iÂ2ù<éÔR54 ".ÌÄœˆ"˜Üº3½/ûhDDaððk×»3ˆÐLS÷•™Y kpc¨›μR {ߟ0År–T]+\“,®í¹ó#€hQš IDAT!äU`YŒ{f\ €8¢kD)ÈÌš›9Ô`€vý'ÜÉÃÜ;ÁÇk«ÞCw‹¨f‹µ%lé!Fúˆs ¾H ŠøhÆ¿þ×ïhåÏÒPü[•Øüéñýeÿ÷«ë8ôïÛ¹ú=͜ڄiØ„'m% ?zýÙ6•à}m´,Us¿´e–ïvEŠïçE/“!eŒ»1¥¤ªµz{Їoãá]šö¹å›’7;M›vžŽ$¨È•šdlvþé§ã²'±Ë1Í—‡:+µfÑ0PËÂ5东–ûo†:U»?Ïs[ªG€j†ˆnª! !öŽA2¶›¼Ûóà{;ñ¡N¾D«Îq3Õ‡{W…¥iQ@m¹ÙŒoüvÙÏ—Kùôá›GH »aÿÉXÞÊ÷S\¦ÅêB´pØR/.yÚ¿y•v)mv›v®DRÐátœÕ2I¸ë2-—ǧ#Û|iÓiqÃæÕNJ>ž']Ú²,=‰TÉ(1eF’²Íé¼¼ÙÜùÕW_Ï—ƒxR5úñ›¿«[þ~ÑQâÆ0·ÞoIa€†±“#.±6–*EcvfR·¦KtœóPŠº*à¾QŽsjºT$ Ç6P#&bIήìnA(å\¤$ xSTƒ“"œzuÓÊßÂIR¬A 5¢ªX*§¼„ˆV[s&'ÆÜÀŒËLÒ=\8§Ô,A:¥!ç\ŠÈ&Iò¸CAê^j7„‘ÓzB÷@ 0u@tßÑs’â"½*îœSʹWYÏ#ù5•ÔTUµ÷V÷9IDJ)ÚÄku]ÐJþÒIˆ°f¦ÞãK”®²|¸“C^œKÜÍ@JÃn³]Î  %ÎC¡’¦Fª)C[­õt:3¾»»³aWun­Ù¨…1oò¦°8Õ¹îàèò¢Ðè…P &" ×fÎÝÃÅ~õòÕ|³r¨W]±¡Ç‚#Å‹LmøXHZˆ¡ERâ5Ú°˜6 !ä”Vô\?ó´DžÈq+Ã>ù^øV|Ä©ç6X$šû§Ãmæ”2§9GõÄKp ¥åš`0‘”FÞî‡Ýí ·9$AìŽé5Ë+d†5€@“µê® ®‰EO¶ÅÔmnLað¸Z*"¨ƒ{¢Û[‰ÈÌ„2DÔܳ¦¶=ú~Ó$`1“› •’²°4].f‹ÄL0ŽN³§§žÀZMn/.4±æ(r8S°»„¦Â$ŒfÑÜ›÷íŒ Ž 032·•`p8® „¯ý'è¼} çëröÊþ^w¼„¹x•úá³ÈŸÿcDëDúB)z‰GïE„èj¯zÊÇ¿ƒáõ·÷õy?ìÑ5Õ[ü* q0bÙ–a¸ÙÒbŽ0BJiŒØxÜHÞï"m˜ÁäD… '%BbdŠÁAoˆ?£á.—·”?¥­¤20=¸î…f§?ßn2Uj–"¶îND)Um;/!Î4 „sædç)e#¢p7³NÌ$2»âîJÈæ³9ÔÔm*4þìõgŸÿùiçB:*-XÒ8¸Š©QxO×àìKyí_’WãÊ„ëÂàµë¬»×ãeïoäÊV­¦Ùî¾Ò/ûÀõñ×ý™aÀ)È"®þÙ>Ûü¦øÙ麫Bx­o"q²@P°ˆ¿þ¯*гº™¾Ã²ëÿôô¯ê™í®8E‰‘þÆ¡–¹ø-ïä+.8àø¡½ß~ü£í@¸Ýa$:?„ Ä±Ùæ]Ù %÷½¥”x†Àæ¼Îöþà‰~1G­ ²cC`»AIy·»I9»Ðîöæöîõ²Ô÷ïß.˹lq{óêöæ5:Ûœi{üpŒ£ànËw»×hº©—ÖPƒ@ s_ìnQ>!›[›—Äxóúö'?ûä“·ÃçŸnÃë?ýݾžÁö†ˆŠ›WôêMþÉ_¼Û’ 6_/©<ùY\ƒvCQؘVÓyzºLS³O1O¦-rKŠ’$Ø KH€ƒÑ](»WÃlÊãÓS³ùÓåxz|P8 ä ,—)4Æ<Û¥ãF  q,i#‘üp9žž.g%Ç4:û¥¶vÂÍç8-O§ËbmïÒ8l•åp:<Hts»“4êt˜.—/~ýå7ß"mÇ6[Î…ˆK"™êrx<î¶ãP8ç\µ=mв–9ÔÛn—ooîï[Î-µ¦=›éËŠ‰µ÷#Ör÷¾œõñÂו˜G„÷@J’ÄÒsÑn«cÅC-”‰Ý›· е®Ë‰:ÎAÁK äÒ2†\ì͛ն( à ï+b¬wÐîµÍ¥Tm®Îa®µ¶eA­”K·´¹Gö;òRÀ½¥úãa‹™™ ÂÄ^ƒe3x¹ô†_9 Ñwö˲€ûˆF©‰pÄZʹ7®ÚóùžÖ!îˆ`’Ìy(®ŽDkuçU%‘>çwë@¿ûrN¹5 W˜……Ìiå ÷øæZjÉ G…s^Jý¬IÔZcfÁêiADbÉ9Ï«RRÉy(”I–œ8ËÍN‡Ø·w»W¯ne+:@Û‚à#w]ªó†J3 äÚÝ ¢Ä9±H€ Ä`¡`¢ nk±Ç:ØGo Z-Þ¿qy%J$=“Á™º”äpÁÂ6 ûa3ä<µ¶˜Î®šÄ.è58,"#ˆ< #†]*û´ Qv9¶ ©{0¹ûrÁ¤3¬ .°'m§š%§‡Sœa³:ÁJF¨Ê³,“mj¼>O¡Gmõéqz:úTÃWÐF›†5'O=7³&…£×³öN<<(Œz/‚Ð,Rffé ˆfªD`7ô|ñZÜüÑÌ«Âé1µ:y[WF0 z.k""_ÏCó "!Hô` „ÌÌ o0@ ¾ѬS΀'„0u£d/?áÄTBŠðì홫û‹BñÉýÛ\nþ§‘åwåýžŸÿ~r€ðöõ½FµïºÑ^JÇ¡>Æ[æðoôõuÿq?£;C<ÈÂÝ©yoá&)Fö(aÒ¨êaÊÕÛ$Ø™ÁCF0ªZɘY…½ <ÏZ©"t0ß+  7ŒO¿ÊÊ·”thmf¾”6~ûjà¢ÁNÒÓ£¹xNMhS„²Ê9§2NÆé ?h»w½äTöÛ¡¦FTˆŒØ‚ÌLƒZ3Gùú›ov·¯ÿ§ÿå?½~ûù¿üêñ«5/8[iœ*£õ|k‚<æÏ—)º6±fI„nf0ÇsX‡>ê*üÂ~ö/Mª×­®-ò?ðþ_ÛîŸN @ˆnÄ—ß0 ^½åÏðîç'_ ç9Ц ¼¢zÆ'L0„€Œ  ç"WŽk|‘Vzªr­ÏöëÀæ úc˜ˆþ°U K 3o÷þÞ>¼Ê›»mÚç÷ïÎMQÛ!ívÛ×·7cÕâ«ûûÖÚâ&J™XZò“-ïÚe¼ƒ ,ÍÛÍ0:Øì¶ÛÝ®l ²¼zóúõ›7ó\~<>ÚŒËïß?n¿±«GøæË'Qz½Þ¼vÊù|^êÉ÷7ƒ™ª^žüüÔÇ'ÛŒº¨Æ<ÞÜܽý|ûù_lrRÞUùÅ·›–bÀÉÛåÃåà3ÆÝý{=¿o45s»ÀI.^ìæ ~òãŸî^Ý<<=\žŽ)ªÚóWÕi¶äÁ`pÁ¥xf©s%7X´ ßN§6#ã¼ m’NšÇ\¸°š¦Ä” ÉBî/åL’Ü„f^µ¹µ¶<­‡,ÒyÀ_üün¿ÛR÷‡|ó¥þåažß§ÓÓÃ<*Ôó¤—ó¹ŽËrÁ¸ÙŒÆp¹Ú2Y„-5›1qÁe^îO—sEÙ•›ÍX8]”šú½_Âa~áŒý^Ï—aÈ%ŠŠÛ2Ëv·6Ã(fõxºd‘Ýnww»ùo~5UøÓcmùp<,m /ÏNí«ûƒþ‘ßÓ6'ÏûÖ€aerY'û»;­¤ï5dæ­¹;8RI¹0„Áá`_Ñ  ¸2Ô½ºFðšS"" µUiDƒ+Ä™™6ÛADÚ¢Ëe!%[R.ö¬˜_BI2‹Bt­=ëôöÐ0q-‚™„­†¡o+(‚œ·0w£ÄݶæÈœsÎY˜òépö¶öØ\3WÌýÄIÂDÌëQÌÖÖ`f)=kVnfÃv µ#+rN˜3«kg2Ñ•å]k%¢Ín÷ñÚÏþ6%Rmî°ÎŒsëÉ/¢Óª•‘ôÁnÞðíè£@QÕDˆ„YžËmÌìŠ@ªnH2”Rµ¢›Ý¡m™[­š’çMo†L0¥‹´yÅI‰N¤(‚”ш)h“J!!"F¤^nŨÞaÜf¾’bm1qÿî<´.kãÙL…þ ¯%pAZK`#éf³Ý›ˆ¨6MZ×&éyÅIDim¤ pwJH ¥H¤ B…¨ÀSD¢œ2æBmGÛ¢B´Ó2ÝOË{ÅòQ¸1àI¡hZg?¢5 žKÝè¨ú´èäÍ0Y,Ô q©ÀHC 0{ˆƒ<8@þ±Ý}?½2ÃûœÉI„ȃ¢s»9‚¯D„.(ºzïö°™©zm6“MˆÊ`by¡ùÇ2Ãëÿ½G)Øœ,)¡ eÖ»â ú°Ãà&@"J´r{,è¹È“Еcf^qâ°&صžõš úîOæ7ÎãßÚ%ú§Ç¿š:ô½Ï÷íw3ôš úÍ­±_ßà/Ó\ÿö.Çï÷õ­C<ÇL>‡IØbªª,DÉQÔ÷Â7ÈKÄùRc™‰ " 9Bçf' <$9µ–@£#b6{šÚB’7rß{Üß@~äü ñë"!-Új»èr©[[nµ~*2”ÔÛT]l‰hÌç°jº„“Y81öeÌL'B&×ÚÎÖ.uZ» %ŒN®DFì`Ö8õx?ÎïNñÓ¿Œ`}8·Ç‹ÔˆY©F0ÀºƒÞ# Go7ˆïèl9g„ܽ߸»Nðì'w1¿,axIŸ[p}p Š ¡•·°Ê@×× ÇÇŽP ï ÌÞ Í µ$ÕW¸n|/O—F"ÃvH–(!1•únhŽGhà4cs§‰RÌ’h ‰FµìŠ‹Ž9¹¸lqí¼Ì> Í„­™Õ—ÀgŸ±±o÷Ãf3þoÿù}}÷æ›/ÞýÓ/ÿy™¾¾ÿïþùøpZîKõ†ýyÜåaÌlËòxÿ´|¥‡Çz:Â+b`rBbl ps»Mon/K.ËbËC&Y"+dv2‹aSvw… ßÌcÁ€¢ç…ªK–mÞx’mŠ$ñ˜ksk»›|ww³ÝÜåáݸÅå4?¾øðèµa”rŽfÊý1Îáùzí§Ð~˜GD„ DìÞ“ënÖ)Ø+7"¼é³¥f•|•r lÌ´_91Â+Ü@™RáœÌ"æmn~™%'Pëo«€®«&†¨U¸&fÉ"I †"£©Â]òRjs5‹ÔApypÜà®Ï“FDêß03;BnV[k¡Ôܽ{a}¤”ÒªyôÊcZ°5TÚ!r='ƒ+!À¼yK‘¡nâ³¼/\@½|»;×ߪŒEɬšk‰Œ):†½'mˆ{ËB'ªq(¹{ÁÂͺã®ßÌŒˆ8È€po­`î R7«fîÎC©ÓÄ»q¿Û;ûét°i9=žœu»¨PÞŸf‚Fk3jM™™™R ã¾×g¢Þö9ÚªU€:Ÿ3HÃ-zCnÿY„ûŠŠ¸î­Wˆ÷@ÍZ—EÜÙ,y¤ÀÒ¶ YÒ´Ì­µª­œ`Bêî9(;¡×Y0A)C HkA©â6Òm ¯"ŠrNfàhD[&Ìç1óÈyßÚ«Ä7™$å‰ôè1[«Î(" °|±4 JÆÅc²Û »‘ÇÊÐebo¶P.n¡ ˜5PŒ&@¿>êÞ½û»÷ÿϯš‡ÎÈ¡8±K I—©3™عDÑa8Ïë’~[ùþ÷ånq½Ðÿög÷e»Ñ¢ð»d¥NŽëµŽ_t¯{gðÙ¶wEüÓÕ5'D~]®ö0§?Gפôšö\G¬®Æ_ß/ ^ý¹v [Å ™` ðÿ¿4"q ð†GÌ|{³³i)ÒΧCxòç'§aÜ¿~s³è×ç‡ÇËIØæÎd€yLi0v¥šCüBØÉÍÝÝÍÝíãôpœ‹.ÇÇzª•"a|zî7uš‡ºÛ¤»;öíæ!¡žÚÒæ$™±+Mc>Ÿæ¹‘@rÒ@F2%]B”nsζ%s¯SÚˆËÓôáFaÛxåÓ‚–q÷ Ýn‡]Cç2Ï•/’±Ù¿òìór°é„²¡››7‰o’Ü„7GPòiƇǨË?bØ,•¦Ãœ(mw7ªznjê2œ9Ë^\›’-m:ðvv©Cv4­ÖnÇ  AxH<Ÿêto¾˜`¹À¼Ç¶?ý镆¡Í~óúí«ÇûG¦Tòy!¥ËƒMB2pÞo„x9?ÿ ¹îŽÓ|ÆfÀ¾Ù!§Ég8ãÍ~w÷éër»{¼œß½ÿ0§fLJ·û5œ\ˆ%1çL)SÜXj5beâ]‚\c3+²šˆ«Õ>:mª†°ŽÞ¨¹gþh7!ˆp§¡ºxsr©ó<µ9$bäN ïõ×þ<ü¶Ë‰™!1±;C19ÔL…µ#§A䈫U³7ºÁ©OY"ë4ºïôNçÁü\‚tµ(÷W­_CDWP­_Ïýøˆ‚èßvïo»JŽñ¦ø#pÍ]ûjú=XÑû@ƒøfw+þduyz@’Ö¦ûÓÓüæÕþîîî<ŸžŽæiY mZ惂‘±PÅól‡É–úŽHöÃŽJŠ,T¢!nXÐJm6c9ƒLǤÝÀ¥8gwŽíò€nõ67‹eR HéöÕ 'Yæzªs­ÁÆf¡u!™K.¼ÔYç0¥D9.@ÚãÍgçŸz>çÓƒÓ¬ Ä/CÙÞlÆ„Ðs­‘ÇéøþéñÝA¶íò4Ù™pÁå“É!Q©”!¥ìÖ.í²Ì*ˆ° ‹ YuÓ¾1å6· fX›á6y[RÉ×óÙ’}s'û}Ybq&äçûk¦ªítzZîÞœN§óyªU°ºDNc¡T¸$ÆRÛ÷zÈ|¨„ÜühØæ-Ï<¿›/3,nFì%6Â1äÝNà<ë²¼ÚÜ$GB4«Œ*œYâ·ŸŒóÓÅ›\áÍîxüé§Ÿ]êññx||üpxòýC™–S;ªVÙïï¼.çÃãXš-йuï­±Bÿ®áx8ácð°Ÿ·:•*rïWD,×ÍtdD‘saAD4k­Ö¾ö€1‹ Ü4<„¥(Ä( gfqoà ¢0Z‚ȨˆŒ’Ç>J©N-QBs@Ro ª­õ}cJLÄì053´‰™³t#ÐRQ« #gr*ìÁ½¿Aý´Ž`b¡DÙ™Ìt½2Ôªª'NûniëåØáGPÈ:Hhx˜Á dy›Û"ˆpw bN›éjI¨äɽùv»ê^ê"ìZ‹:“o… c]o‘ªjÏ­ûzÙ 7ê³S º¬ w%¿Ÿ8„’sN"Ž étQU¸š‘:RaŽÖÀaÈi‰ÖÚ0–œsI\/†©A œ¤À><ê«P« Ê(£›–=ÌÕ¸Bˆ ðàÚÜÒûÇŽPïeBd ‰(,IÄ="Ô¯5Ä´šÄÄ`^!lýöq  $G7|jÔ¥ÕæMû݈?³ÆõÍL)QeA‚Ü©j¸+©FN›×¯v™íÐj es~xŠ™xFªÌ x¤b„µËcÚïÇñM¢§¨ O5OgÃÀÈY`Ü|;”")#’ ï µ8Íál™àÌ! ! îã|8^LB´ÒóݽQB)Z …뵆ƒA ””™:æbÈ&ÚÚ8QB¯·e¢ð¾)];‡ÑYp]”Âê!BƒÜ‰¥? Läp 7@A¨5 ëûYòîK‘pq¡gº·“¯É  'JH‰‘“Ä2a „ñzJŠ÷ݪ;ñ ¡Âû‰ŠÿÈ=º6PÇo~¤øáÏÿÇÊ4ÿN ç÷ùú?`…¶îÝ^ˆpt½ˆ÷‡ô9!ácî¢_}é‡$ ¿;B`ßåÌ„38K„yƒÅ¬m`‰Äl<˜îÁEøÕX¦±La9P2EÊ皦Z§ZÉÉôÉëÎ%afZR.YfæpÊA#ÉF„}Ê|*q¾­ö5Ùyö!¯Ëæ¶jK"ãPŸ¼ò´ÔåÜëѹ…Ïá‚™ònË%]ó㲜µ5N‰øâÄR[rp"aV‚†&—§ ‡¿ÝnóvX–¥+I\ IDATC8 ŠÝC`æŠ *¹#†@=Ô’¦ÕÜ[„c¥Õ®ØéufàN¦x­Z[‹Öz «¤Ó}ýõæÄÄëØqÀ×.2 éfhFPçoƒ¯%jqõŒò z±SYù«!%uÄâcs½A98ˆ8((¸GWƒëÕ6zýÖJt¡î»yžÛú/,V“]·öýhDþÝTá3ð>•Ã÷ €Î6 ¥¼»ÿj“Æ…ö›­ªbÐÍÖÕ.çm’²I·çùpz‚3nnðöõívØÂbñF7i³Ý\æ)1Nªß¾Õ7>•ù1Ÿ[„7¯àpFI8|ƒúˆOîÊf»÷|›|3TÉóB—G¼ÞñlO¥.Ðcó‹Üy(¶;£ööɶ£¸„]\ç R5ô6v_¾<—Œÿùÿxû£·öWó×’ÇüûwÎË4&çeÜz'ÓqÜÄ›Ïk]|™&=^~õß~ñù>ñ³Ì÷<^nnÛ1î17,joî6ƒŒ_?± ry|Пüìn€Q’4&°ßÉPïOÒ°<¸Ô‹$šc¾ýlûã½6´ûÇ-oæ)òb¤Œàü”ï.›Oôö no_ÛWÓx •‡ÃáýW|j_þý—9Dd÷Š#J2lxóÙÝ›±Å‡¯¿¤"Pýöx]0mðæ/7?ý³¿º+·ç¯žüe¼O•ôiïùíX Ãí«Ïù¶¾#o¶»Ûè2å‘’pqÜ–l¢útZNI1ø­LN‹mîô–dñ™d‰ä·ŸâG¯?ŸŸô«_ˆò¸K”ÛÍø4¶}ô &äœUk7Kõ˜òÇ}ÉÊšƒõØh$FÒB²QSÐu3¢(ÁT›$îîÚû=9çl—™"L ’T¡0ÕÒ,ØÙì• hÙÒP$“ä]„<—œK:NÇOŽƒÁtjˆ”DR]bfÂH‚H q`SZ[f«Xˆ™ •J€:…”ù±bL7Û7î±, Ép¥QCJJ‰‰Â´µVça“³‰tVmÛHIm¾XJœGus2k0Bs”’ä”$kÔÜÁe€‡¡0Ä,afÄ¥žÎåf[Ã6i;=‰yöIU# )Pr‡ÁCÑÄpï|ý iÕ©ÈèÅ—yŠei&Iˆ!ìÞ³XIÉÔÌÁBDiìÖíP­æÁâî­™#´”1‰´fÌ$á—ÓdÈ”lÑi¹tXÆ!mKm—ãÇã–¨(q; ¯ò¶X–zöË¢p­"SÛ²ldl ÊîÍ‚´¸S¸Þ,L`DPm@Œ 9ñÀ”)B¨dYÌž—wÞmÙa±Î–PŒ”„‘ íCCáHn~Öù‚è¦1k­z 5×9œYlæqSn¶ÃÍ6ö7¶ÿ »×Ìû(7£áüt8jLóÀÁQÆÍ†ó0Üùd§§Ãüµò” ËBõ<ÕY#À Bæ1I Ú5Ù¼Óý¬qUw±©Ùä «œ¬ÌF¸û²´eЧÀœˆÓ˜™Â½µ #É.I<¼z[Ö§8R[ôN騈Fd,Ä$Ħ-oDR8j˜s.ã|jË]ÎTrk–Ða€tb à… ±ìŽ0r‘P°a„àêµi³”Ű Qqã0s(ØM Ã0Ì:OT²´¦þWõ³øÅ?ûíý‡‡ ¼¼~3/MÊnÔÖ†!•”çã™L 9k{[²”Í¥n\O:q…N¬~Bë'_~\ù#ßûøi¢ô–É÷Î*¿>~cŠç /¾Ãô¾_ðзnù%¾ï :ù§<›âzΠһשY ¢o?<ú<Õ=QdY†4ŽÑ†x|}Ÿù´ß¨3§ÁÍ ø¶ä >ÕÓlÖ˜eôl¡¦7icœžÔ*p)iæøª]>çLV-MzV–¹"j] Y‘)gaé9QÕ%• …ÖKaÞo6I(ÔÌTm©fÎäÆPH­ÓdÑš¹p‚¹µÚd,Dà 77SÃJCJ4rJ«sLÝÃmuÐÑw^UçÎPùŽçr Z¬ýß}'H „)3‚ƒ)¼ïÒz?;ÄH$¼æÞàªBéð«.PÕç)k­>»’ûßÄÃ(˜×}tï™vgî&Ñïké|Ð늉„(@‚Tݛ۟kŽ~‹ÏÕ3›k«Ëôˆ¹¦ýͰݔ2lÊÆÜ«k¾ÔæKuí׈†ä”ó°ÙlÌlÑv¹ÌÓ¢îFI‚i™¿øö]ó¶¹Ýüô³OöcÉ;<´ûK=±'_¦ù ñ´omãæÓ{k³éAtnŸ~öj I’ê-%rzû_ÿïÿÎB À7¯ðgñæ'?¿ûó¿É14Éû¶¤wï¿üû/¿þÕ\Øg,ç¥Pžç¦ Ú&bÆ&çrqÞ–4ä1ìí¨Ÿ½½“ÏËÝÏ>{óãÏ`x²“"fDÅW÷ß>ÚeyjÙÆ¢›Ó·'š‘)N'ÓÉ“Pž!Èn÷Ãø:}q|ô>®™ä|™¾úÇ_—Ç»Ÿnˆ?ýñ-I¾ï2L_eRÙì÷Mãp¹LçÙZß±°«]Ç!üÎHÛï7‘׊´ˆv¤5›Ìµ p·èíA¶vÝô«EÀͬŒˆ¥ÎÖC ëJã¸P Ÿc6TxSw8N© )ekªÑ|ÑZ+"¢y_}“_0Wøf„™õÊHâg€ eóhM«/0 "(Ø5´6–•÷¶¾c³€fÍÃÜäë&©ï®‚ÉîpoKC˜¤± €‡…9´¦íÞ\C=ÐÇB‹ s ˜Ñ‹½Ý»†×Ù2Äy@#ÔÈH„›ÕÐÇŽ$YDˆd:œàŽ~Q „D$´çžüù¾Ïk ]¬É£¾„ëœÒ«x¸fvˆ `0sS³n,\Qypê=T¹;›úz”‰(È"\—sÚ–œ¸0©y4ŤìKÖskê-”.¯9¢Cå %^ÛÕÁ%sU„¹‡…· 5S"¢  0‡™ÁÚª1ü}å  «ÜÓí†àˆ  ##I ’¶*P Ú1ÐëáXÈÅÙ¬ › L9•=ïÞ”»Ï‹|N›?ÛrIÃ&Úž'¡‡e>^¦Ç¥¾öW©Ñ¨#TQ=/‰Ò ›H ñ8.‰ x‘W—2ΘlP!5RÀˆÁËeqÖ !a–Š3;UerêcŒV‰‡ )ÁãÞO bf缺ZûXЭüÀ ‘Î… ' 3å$⨋^TgÆ’ö¹®R‚ØqÍ/AÒuqOD¡`‚$HôºM"¾÷eBH;?± äõaÈ›²#"É©Œñ¿ÿ—ÿòóŸÿ|Áÿõáðø×û·gµ–Ë'›ÛÍWïýîÝûïKJbv³ÙV]®Õ)ëkýer’_x·ì èŽÞüñâìþ»?þG;wüàôð²ä»_OßÑ|¾ÿWþAXù‹ªîŠÐâû?Ã~ê|öDyüD¡›Ábr>%P€6áÉ`¦‹Óì¼+EbìÉ2SØwO$™…IÜiqWJ3Ò…XH\¢&öTDèä!A;0›'lF8³=)}0»÷ÿ—¼7ë±,É®ôÖÞÛÌι“™YYd55ºB‚ ^ô ô¢Ø­?¢'©ÑB‹I©›bו1úp‡sŽÙô`Ç="³2Y,‚TÕŽ€Ãã†{øÎ5³½÷ZßÒ{ó™Å2—ËtÉi $fjÁj`w÷ ˜ç™Áp TÁ‰ÉÁI…kÚyRõZë¢AH" §[Pƒ"Q»“Â{ø³G¬´¥èž>ê´uXO(O»L‡¬A=øÝ¨êž°ÊÁ‘è[³Ùo‘oÉù[—ì'µê÷U¼OnÁû¦èÔÏ `ïkÝ;ô]cÙ§£ |ìžÐÓ_:B¼wkñÃp_Ir ~7ú× ð“’'VÀûSªÁï­¨[—?íµôº““„£5SÇ¥©4ÙŒ)u^G]oÅc (6‚”sS=^ÎfVëâAI˜rl·[—ù\Ï-û›Ý«Ï¾øÃ?þ1ã?­¯î³Sfƒ_.—ýeJœƒuzx|œÃðq‘‡Æ=íRæe—-É––Ë|1CÆv_’“µ˜2§¼y¹)—ÔÞçS›gG±œü—?}}>Ÿ‡q¬Kܽ;‹ÊõG÷AdH;É\EUÀñ„‡3ÊýÛív»ÛlSášš5ƒ7Ô)¬žRJ^+W¥´ãÅM}n:×¥NA3Šb €,å´Ý•«ýî°Sbòr½ßP÷›m\½ØÿÉ?ýÓ?ýg_Êî4éQ5ÕK½ûÕñW?›—3®¯ðòzâˆØ†ý°•2ž.õø~BóS;BmŽyIcºÝóO~ò“›ÿì•Ün–h?ÿå/ù·¿¬÷Óa<Üîóc}äGŸßNêJиßÒ6µ55R0†#¥q·ß§C³<Æ8”Lçóñ›wùGéúêzu«n:‘%¥£róùÃåáááø8k[µCföߎõ@LXD)` C8V š¡Ûݵ÷ÙÄ=:¥yËYÜÝÜž‘UiËÜè€`O6ž”Dr’Å´^ª5mówWm›š;M`Hæˆp, ð°0Ô‰ÊfKfѺ¨6D¢€™/µ:§LD}yCR¤”ÜUMÃà”ú³Ï"BÝaƒõtâp¸Á”Iœ‰Âa 5¨«Xw#´µXJ ïà™'þvZéh€5ÕaD©äNîÞŸ`‡1$õÞ“ŒÐï¶wz(ü?L^ŸÜèÙÚѹȫRŸ"…Ãé)ŘÀèš±PE˜ÃÀOœQÀ%e‹þJiâÒï¾õgÕSf–ÐÑ 3„JÎÕNÖY({43 "NIZ,ÈY ÔQÕÄj°¯á-`AaÄαÑjrs„F3H†ùŠ"#t¯ ¯%1AáO¨ eL9[•|n~ :¤Á-Äœ:à»E88"€h{òÆŽh'-Ï–ªgÐPJI#§K£v¶×_¿Ëwlo»·árF>òp¢2‡»#Cž²+;Ñ‘R§ÉF˜3zñC Ž$ý`UƒH ¦@á<º-æÅ12qo”®9ç°R‘ D\k/‹'¾_fåöªžÿÝûߘdlwŸýä¿ø'øoþüßþÅ_þÕ¿þ×ÿ[›f«uÌãét.)‘Üå“„qöoŸìÿÁ¶Êß1Å}rj[Ãu¿Õ:ÿ´Èùõ¯Ÿ8Ïhõüε4¢_«{¾[O†Ó¶è>'ÿTCÄÆ$" ñ”HpNéâ|ÔØ,C¡Â¤ USUg.)Í´*RÏë#çVÝk¸'Î"Vk l÷¡ïëeTNDƘ(\]g‘*©¥\CÉêæWÁ/h¸Ž¢¡S¸±Î£ˆ3oF¦2š7'Ì94pªÖ,­³œ“Ô@󍿥3'‘„Y[ Ó‘·6½z,t—ž’­ðËîQ]ÃU}MìÀSHuI¿wñ61=ÁA;RµÉ3Ÿ¨“QùÉ&ôÑJDg}ô½yô?p9àº^˜J2HO£Síî¡~§"¤ˆï’?è¼ÿ³¦î©ƒ°ÎP™z܈+Òæã¿>_BÔqzOvP·+÷(Øßç*ºvnèQ05«Ì\ÆpRðbHy³1‘f5µ¥ LÛŠå„!A)ª633³Öª™™¹B-"„Ò~›˜™CN_¥¡ ¤%¢.Ë\½U â›_¼oF?´jÁŠH*µÚÝ/ê´«6¶ ÊA…0ZãÓ„T°½Ú$ÚÅ1pÚçÍ«´ÿê@Ë0“W?Ñ„’ùj·½{{šŸÏÃæì&§Çúøz€Q[ ™ˆsIp÷j~}‹Ó„†¨±df¥dƒ§û+ÜÜB2H¦YMÌ`‘¯¿þFMA@Ê›ÌÛœêÉNítz¤ª­5K"œö‡Ã‹/Y.ó×o^ÿÕÿù×wÿÁ7ÀÕ‹ýÕx8½=&§<Ãçù\1xJi»+Q¹Zm†4óËR÷Àg_~‘‡dƒo–Ý8"Ù’·v2FÙmŸ]Îçãã‡Çù~jÍö¾»›îïNӴ꧈(âï–†ÿƒ„ ä (ÐÅ kR=ˆždú]wâp3„8‘‡#¬UP–²ÉœÈkkX´M‚$„ÔWB)qbrw«ÞæVçæM£9‚A·ÓN&èJâ”Ò è6íÕ;@áañÐLÚýö,©çiTF@˜ ÄÁÒ‰ p¢Ì"z €¹GÏÚ^[E,âìV—¥^.AØŒÅó&ÔèIËAnâ~2CÏØ 3z‚k›6N`5›#„…’ˆiXh_°m3lܬÁ¼5`ÐU”‰m5w2ƒŒ –89„"õ'1]òtü "8ÇjЧŽi@ß¹YRhsw˜¬w ‰)̼õÙ ƒÄs’K¦´É¡Tç¹.@Ê‘Þ@– e8h-”ÚÒf_–dÌAìáAÌ’›{ 9<гIÃÃ,ÐüY€DNk"y 9N«‡¡‘I2*iH2Ì £ù…iÊÉRŠ`bJD·>¶c6ò,HÉ)yHxf+¦…#ÛûËÝyhUÄ/CèÆ å”äõý‡òXø2ƒâ3ò™ÒD›šÃRA=W¤!˜ÝÍ.æfêqQŸ“úQA s5ïyDްpÊ#‘¬ÉàÔ_SPâ9±Ã©³°"š[õhaÚ£[ÑÑ……îNtK§Ÿu™ªzN”Ø­£ç%>±ð'?OÇ–Þüí¢X°pJ∦ªKu£,È"$g§D–BŠ»P¢°ÀÔ¸\Ê8L©J4Þïþâ?üMùÑçm3\ÿÁWügÿù›ûã¿ûÙüóŸýôO?üÙ¿ý¿þò›×¯õö{ŒÌ:aÕå$äÎnsöOç¡ß>Çÿž#è»G°¿Ÿ¨Ÿ^;;¾¬Š§–¿cjôÛ! ¾'’èÿõÜ¡”Â+.…¨Õ,3¸eÎH©Uœh¶8…ßS(C°†ÔàL¤L7°ƒf·Å|Џ rI,SÓŒÄcØ»¦£û–¹hxusŠðAŒ]ÕMymú W<\,Qœ¥&dó2ppSWÕêQ)f`LùâúXÛãR…j’•2朖Â̪wI”)eJ®Ä|ï´Zb"ÊñiX­{cX¹?ô‘ Ìלr"ìéÜÒ©nOâ5x­¯TŸrrŸÞ¼N¿Õè–ëʼnõÁyPæÜ!¥ó@ÏÁxö!~«"úè©Æ=Dë@«×EôG»>ò§à€ï”OOã'pLç‡ÓñÞÌ.S½?Mç9v»|{õj»Ýïn6xxmÛ^ï^þè6›y¨§éüp9^¢æ0Z6bnÐóeþæý/tˆ»ÇãùƒcA0–S»ŸŽ£•Ar¥ÅÖê¼XÊS¶Æ³ÊR5œ1îÀEÌa ±Èözx6ûõÔæ'lOçññTnG'T«³Í³Õó÷ï¦ãŸN0{öªõ’À¿Õ#ü;GXj+6Zm üd€‘>Ra˜ÕºO±'óô ƒ3çQH¨5ujHf…23”I $…W»Ú¼LµÕyÙê€"ÉÏCô~›G B8[„yŸÜyP¸c(`ZZ…‡©!¥¾Æ‰ˆ»ÛQ]´&Dnj¡Dæ\J„õˆRêëx»?k>úÑÕœ“1 $"Á©»(ðÀ  ˜qD„ˆl™ÝóúÚ‰ô ÌÝ—iâT²$"&J!$‰$X<˜˜õé´ÂFŽÐ¦Ž`±°¸÷ ©þ ½‡!tÖ·ñš"Ï|÷Š„B½ê)F`fcî¹Ýo_3f"@d­NÓyY&À¤$­Á§EJȦ¤±,SEôHñpÕUË$AáÄJ\Ylí¥”Œˆ\'×f °€’ˆ<„ˆƒ˜Ö‡` AêÎ+”!JLYxΕÆH¼¨=šEª°‰ „©3ÉCÉ™#ôO)å(£ØÈ±ÁÂêÓ0€s[|Z¼Mn'¹9|ž5a®i´"*feFž)Ûss¦4;’A`ŽçêQ-f90GÔ *²„/îA`r9䲯úº­!^€KâzâÅ«;9싹ºY8X¸“®‰(<±$ Esa.’ˆ¤š7`– ‹`0˳½‚‚¨¿ïôDv§'*7eaN)ÁTÝ\‘=\"„EH à0A$R&Hpu?l$¨6,­ËlÿÃÿô?My¼ÿæÍ»—ñ¤aw_§ÿõÏ–Íðúþƒæ´»½¦9âqYH¸^<¤³LÂûÕè¢Òõ8Â`Ò¹ü^ ƒèsüýç¿£úÄ…ÄŸ&>UÕ­soÿ×O ¤_?¬~ïtèc¼Ïïšj.ÀJÉ ´„/Ö#=žÔiöx A05ÂðŠ@RÎÖ£j9°åì$™ü¶D<†_8"ŸcJQv îÄM`O´ Þ°â3E¨©€SŽ1ÿl9ï%®|3`Øp èmaš$A(Qƒ+AA-Obko=$å’sN ¶ˆŽ‹ÜHJ²æÎ$DÁl h„ÈJA 3u0˜Ü%§D²U½×5ɽiûL¿&f_“KsNþ­Ò8V¹Éª4ûöÝÉûßgæÉ8¡s\œúž #bíŠlšÛH¯ëx­ˆúC{æÉÈSf¾ã¯ë¿â‰)×è×ÌŸÞdˆ^u®_¬nç'èÈïk¯æÙHÏ©ÌäÑù®a*5ΙS¼}ww®º¹ÊÃnwýêfw=>Û•ñëŸÿåCNì5#€“ ƒpØË—·‡Ã!4§ótž* |Å÷}ùL¿ ÎªnÑ …±ß^}qó£YOô×h Þ€áz?̱ԊI»ÝüÁÍáÕ6íòðæõÝ»û:Ùùt®öW‡²_|uعµÚ^7»ó|ß´Æ|lŸ}õòRçc5° %®Ê°/zÉÊ)¥Ãaw}}U6żU]Þß¿k~Ú…3s’aSn¿|ùÕw_¼ºzx¼›Ê#?D)ÃÍý‡éîÃ6 Û!%4YÄv7.‹/í2ÕK})cÈ”rr„2²k\Ï÷Zkï½Û"lëÙ^óþO_þQÊ%enÑê¢s óYëÂ6$0¯dírþÅ/~qôËDúðxlGÈÀriþòú0¤<¥Å`ê4º]¿Ú½|u£¨[OórJ‰®®·¹pDLÓt÷«û\xˆMx3ï`(jНy9ÚOç˜÷W»n‘7à<'¿\P À óçkìï¯+ÿ 5S'©s¸Á¢¼pŸB0Q—Õu! Áž‚QVŠѰ¥ «·ª®()'ææ´2L©09wqZ¸z­Õ¦j Ä½1N$îòü0£Û—Rô|“xš•ôñvÞÀám §œ„{Ì‘€¬,™¤‹×œHUá *‰ˆYX+c“: p@¬Võr%gç$×ZKÊD`Gwõt än]|'ÑÑ:ýÅb÷Þ@bpJ©T70¥”!éÙÇåîîÍB{aç}S·BP‹`ÂÂà @ížOã` ¢×hÔxIJâ^ˆŸäP ê»]§~Ç—¤Geö¢È‚ Nk«°šª)"œ¸? ZI‰™Üœ(”‚)·eBN€›ª‡õòÐJ)Iƒ™"g"^מ !Ä=Õ›‰àÄ"ëöѱé]DÉ„5 $À Î@æ¼oAÐdz±é¨ÓDQ{¬£Ý©Ë&¡‰˜!!Dpr‹˜a›m!œ}> å’6;— Ô¬M‹ŸBOçÈ“QsjÁ‹KÃài/ˆ,¼ysjÞ½a€Er †Wˆ2ÜB Zj«ðz£’{ýÁ J™E’DúÜ¡+ÚÔKú@0‚ej2P˜BB ɦ䒲S«Ê™ËÒ IDAT ÜYºÕ¬‡Õ2ˆŸhN}ÚÖc_ÓNÍfGŽHLB\X(ž¢Q ÌÈ9§”ˆÒâÞȜѳêN}Y&ÙlG–)ÚæpûbsEËÜÆô¿þ›ÿ½õWuÌþW‰”Oµþǯ¿þŇw‹iÙneLÃv,,?ýÛŸÝfbJÙ£ôøY2GÏÝ'øµåü{Kææo‡žKÒ¿ëgâ[[E_Rø7ÕN¿qwùÏð'á§ÿQ¶ÿ±ª¯¾f[xmma”Â@u§ˆYèD`SÀ[0S7‡ºÈL’R¤Ôç¨kø9°8D]Yzš…„Èžðä”IHø:D»7Ÿµ Ñ‘üoŸ¡–”¯Sž,Îð³Ù»‡;7¥Víb>…O„ “¶ "§TrQ†)Ì$8‰š•ðÌ’$6)œªÎÑÂî„®¡p‰Ä]ÍÄÜ“WýÀŸš‹Ï/A€œYÛüÔÍOÀÏ(¹ïê1ã·Å¬HJ{2 wš(ˆW½½¯Ó,zÊÿ[/°†«>K;AÌñÑ_Ô¿–î­~ÊÒê¡m«Óé‰0O~!|ò0#Â>ažôu¼wp~o+¢OXßQžs¼v\³WÌÔî.²ÁöfC’ AÂãv¼¾½©_ºhá@õH)ùp-|ˆÝn7Žã|žÛR—©¶®ö‡6ÛîWØW4¯3RƒPº¾ºâÍ–¼].—¥ž±¡á°½*‡¼Ð2×éâ—(È7róÕþËòÅË/?{ùöÕ›_½{ýó÷_ŸßžÌÏËåñô˜î|*²6Ï’Ç<¶fõb?ÿé7È6^_}õâö³îîÞµxJFÞåšÔ-<ÔB·Û­ZÝïã¦8¬µf³/­•—[¼J<ä›úò3Æn·ËyØ”ýã‡)¿~h?ûp·ÜéûûãÙ[¦%öH¶ÌUU‹ÂÛ-öÆMÞj}¼\ì>B` wè] no¶e³Y.ííüw1é<ÇYS“B_ýfY–ã}½!#’!ïJl±q·•‘#h;îNwïOïgä@!ITt<—–OÓ%Ì#ç„rÍåVnv7Ì®vØl†W‡ÇÇÇû»÷ï–sºÛì7» X(ǰÛ_1)ïÛüá°¼þòÇŸÃi,›¶©9{Ù–åTW@Oï5ýãµ>»Q–#Ðë"dÜQ¶j+|íÍôUÆáу9€È9­¡:Á=]üíÀBÂUuv« e3)‘¹y¸ÇzŠéFn"t/¼sêú5·”Ì9 $¤ÑÔš¹À‰#º]„B,±B…n \@®‹…†$bâ®Ç[ñ®Æêa?d@¨=åaJ" €Øpon¡Ö;``Öè)¨€‘€È=Â2R´ª pX"¥¼¹ÚVU]Tµã¿ ˜gÎ}ŠEÄ0#Vr-Ëz •„DÄÖ©Õ& aôÐ9apƒE˜¹‹§ƒºû‹ÁŠV£Ð°0 ”ƒ{ùçˆ.–ÊCDC.eØÔÖš÷yŽ$·™,–YNʉFa¶æh e`´Vkõˆ€Ôªá7ˆ0‚r@ÝÂ8G1£oSôI~| ؉:{‚¨Så‚<J‘%lDì)äsÔÚΓ]jf¥dìNN ]Ça ˆ†4ääI”S°„á¦MC¡5ä¢N‰tZÑ*´ØÝëwüãc쎔/ÉÓ ’VÁ<9‰Ã¼ë×Hê¬æ¨գ•əÁLÂ=}• ع\)TÌ%‰2ó@Ä  h­†5x0³DäXeá7¨«$0¸g‘ì&áb1$‰’ÙÔÚ<ÏN‡z³†@Q„­‡ã€ø ÛIM¡Ê $áœH Å@Q—aäž…% …†NÙLVÙm­ªC=jØÁ«“Ž‡ÝŸý÷ÿõ?û¯þÌÇA3Ëv›6#ƒæ©~øp_Æ1ç«ÃÅ¢1NÓlˆvYÞ½yû/ÿÅÿ|‘Ó#õçí™Mÿ©›%žrHþñ$Åÿ?­…‚¿¯ߪiâ»å}»–úT¡ô<#â§“ê÷Ž¥z¶Ì¯ûzóâ©Jþˆ†û»2­~4>H‡s¸uSJÊê-Â0w¯Æg»§ÐàîhÚßâÌœ˜ƒÀYüie°¹VS2Ê"Bˆ÷„ë4¾ úœø–øà˜H¤Iy°úàõÞ˜Þ‡ÿmÌÕéVŠQ{×–£ÎÇãy2†P7×¥éÙ±q'sñ@‘D,Ž1¬mÀÂ@œÜ´Ô–j‹ˆºÚ~ÂÂ4Laá°ÞÌ È<਋y[c”áÖ·nZ/‰ÞÓó®.­xÃS–;ž£áŸõçñÝ›èµýbéûßܽlëÓáxªÁ„ŵvEöz׺2¢»‹#z¯mÍF÷ @AÑ'M„~§]mÿ”£ñ‰ÐîcÁŸ¿9€çºü¢ƒ¹×<ûßßѯ‰eשŸ‚”‘$R ´E½6¸F.y™ê»×Óéü`˜Þ>–²-yÈ’2 ¹ESmíîáÃñxÕ’[Iƒ;/[êTvòõïÆ7´\.M§Ï?{¹I %×[çr©šÞŸêûùô8i›ÂT(íÉBR…³.pTƼ‹ÖÖêÉ£æ’Wã°³”ï8ø³—Ÿkàï~þîTÓ%{l¯ …¬F†Qpx¹?—qØ,—YP·7W7‡ýíáÃéAü!;Òˆ«¼Ùð–q³ /4ÜìwWe¶ËöåX®(¤æ!”o®¯n_„×»·m:.åEOZ]/J*Ûa7äQrºÁüË·ß´“ë)†!ïJ–ƒÔ«c®/§ÇÇ{:¹uÌ ÷IóíøüÛå¶w÷<ÉÖeÊà „G?fôКÖÜí>Þ[î#“i°P­³µ$¨€ÄErïï÷.D"]¨eáÆªý÷w§HàCæ ix¨ixæŒ D¢NqsF«PR6D@±K Ä0_ÑL€À­G”œ‡èjO„”®}Ëã¶é²P+20å1™Ë°%× _ºO“RNBÕ—ˆS!‰pÜÌYp(Y xI–Q’8Т©U˜‚Âaw…X¶iÿÓûø –)ú¦5ÿpÑH?ùA|Z:|o=ñ»ür€ +L™<ŽÂTÀE’A ‚’]<*Y¸çDÜ‚?ù‚øÑ ÉMÄà’-¥“å‡3ÞhýÚõ„ö3?‹^G÷e>ÏóüÏ¿úÃÝÕawØ˃·÷:]-—÷‹~8×s mKÃ0޹$Î f±!l„‡»{½¶ '‰áê¶DThÞœÄI]«@UkÒ¹¯ýÐOœD8yWÞòšrÞš}z>‰ß4{äßÒqFÁ€óS™™ºHݽ÷&£gŸŸí„õ´Ñ‰CÊ‚sô~Ôóg§` Äa}ôÄNŽ`ãéŠ~ûª¨ï¢‹p0Á N¤u§O¥Ï3©xÊüÝ_•¾çÅ€54`Þ÷2êé„ÅNΑf¾3É!‘…Ë ¦¸œÎ»q8ž_^Ý›©óâÛ#’ªÃ×7xyØöÕÍf“/ο|ûÆîðøøˆæå0쯮÷/÷—óeyw7Ío¾¹y±ñT··›Ï~ürˆt·¼ÿæÃët]"Ëùþüá›ûû7gf¾½ÍQÙÕî~iwïînÒå@WÜ$fÔ©ÎÕ0àú˽†6æ9ª6Öîõ.#Uª-*Á.õ„M+¶9£–ó¨Út¶‡×ó/Ž—á9cÜPB›O zO0:ÞÏí¢dh.gdB)˜.Ë~·“œm›˜xÊRvÛÛì)€éøÐfç¡„ó<¥¸?>Ìm %>·ã.K)\sÂé„‘¡™¹¦˜ÕÏž TÐvíÇ?ùñrªoÞÜ9ow‡ýá6<ê¹>¼9ŠáËW¯Äóéý9OCQnsLû/on>¿JQ}Ž3Mõ‹/_¶åœrÙm“¶ùáýÛ‡÷.øòåÍÕæ¦©§3)›ìŠ”ëÝþ›·§W‡›ûãýÛŸ½ÿã?þ'¥”¹µÏn¾ðéð?¼™§þç”Ê¢5§dÖð \Yú•p¿q†ùÉí…IN§ŽÉ&÷“ðgæá¨ƒ™£»Ú2q÷I,GDÀürM·"Rm¦ËZØ‚¨Cà˜8sr5qhXóÐuÐÓÐL¾j­õò¦¤Ò!žÒ•|8™êå4saØ¥DÌ º,OX!åñ,n¥^.“Ãàh‹fIæþ‰˜Ì<à–2rY˜’1¦¦”ó¥¶^™€$H IÑÔgs°àî­BÃ6 œ¶¶ø0Œ”x8½KÑà„õÀ;(8ž&N)§QÓÞ¸oê4¦DÂe»édêhV#œK‚°› ©˜Zse&îà¸Ö—n{å\zuDœ–¦Ñ*"•q—’LËŒfÈŒ±lû<”_/—°ã,Ï‹"Ø'€»X‹kEKæm äejhti±Ýîê‹Û/l»ù²¸ž/çj¡°¨[b˜¯²0z–×"„]Y•ˆ¢ ³×%ÁÇ’¡U’Ä~3n\@Õ\ƒ]X/<jÖKA`ÌDäRxØæíÕ¸=HÂiiºÜ¾<øF,òýÝôægoŽo@‘ñMKGàv޶pñzœ*ˆ4'%v‚"³êhœ&ÓÅ舎ðVII˜9žvü5¬A¬i2¡õ<]84”ˆDH-:^%ga˜æÖ fèàØ$H›œ¼)9ÆÄÛa`iu©Íµ_b-Gpî²î0îEŽ<¥»z@ÁŽ’±òX’\Õ @æeñðînÍ[ 0¡c»)m™¶»±Öù_ý«yü_þÅ"H"û™ÆH‰%³K ¯ˆ‰03½Ÿ/gÓ4”`™.K­Ö!pF0HäpsƒÍh*X £x ‚=Ñ·#âwøhñ}~‰¾Üûwäa†=A÷Ö¼H@ÊbÍ>16|¢*ü(øV†Ïåÿ|ïðÍ fö±»ÿÉŒŠ™<ž5Éëçxî<ýý¼ô[¢þa/ú8ŽæyPJY–¥À–ÃSXª¸&r/*ÅØ-pÑEmV‹¼Í$Bv®uX"Gp ×9g–b‘Ã2b!|híÅfû*øú<ý(äOv‡[.—Ma&2m®ó&•+æÏ•¯,OêoŽ ³´_ÔÇ|©ŸSùÃëpó‚Çãô¾Î§¨.´…+Ñ¾?~øð!ÌÌ›”Ü´]f ÀTQÒ0 CxqõCJî>!ˆÙ%)дU×HlŒÎH0b’ «©qõpµÕQDäýÅ~Šw6F}y¦1?©æžVÁ£E'p8úÿóÈOK ȃz„÷Š˜«"sîŽ'û´÷‰ˆ¸+„  Òª) ‹"<:íG’¬@„ž' €‚b…+=+c N¼¶iÔ²]Ißì?¬šaüÞ}\l]nºCÞœuªï5±ÙËp5&ÑÙÎ>-ó%nfçù²´Åš¦œ —eiM+2wIXlÇòâæúÅË›i;µwíþã·à$Íì4/6Ñâꉕc6¼œyh”™Ó˜r. þþý{™:=ÖznõÜæsÓŠX°œ¡¥æ‡=¶l”8‹Ä¥ùT›±çåá|J'»Ô3o±»Ý]ïÉètº¿·i¨]¢Å<·v¶léå;Ro,!77/RJJ­ ¼®S>Ïo^ß]m®£ùùT§Ùc¸[¥éë÷—a‹ˆã£iHJ›M2Øím¦Bd<Ÿk=zLHÚÐýÁŸ”ý?”"ZñîÝÝé4˜–©8oK(‰ ézˆŠYÛ]}Ø^m®_Ý^îk;/su»€Å­»Nçz÷^6i¤ˆ«CÉCÊ(I¥6 5Õº,gH“dVÊÆ]–úøæ”JÑ á||œ—Y£{@Öd‘UüúDmyáïŸ}ÿœXîÞ?¾zuæû͸è+Gh?QS_󰦯P€•‰ž8œ"‘8 …7mnm†j·:ÃyMª rjY­÷jÔɌû{^jíSÎŽ‚é.®óÜórb5G9;{Þ$î<VM)åÙyÁÌk€IWånv{ÖÚ0Ø]WbNÏtìêybYP·™»†q[ƒyíN—U©ìÁ!¶”`ï¡;±Î¬:›Â=à¦0!RöbãÂN N0Gk0…“ƒ˜­OL¿‚fpb ï£ò•µŽï B”²€Ö¸ŠèzºÄ’´H±(` ~¯˜È‰H¨oY_\aD2QQÊlIÐ uéO#¤ãì„=¤3~„C ÚÊaÿêz˜'Ü\}ùþýYAž(`wî2H€Sîæ§§}’Ì1u§ZOyZé‡=𠉄™Š›!oF€«ÙUÁH!””íbëñ½{eœ@•5%¨ /žØ:땉ò˜Æa<\r/_û‡»Ÿßµm{ÂpDš°5\%”iñe©Ã&Ęhn‹S Ì SxejÒ·í ðˆð±†`!b0 €Êf`².œ’HwÂ!|nó±ÄÆœ<„`-à £(ø|~v‹Hæ$™J6óFhFâ5¬+t'aN§ß‹ ê–"D¸02Ó0 9§ 6oU• ˆáD.¬,=€Œ„A+\j쳨𵶏VF+H72î4e&fbc4¢EèÝ2Y»ëb!$©ô³Ìv“—YÆaÿõ¿ÿ›ÿòó/À¸ººz¸\q ܵ+ì«iz³ú]í³þ°:(ž¢-Ÿœ6Qµ~{™úº_üÚ´'¾¥œþxФõ—}_!ŸÈ„>­ }÷Nš¯ÚçÞ’{rKÆoÕYþ‡iv~«ïßív§ÓižçþƒÌœs&t)˜‘©PPxJ©³û8 ˆÎè„Ó´Pn)¬Q‚çˆ <²{ Úå‚¥U@œ% ‘htßZì›<öÙwLîFMMB{Ïb ´­Q>O»3ô-ê)éZÒ._½Ú¼Ø,” Ù@ÎHÍ­4Oˆ¯ß¼©"‡ÝÖk³i:žÏ)(±Ü\_A܆úÆ’£/šÝÝ/n®õÞ´ë«5ÿØ-`}Ä‚pôÚ4œ‰×n‡­ÑZ†htò÷ÏÞ­á9Àã`§ëûz¬Dз>3$(àä=t‚!}¾Óc€;£Ç¼öÛ:`ÕÉ9¸O²ˆàÖÅÎ z‹4À sªpÁšÎ×ÓU¹°8]T²Òƽ%ýø¤þø&B‚Ÿ\V}–õƒÑo•%ü;4uå00ôh*b"‘¬Kf H}!œ,К…¶û»»Ï_Þ´Öœât9ªÖ«ëÃa»ã\¦Ërž&mÎMc™·‡¼ßï‡ÃííÍõxh° Ç-_Òù8M>?<Þ“BAËE[7WÁ¦‡éޤ=;æ÷‹ßpOÒ°m£ýa3ì·/Ç£žjn)çœ3ÌBaì~©ËTqþÛ_½=¾-[–ww•^ÞhRFÊç‰Ú•ã8’Ó|ž½i)c1ŠÑ&š¥-sƒO³ølQw‹ê­)r64ŒlÕ[³x<Ÿ¸H$K”Ç44xUm£4(7£@ p3Sk”4_c÷¢Ä9îÞÍÓ4ÛÍ~c)6×;—hnby³¥«ýî‹ígå&çAª«)©.íõ7ï]ð’Ø=òŽ£ºFc*Î8×˸ߌ‡ yžçãéa:ÇAveûáÍ{2ó¥Õ‡ËfØÖivG¸Ì§%!ëT !ÉÀ #Jvc‡!ªêdõ¨>Jm¡íòîu=àa¶ ÖžÆw+"sÿÞŠè‡vˆ”Rÿáû‡ç·,·n ÀH=f´ccüc|[ß¶Ì=8Ô»+ûÍ–NѬQh@»e;´­Ã+CFOrëîÆÎ§ïÖ#÷éêZbæ, í]¸FŸIõîfq÷k(õÄžRFˆˆGW5¯äà@x€Øx-ª Dδ¢˜w7)ÊI3B>îè½{¹¹÷ø&KÀÔ, 9V ºö¸ÖÑ,„ÂŽpr“!%÷ÐjfŠXÐ @ "•<îfÜ{jÏ—A¬õc’…‡3P˜ó@pŽ ëù³A^9ÔÈ{«wÑ;ŒÔ Äl€a¥;TDC‹P,ói)LD…}É„ÅШƒ€Hý0.á)úõ °ÔA˜ãþî<ì=mªÍn`QD-îKDu£‹^¹Ïþ\¢õzëg5q°„ 1TÂ6R~ŠSzŒxG^}úÕ¼¼­8 uOO”œ[êL\A$'IžÐõu…ÞoçÃÊ9ŸDU5³ý~OŠBœ›Ø›Œ©/©[Š;²c4- ”“§L΋F $ hhÈptêÇDbJ¼+eH“ªZ VZ´‹Žy¡è8,HÚ›F4xB.b£+™ â¶Ÿ?ãø*7:‘S“”4yãMN¡YrXRq” Óà:nq¶Þ¬WR\‡)#L™¹5S+:™àVBǼµÝB„s€"÷–­ÚP)ÑœQZõdN*;Yo ;»3s킎¾1óZ3«†ÖU]ïP¾ã°µqì×›âŒmã!6jÞOȼ¦áí#Òkît´DžÁ*‘èdä@ÉØˆ(®>V‘âï hŒ±ŽrK 2="Éî®B! 1¤5üaöŠ 9x†MàžÜ ¹8¹™ƒÝ48´z¼ÔЄZkG‘£Þ·8”ÈY˜L#´8¨Ü´.-1ç ;›S˜BFè/D­ˆ™Â,™[áê»ãZ=ʃ¦l4ç>‘ïbM IDAT‘°ây"Êq®qŒI\#“#2EñJ,´©˜Õ(Ô •Y…‰sóU•Ì‹e”Òm n®ª ³¢¹h)‹åÒ}ÆÓ2™ÖNÄ=tp›=¸‰ˆ’#Çq¤ƒèc¤Â+±ÝÝLÕ U‹ ! 0dH‰C\ž5Ìé0ÚúaR ÓbeÆN¬„\™Äs˪N®µ¼›YO3/ÜÁtL¯þâ`8…@ă³3¹4í®‰Ì6XxÊÁµ0kÓ(7nrp‹ÄœP+@ì6Z)¸D¤¨}Hûf¹jÛºnµÛÛÃþú¯u¼Ö´kB’õâ…t% »’¦Þ‘Yd _PÏap?(ö%'Ö">‚÷Îeá›9™`B\!ÍP©IB5›q™‚’ÅBLެ6ºš'`b7‚€„¸ªãR#f&8ÃÅ`²#7stÕž:Œ¦¹¥RY*M…Nä+;ÑVÈ % N$Ö4b"Κ§Pr# ÄE( 4õ鬮ZÔ·Rȹ+BöF¢æV&÷( íÄ¢«®w7 Â`‘‹f„àF)Õœ9Š./Ÿ†G?Ÿ zÐ!•” À›ó³ýö†îírubà©Âøï0FDo©C­ºƒé>d4³Pê') f²j½QóØ€¿Ô×Ý™U24î)Åï¿z×™ÂÄïyÿ_f÷}]¶ø7ÃúÐ û4MbŒÌ\J™5ý H±tçg~¸åÅ"„‡.{0ãIm$ë#…Ì¡0ôèÀD‘‚ÀF4Z5‹@lÄ…33GÏf¦”µ÷²+Ī×$+x"XàÁ93'ƒÃV†‘eâäröø£‹aÛ$†íÙÁåÖåe*ÈhYzð Ó–è \”wVJÓŒ¦6MçÍb}qIö‡¾ï{8P+®–Ê¡‘¦’B` á`iWdoØFæÁMg…Y€Æ#uƒ#TsŸY5s²Ù¸4šͶ(uLê즘ýºÝÌÈÙ1c)TáDgw£UËNzŒÏbw¦99•g«XS@Ö…X \­Ãçì=&bnpì‚êÈ<Ó¸Ù+»Ú̬„#—­²ÜAs";ôHf­SÉR¤÷~¾OSõÙêñ½Q8…Êþn}UŸƒ·€f³9P€>ûÛa±š–ëUilpË‚õY³\0¯qo^îCBºAœ (5¡CgÞs M …¦IE7Ï.ÿà±v庿ºÝÝôûA{{Dä¶½çÁr†2JÒ2¥Û›aèG¤ÂÌÆÙÉ¥“®³ëÞÅqy¹æ–‰U= }F%Œ×é&Ý,Cƒâ\ ³Ã¡ÂEu?`µÑGÏ.»³e³j÷[yõjšÊµ.vM·HÅX•©R}̹TÒBVÂ%k6+8’åœlZ ÂÞ€™»usþÑùåï=æVm·/¯ß¼9ä¬Ë³|öè“c@òL®Åmô1õþæçoÂF]#«¸˜zŒ»ÀB(i(Mã0Mû1«!9Â\Jr ¼¢doûÝVâ ûh®E¦Øv¡ ‹6¬Úå² ”2%[viRNCžJ¶½q4%W [axuŒÁlNm3¢~«YÕ†Þ‰½ï„`1 öêõþÉÓÍÓg—SÊ»ý^¦¸YR ÈLù=ñwkDgÂyzCÕËÀ= X2nCƒxJÕ ¢Fpj ­ºFuS"«p´v×@àyÉ€CjF`° ‘„ æyè¬dS2LHkGÄ@W9Üă4Gábq" äî5%‰à@!’Y"Á³Ã™¹l^Í¢ ŠSéÉ` #£pò\ˆ9¸@¡`ˆÄ,¡T¡¹‘1s0§@2ɸÌ;µ#(@êÁMµaŽ "S2—ê¬åâsåè•ìVí±¹1‘“'PŠ+{7‡Á뉦 [×´nUñ%7Šrw5B$ (¡PÔ‹I)eÀÀ£î[ñ¶1 Ä`¨¨‘U»èPMɈà!Š%£é6ƒË“§ëŸýüêâÉÙ¿óÿÝ_þàHzÌ%U†ƒœiLc=ú*qŽÊWR¶™>³´iöœ› a `!ï$¶-ä!g“þ”¨M,É¥@܉™N0†2)3(x·iÚ•¬7m·¡¸òæŒÚË&n8_.üéÆÊcM·)ÝNy›ÂN.¦uÓ³÷Sé{JEà1FŽÍPtr;(ME'uS6óÂ|`³PKW3Óâ¥þ‚Õø‹œBÎÁ©æÿIp!àȱ!PÔ'èhžÈÌÜ…™Aìd„)»3ÃëÇ[ •v眴”bªš‰2Kž;¢» »²æ`ΨÞ*&D "Ç’šHX˜™ÙòX4YòÀNT-Â[HÇaiI¢S1í½ ÐDAiIb²PÔ³f-™ÜlÑ6ÂO¸i³“VnÌl,&¡wKAö¹\÷}q„®cľŒ…m ÅGßûxóìùnH›ËÇ»ë7ð;|¡Þh cuû0§™o)F„H½Ãô@QÀsÚ„ ãj¦äLVð3­2d辨ûï¶ãA§tšß“¿ßÑáÞ>w>¼—ùm]è¦iJ),‘ÌA\’}v»ÝOû7×å1µO/ÎÏ.^~e@&™Àó<‡ÖÙò4r5…Iˆ÷ˆ˜á‰Ã š‹€™Ï–ç8fG—D—ݲ îq²¤Uõâ-Åu\,©1ÄÉ쥣§8q—¨Ü~6M}Ò-.ÛHc#¦ƒÈ˜ÄåÐ3)”¼YÄnœ¼Y¤fÿf b‘*&Ž…sç4åH@|0ߺìz¢D¬€Û éÌKÈjÏ–qªÉâ¿ëœÈØÅ¥º (Œ˜ŒHŒŒ„%g†ž<@NNü¥G ¦:ðÙ‘TW´ÛÑbåØÛ[a>-lˆ\‰éXvœÌÁO+¹ê÷Ü™•‰ˆÔ¡B‘îftÌ–5€sÚÌí§j&þVÙ%w‹œü«tDþ»XÁó§3Ÿ@vªPEc$‚ªæ‘ÝÝ%IÀ8ŽÄäî±å2Y²ÂóAЄEX>jA²¾ÜH'Xؾ\÷û) ˜v kìÊv¿¥c]dcìÐù$SNûiº¤³ÅÅrùdÙô~jý.MkrÀH>OŽÁªZ¦$D±kmÓDЂ4°î¥‹«q¦q ìRp¾l®¯Srßív¹iW1FçecQÐ,"(€„£›¡¹À³Ÿ¿øñ3nåóO_]—Ïo¯¦ÑûDK q,žeáÝj±\-4MÛíCJ=\J†™XÛ²D›¶è§Q Æ(ˆD'æØq³Ž›Gg»a?êP¨xpDœ]ÈÇð£Å³M"½¾ÝŽe‡~{8¤}_ÔS‡®P×–@Í ÌÂ+Åò”rΪ( Κ6:0ª•"M\/L®)5ËTÒ4^JqD Ýæìbùü£eˆ£/;é¢ ·{÷Â]×®1M¶\…!ëÍ>«ô‹³³ç/Îy¸nbOJæy¤âÏ}ô«ßJžò@\ž=[ÿçÿÅúOÿé²:ãA‚ªz¯ ¾çézJ‰­ái†* |oëȤ!œ,'2ú RÆ1öfn›k?W­– È5üAŽNÿtôû'0p²­¹ŸX_™"ÇšûØQR|"o¸ä•}§÷«,÷X{£ãöïG†I%–@uQsü¿X×¹´9`à£Éiv®¿{}ÿ ó#ý„Ü%&󻻤 ¨Þ+‘øèûI0sÓ>í»^`Á[±ô|º\xyïÀdpFÂñ/ÊLŒ¡ €Á«Ï3”QÆ`GpÄ w€½â±à ÿèŸüÇÿðŸÃ˱d#0Õi¶kx°ÔìôfFótÍyæ†×µå'MŒA %C ÔÎnAÜÀŽ6dÇ+·‰,â$IiÔHÜ¡#òýþî0퇲>_ÿô§?¿<_H]ï3íK\ÀÄï4B„·mäjƒç),Õ}]Õ²j&¢ˆÀYD:ÔO“1ùÔu·e¼¢úÎÌOzðwþ²^諯/}h‡ó[Ö“—R*“\UÇ1Ýìú‹³åù/þÅ?ûoþk Ã Š£ÑœÃxNò VÓ…je}ƒf÷ôtzÔ4#FD„!„ì°Œ.  PG¦ªnAeVÝY5bå9˜™Ë|®Wvo=¹éÔÍ,1ÔšV dwÛP'vÐʦ~+Mø´±Ð=zØ=x÷¾_ è¸}éådÙñåUô¥$Øc HÝܪ ×êT3Ç-òW=:ƒ öÖ§ãßéøœÓã[ìÔ£?¾ÍÅøÿ_:"\b•AeÐÇ ¨Àë©ún94§4äñúåËË'›Í:댦ú|ÝâñóGe¼øñ÷Â&ôv»½}3¼9ì›]¶c[êÓ¤î8ëây»‹–)¬Ê.í>¿~yÑ^›„†9iô¶š¢!³2é8M6•½I£uPVšeó\°Ú,“¡å¶ú|°¦i–Ò}óüŒ÷f%õŸL;oÑ®Ï|½^å2œ?:kVq,ãËëWcƒö’pž?ô,C™®Çói2,[4kn7ÍþÕ>¦Â~ñtsùìŒ òÆìõ–n}µ<+®}¿€ìâ.Ö¬d-Î¥ ¨¡)·ý0]e{)Ûa¿ÿâjºt€G¬-}ÿÑßù·ÿh_†_~öédÓ4öSA|À@3yÒœŠ¢ŒÓ¤PÄ6’ûfÙHCˆÈÙE[˜‡ížF]ĕԶŸ¼´‹Åh/—’¥7ùJ™F›åbq~±¹\ªÞæ´‹)ÊXnævyyñx1Žc—ÃÆÃ¡²&.j®9«ª “B¨ÂÙª€}[Gd¦ #"t ‘ ã´ÿŸþ—™')ûq”( •cGt·ËÜ g|[+¡ ÝÝѲÆÔFäÌ5<ͪšIÀ\ë¦9?'Šª’ƒd¦ ‘ƒCM„œ¡“ÂÒ¨³êY ^üþd­áHtœ÷(k‡’£¸«»23ñqàw§>s=3€ªÙ¸¿f­†DQÄrϪ #s­tÍ®¼”jŠ¡nêÅȪ{šÖ¦ÎϬš…Aªˆ…ÂÌCpg"˜fÛL^¤êauÂ0Õ ÒN@µ >6ÌÌäª>÷`ÕÝ™ª‘7 6©H3œLYM´P©GM´FràÜae/’Œ•Q‚YPvâÄÁºf†Ã?ùGÿÑ?øÃ¿»ôñßû*M%ã8U{ƒÊÆìl®öìØêÀÕáùÔÇÑÑ/ˆO=®ê]$ Yšà‘HPP L€7éxLCk E8[Õ£ ¶,@IÈä…²´M…Ш /@]»¾„ˆ†YˆVœ\*¤¥àq`VÍ*TYM‰S`'+®Äsÿë^ï,v'1[,Π¥2û©•“P‚er#‚ÃÌ”Äq#GÄŠ8»ÆÜ4Cv°»Ý…Òø]-[Ust¤Á+9ˆ+‡µÂtW; PÁè^'%↠€:¼v‘HÛ„Ùñ-ÀDKÃAÄ™D&T‰½Ä°oàQæ¸ÉðìV88wŽ ê5[ ¦iWÊ.çGO.w‡²Ú,Xqv)È AÉ 9]U¾ÛÐáRS[bœØÍ”Ø¢H”€E' ˆ`è”§AJà¦A×b4«€³Æ0†Ý3þýÁIt_!rú2¾ó0gÓª7éýJovúMꈘ?¬³Ê97M£ªµÊ9眗«åÍÎa7–‹M‹œ„Pœ#×U3P…²Ïû±’±™›S|hý®2›âH„3ººÝeà:E°ÀjpAl@%d­¡3;3‘Òh 6m}QY f«ecŠ5¬¦–!FD™uµÏ©Ì3a @ǹí©}ì›ä8cœ†®.<¯Š¹ë>¶:ó¬t&;ß}ºvB##¹óQ«3‡ÜÏøy'!“¾”ÁEWÏê·"Uæ~kž²üû­šÕÌŠ ÄУ-ñ¨‡ÛqøzúÞãØ˜NÃã{ÃŒ9½•îþcõô4ú ¯¹ßAÖODPÍ®Ÿ±=?f8˜:! Dì":e͆ò¦ß\>"n—«å¶ï¿xºXu¾Ÿ†åjõô£ïI ׇ]*Yíñæ“ñÓ7Û§Ï——ç®hJËÒöÃ(Ú®[-±kŠMƒ’én,)`™Û³’•ÌnnncÛm¾·êM§eÓxN—OÏô“ß;ôû/~ùÙöêº(86íY{ùü24øñïÿàüÉùõþæ—Ÿ~òòõÕb¹Úœ=úâõ% ¯n^í'È>Z~ôâ—OÓŸçò:—œxV7m5ädþÑ÷ž<¾x–sþôÓÏ_¿~]tjÏ»ÇgOÖ‹Õ4¤ý~oV”uº™n·²ûäæÏCƒV¸á°Ï_|úfoÿÏàùõë׿üןM¯ "àACËaÔbìÒ5˳ÅÚ45KKûÔ3•Å£ó™ÊãG.Ï{.:–¶iÚzvq¶ŸvmiJÑžÍhb Æ0 ûÃm3yÓ˜æÒv]»j[éK-¥m«Ew;øÕõííõ›±9ÃXk^gÓ‚¹ù—;"Ì^sïæÍ¿oⰽݙiÖòßþwÿÕp(‹Í…WÛ4© rµüªþ¼•ü©GI"égæî!„JE»>“3!ºÎßÅ\µüê^ÑB•÷h­Œ‰ˆ¢æT9lÀœBH©<8„Éëû3–ç›+d~¤.Ïì>r&qšUÈ g ,ܬ¸{eÒÏ^MNxîCÜÝó}øúô»çœgò×AéÈþ¹Q{‹`ƒ*ôø½µC“™Uí.Dµm™Ë3.f–zøüº6»9±YÉe‚»¢¬9VÖ™×¶$ÎnF5쵚Ó=˜Bû[,ÖûÝþÝï.ÇÇYLÀ¿=¯¹wú—‘ªÝySÜavïÍoù ÖŸ‘’Ó»8²ó3Å ³c 7ã0€Ÿ|¶]oÛa7æf5D ­RÙßLŸüòå/~þÙÙÙYX5Þñþ_¼hMÛtûr=ZÖ7ã- &×›½íËËLù|sÇöhs¾ûíMzó_ú³'ÏÂÔ¾Þ^_½Ýã~EË àêíFú›B@\-$ÄíõÍ®Ÿ@4MhWD¢?ü½Üóç_|z}ýúÍgŸÜòéŒÓ{Ò…™¬Ì?P+VNP4CÞÆÄk?ç2Ùi_º»ç“Ú*æ@ Øñv«Q¤³=72 ÍËéWËv×§\3_µ·(zg p'$"½wû¡hû¬1½{ź?Õv¡zð NO€»d†ûÎTw«$À8³ÿ ÎÍgxä4ïDd€ž~GæûtBó4øš“ÛŒàV7ë+3…™|å<S©»Âƒ03ÞܾĂ™²ÞŒ‹v¹8{ò2ÑàÝajMcä7Kæ03P#ˆƒA`õbj¦ˆÔÎtÕB 4ãpœÈÍ“–>i Ô„­…w¤[ãSgI\«crh­Ê0&¦VD˜…2g‡Z(¦j•¥†LBÙ#{ãÔ©N †w ÄÈŽbTJ P"ƒ+#‘3(ª‘‚ ¹³Ô¢H EUÕ r" "Dð>‘iĬ?®qÌÅ̺œp´ãó#ÆÓ­áÑi„%xqÇìâŒRË‚ùÎu[p'76%­Ä+.gÝÀpµ„†à¼ àÁIÈÅ «ÏvSõÎ`f!'"Ugb&{&*BDäC™ë¨AÍbFl”Õ¼˜8¢CUaDܱQƒëH(h ·Ô—¶ô¶_iw§m8Òü¾«ôšãÄþ8|¦ÒøÚõ'Žï7Ø4øÞ?¼|õÇÝ÷þñßÿ´{ùýïúïý«§wú±Oòg?ýäÿøÅg¯™¯…·ýÔ’˜[†B€E¨•4‚À¾lÑ]_õÔ¾è{`ªãøòûw0|›v¹¨n)¥)'U­3§AÌ=‹âo†äøk¨0N%¢ˆ¨ªˆ¤ôŸM©xò=v+1 \K*‘Ù¬š½` ³F€˜ÎÍ ‹Ó,ø$ªdSÅ~d«:»Ó0?‰Äê½_7>V’ó'@Vp·Î¿ ¯»áU–«Y‘v„  ÎôðǾ£A­ªW†ÓYü!õü{ùi'íÚóñ×óÙîÕöVVÀäïÅ$ÝéƒÖ<7ßóÿàÅvo“úVm:ô Ü9ÞþÍmjöÎvTeœ„ G®DbpwI“ï91›B®¯zóÐ4b™u I|¦˜£M9¥ÃÈ*ënóñ³ï§UÞ]ÝL:ź®{ÜåØ2µ´÷])éÅóé05~µ³ï_/o_›q?LëU,p‰"g2¸6,!H¶a± Â-"¦é0¥”!âÍÄ>¥¾w,:¡} v/¯/Ö¸¸|º\ï¯ÆqÞìv·V^åòrX\Þn®^Ýøw·¹Œ/K½½ñ˜PDò±ô7ûq?x.¬@Á°_ÙË–›©ÏAc¿Û›ûpÈ»mï&FœLo¦ZÞÊ­_ m±Z·]h¤€§H…wû Eæ@ Ê‘ Û\ÞX ƒíTmXv±]µA ƒL;µ” £ä£»÷»ýš×¦¦®“æ ™÷jPTÐç̱_\¬cX¨s`a9L¥ JƒyêÚÐ4MK˜v{ MÈ‹Õf±:ÛnÇíí“‚ã0L‹ÅâÑ£G!®RO 8'»»yøÏåÒZ2{Ÿeêû—§£†º8l†Pb—r<çóŠÜ+¯ëw‡¿'+Þ?ð ù¯´¹èéñ}¨¿õÌùù÷F™¿ÒŒ6ð—æ)G·ê÷<ŸÞÑ}éùsh6Þ•LMG¢Ü=6Ø;†O_Ç6©F¸N|F}%ëàŽpmÇöõaýCN›w­Ó€ÌrÀ”àìˆÙ…0U¿/Â$qb.6UC35P4ø¬ì!+`!r*ð0†»'q1œp jÁÑ-«ð š³ŠêܺGå_-xAhȃÃçn›Ì 0M¬€#Paµ£”–̹8aa¾3 IDATåç`á Nµ))HÜÄ„ìÈ'p²º/@nFªA¬G[xPµE163&°Tåœ+Ì©·æän^‹À=[pwƒžæ µÞ h87ÏdTýðIì(€fØÌñ¨­±“‘»‰{¸;éñ½ à†¼s8(ÉÑñ?TC;Ã\ÉÕŒY„£"ŽÀ!"3?¶¨)(+"2M`B !4$\ÜÍ…i …$“™{qó+ð .U Q»ˤ #ךÑf¿)úÕ·DLTùˆTêÑt©ø8àãž? ŸüÁâõú/哸oà󟽢¿:Ð5ooKð,Y‚Ç >Ç×¥{Õ ½u¼½ýÎ Iº;YüCömRN4Š˜YJ){=Ô~ÍRòo:8ÃØÍäìNS F¦÷¦z'ª”‘Ü Ü€’ß;>î_x—»iãý Ú© úÒñ>_gº#„@¾~ÍŸBzw7{¿¸?¾Ê×Àtö ãw>ÿýˆ?ìµ¾ü8ƒQõ"̰Åó>â­2äžüé½c|íyý.LãÁuûµÆßÒŽˆîwDÃÍØÛ«'SåâX.û”p€DpäqêÝ}¹î¦Q5Á²Ê@crѦi8ó°ÕåY¾¸8£èËööÚ‹´]\¯Ò²æœ ®ÂÍf})¹9\ï} ]·‹„Ý)Å4CbK¤ÐËË‹³³sxØßöD”¦ i!Á4 »ý­¦iGzl6¸ûl*ƒ.K\] ûaDOý€<¼1BÐnÕŠCˆQ1\íW‡RÊíç[Ëh8ØÕí•M€¨ÃÔ«%‘6Q“rölóx)›³ÅåÙùª[X.z«úÚ¯?ÛMãVÕ£ˆ›Ã`ŠaJnæY‡aˆ ÚÕ²Ûty*‡2öèa¾ˆ-sœlЬCÊMrò¸l8x`ŠJuq™yišØ.Z† ýË(Á—ë +©˜iÓ4]ו\Þ¼¼¾HËK<{òÑÓçOó0n¯¶ãþê“_4Å»UÛmV»ít}“Ç1¹‘ëƒì¼ûKå›ÂTO©ˆˆ 1›©ßy¬Þ iN[¤oÛýûkÌï‚Þék|ÿO|ô*ËÁQ¥ù¾Ëð¡üø÷ñÝ¿)§™÷ÍwÞóºô¾—ý5®óü-îÕ÷ÜÌT$ðRÍ*XÅl ˜:‘W›j&©ê«ÜD¬^‡¤ä" *L‰À¦°L3«“”€‚@ˆÀ$B^éau mI›'ŒàŽ Gü˜º‘@¹Ns‰ãl9l5¯)Ϧʈ¡™Dnw&NvºI•ã¬*#V"#2*Ñ”%ˆ/âNî&ÆBÌnóÙ@÷Î ó2'a¹ûl¡LîŹN.\ŽŸtÝÁœ>—O³9;ÍÆ°ættP " ÄæpªÞlU~ïÆDŽÖP&ŸY?5’pþ“ADîT½2‡q1JæI%ƒ bu>:ã.r€©"TFT-»gv“À¬\¬æbexaWv'"v˜³º«Yq7gËïü]·T¨[F®„XŸI™³Ó€ßþä^È‹|ÿþøïüog?ý¹ÇGÿÖÅÿûÞüéO{lqaЀ0ê&ù’šâɫ݇aL0â9¿j6黯tG]ù×DºNäêJ»ýŽbvÇÄï_õ<:=ù+7Iüí×ïð××ÞHáÛ¹Ðq5÷ëÕ"מּb¹¿Ý߀¹+̪m ,ѬÁîv?MS±ì…„‰¥A1˾Z®6ËÕ«Ý›þæp#o–ݪ 1"””¬i„‚h.©i_|ñ*J×QlK1ä.Aº2ì”ÁUÃ_\³f‚“Ëš/.Ïž>yVŠF‘¦i‡~(Ô5ç¼Û혽ïÇœÅ÷?Z?úââì2LD"‹2Ið*qŽ„Í9l {*×·½+Î/q±¤õÅ…BßÜÞÞlÑ(«Î×x´y$λ«íÍ4£!´"šf!-i*jìqÙv«¦}¼Z{}ýéçi€È¢i†©Ž:ÔßD7bó:Ã}i›(û»âùöûüê‹ú¶ø>ÉöÏÿÀ}ãw3ˆÍ½Â_³RŠ*J)¥8Å*æR§£kù±u"w¸‘¡"q•RXýƒ‹»¤UrE`;Í.Uê6‡¸Bj?Epªqsþº)¹““;Á"Šä¦'HÈ@…¸82Pˆ^ˆn`c°“¬FuȽR2ˆb†×HwŸIBJdÌL¬Ä¦Tæb›&R$%1W6 fÄLª÷ –5JËîVoíÈëñ@ÙYÉ‹U—š«b³¾ÛŽF´Nî W˜8JàN¨‚ÚÌÍ)3ÇÓ L3ËŠçtÎî.Õp6ϼ“Ë®>)#³¨…âd@`5(hÅÚŒè\Uh9œ£0›igrP‡ª6(pC@õ¿efg2ª¶Ä® z\þŽ~ÑL”5 ä˜oWrhA«%öÉß\¿Yœiî{iúgáÍyÉ9cíÕjÏŠ›Ó¬‹Gk¢Äê•©ïï|ßdkðí}·ÜÛ¯jª…ê­‘µ|'>ûJÑ_医/¾øÕŽÅ$uÐ7 æøFÏqÿ'•¿áÉàaDô7ó~¾u‘Ùé<ö{“€Öý5'ܧ¿´M¨¾é5Lw6û7xA¿úÝäŒi±ê·B(eÀh‚°¤ö0Lo¾¸šcâr±GHH‚¹9ÀÌiÊ“£&.Hý8ôC)~0bf¡ Q(s+9¯Û%‘ãn·ö·»”l¿ïonúźu2ÏÅ­ùÙ]‡¦E»©Ÿ¾^Ž»´½¾™¦QÉ,ãѺ¹|¶ùøG/ž?ÿh{=þì/>ýå_¾ìÇÃóß»øþ>zöâù~ا_þ¢ù2º7Ý‚ˆ_>yñø¹ɧ¯Çðùpè…Sn—Ýf ôêú*¡´ÜIänÙÉ‚‹è.oûý^ö4ô}z•o_ö·×û1¡i¤)ÅX)(©[·h•ËäÊ!*ñÆí8L&‘ûT¬T俬q׳ÍrµYÆÃ4ŽÉ”ÛRRh—1FìvõÜ­ÜR6‰y¹\ø’9r@Ó4Mn|Ñ´ŸŸ?Z–ƒ¾ùâ*ùòü¢“ë¸èJ ¡”Û4\õiÛcJ³x€•ÊÓ:­Òo¶/ªÎ??±ÂÌîskít@šÏé¢ïÜ[ØÑû:oêý”bGC`º‡Ô}çk­÷_·÷î“r àKëd6—€²›»Á ®3³ÚŸ¡sƒâ‡Ìb›¡s1‡:™G3rg:QKõ(!&P!Ÿ11c*€ÂÉ r·஦0³Ú2Pˆ ¨ÀHàJ¤@qT}•¹TŸ)w‡3œ˜ØÈ«Ÿa!”™ØEæ5Ƥ… ³ŒH™³W_.Ó?s¾v§¾h¦ßð­ódÄìÕ3‰… ~,ã(ƒ”oÕŒf·ìc÷# wy…qÈJ”\ŽT\&®]&pd…Ât¶ ‡@^r) @×-Ä„KÜ_šˆ¨[/ )»^÷{O¾›&4Ì¥L¹?ìÚö¼e òÍõíÅÿGÅ·e÷vzÁW¿C7÷ÙÉͤŽY>èúTw¾ßÜuûMϺ¾b¶Ê fÉâ""B"ÊŒo§Ùì³²ÆÈ©ÚÍä1qW°»¸Øl7®0R n  ˜‰R³ñž'cbgcTot¶ùãt†:; ÃÆp##SG†gGb2£Ì°9*PG`b­à ŠÏ:§ÀALÄp&Y5Kt%ãªåcø”²9œ¡aŠnjP=âO÷âìgäLdÇ‘gEÃ8;Èh†ÒÜ a `JÄNîÄbþøì ÿÿ±÷v=r$Y–ع÷š¹{D~Åê®î™ÅJ$è'ô{ôûôªI ·}Ð ‚°³³;ÓÓ]ͪ"™înf÷=˜G~°˜,²ŠÕ]UÓ "@&3#Ü=<Ìî¹÷|¨ô#£LÀ@` `è3#J@D;(R A‰èœL¥˜ˆA2mæ0&—äÈŽ¡!{ºÈÈD(R]²˜&­ÎF— aØl•bµU‹ Iت{SQHˆªˆCB”?5ʘ=ÈÛ>°!h'fÇɱ¿­7ÿïõbÿ_ñ¯K~sóú«¨»b§5`½ÞYÈ5£Z÷‚G*PÊCÓ«'@Ѧèè±›ý;ü5Ê;&Ñï¹Dß¡ü Þ{[çÚßÁAx/úT3™OXü¬çc÷»'uÈü×OÑYá[~òeíÃÇDµ¶»Ò-œtï ë$Õ—)¬lðºmè ÆqLjµÖµÌ¥ùÚZ4â´Ø”mÊ‚hK iîÞZ«•û¤WÏ®IÎór\Öér¸|¶7Hùú¸®5Ò÷z:•Z}Y ”mSÎÐÒj7Çqw}‘Rr¯o^¾,‡¥ž××—W{ËRÓÃJõßýÓ·Ë|¨cºØ_] àlåÍáT~ÿÇ@ôúÙgW×ûýþåË—_¿zõU{%!um…( ›OÎã|¦Pê4X‚.·s~“¾)ßZéžøÑ+tÅNRNÒ¼EÀ«'šÒY›ÒÙj+%̬g¥O»«\m”lbóá˜ûëQ¨ÄÜ›£ò$yocäŠËëá³__î¯eÜÓ4ÑB´•z’Œg;Œ{ÓìBªùZ£­sk&"_ýþk_Kaùõð‚YË\jõ2j­%˜óó_=_ÖõwÿüútK4ècŸOþAÝX|؃¨ÄC7ýÐý¹6¹ï‡î„@ßùë[ÔžàƒÕ†ñQ;Ç­#zš•Çï±N~¿géÆëªªÊpï×sS.ˆ·|OÝn1†mv|JäsF„Pt…z+=îíüÆ$Ù¼ˆÎgëïÅdŠÖz‚O·¿RUQQ¸yÒÞ8—A— àßÒz Ê{õ…C¢£¬! ¦³ B’T26«·)$‡Ž ä†UZ˜fPÃ=Z¨äžMJE»‡ ÎÁ [œ†ôeA-Ø]¡P%©fP¥“ô¤B¬C5Æ–:Dt*^€¡™ ¤ˆÜB畺eéR¤‡BQ›c\ÙüëÝ*†&CÅ`b cH&&Ȉ|)ìô¹,b°±ÌÅåŠ^ZDÕQ-AšxexakÑ(D(ôž–G-Ð,©©‡À)Û ýbA‘vg¦ž8 AiÂ?ë£À^á÷ÿËÿ·¿iÿý¸åõ列øæ€r^¸Y€fŠ›k³3µPˆ!âјHßúTßÉýÏÔºøÕÏö©˜ªÈƉí/¡<ç}ãû=ûŸhùp wö þàŽñ—¯Oûù¸ý÷ǼþÒªù‰:+¼…Lþôå]u='êna$±¥?eÌtµ”27øjœ¢.»qœàÑ*e`«ÕBt©îKÝE<Ÿ.³ì%Ï_¿ºQªSÆn¯®wá¨^vyxöÙÕçŸ=÷Ro^°„ýÅ  Èj–ÁŽœ u\^]ŽÇy]Tu†Ý´‡0"öãÞ纆Ã0éÙ³«ýÕäÙ_^Ûáõ+T­ž._<[}Y2ôôõñðò ã~¼¸º\ëíúÍ-Z[s]ÛÆ)OiÜgzÍ9N‡<îvûÝ8MWûiؽ.oÊmå´ 34FŒûçÅëÜŽmeñ"êږÉ‚$^+ÔRr²”6ZúlÿbŠÁÝ¡ƒ¾øì…™h­yFb¬MÃ5¯?ßå]³btµ6ì÷ËÏ?ŸFS“VZk9üÿ{™Öj·Ÿí|ÿWo._¿.ë‚Õ¢`0y:Šw÷H£÷›5úçS–pŠÇԹǥ¾[wô>„pŽl‰-ÛÝ=øNQ‚vßšŸ9º}H“»ÛU|=̧ìþ9fM?Å7ñ]ÿ#®gwSäƒô¦o?¦>÷ïïÓ91Pþ ä»ÔÛ÷oWœßgÑzJQ­¤ÜzƒÔÙ[_¶7>»õ&BêRcKm³VxSŽþ•RB—ïÃÓœ]‡qêųýtñLòÐZm±uCu0©K9º{㜆L«k;´V-ãêJF±œíů_p”a˜¼ÅÍ«›o¾yíÎq˜: ¬³çÇãÒ*Éæu}}k”i%j]—uN#X׺6¿¸ÓñjÑZ ÃÀâ—6^ìö¥.øòå›ßÍËnž&ÈYë&°!ZÌCžviX‡ÓLƒ+ išÒr(ó²äË'׉±bFyÉrÂÕ¤WŸ}¶¿xvOmພ·§ÃzLÐišœmYÚn'éb:.9cÊ·ßÜŽË«ËÓÍÍòf¹~~%Ôãñ0í§ãzø7÷|­Ç翽c½ø"]?»/ìöÍ«R’™-Ër{xðù°¿¼¼œvéùóg·77ÇÓ—¥­¯_ÏeÆ‹«ÏÇ)χ“f¬Çåúó‹4NTÿæË×Çyþ㗯˒2/WÃÔZÝÛ&TøËÜ;oo$k­yȵ֜ó©,9[sß‚×ÀmÚd Oz—}ü´Z¾ßÊþÖ§õNjò8OŒOÏ^>nçè:"ÕGŽ”ßm°öŽõ§Rß¹SöOVD¼õj{ÝÜãWÀLÞZßj ½uŸÒ‰²D„¤»«jw;°”†aÙkî‘r¤µ&b9%ýŒïOJ§ ‹ˆvŸw¨FQ‘QÒ$2ƒ03Ta¢-¤Bª¨“N´-m0BÓ b*Y0“-¼2L`ª"H}XJh°‹Ø›!." ˆhDTÙnvE"$Ø-ª3:"‚LK‘²¦¬ÀŒhH” z¡LLY±ÜØN%æVéZ+j¢T5‚p XïWt=Fœyx+$ƒ¥dƒ`@Ë­ajªÒs¢RP ÒòD ½;@´­•Œè „½¥OK‘Rµœ+£´V»éŠÌò´ƒ°x1Ø0 ^ë<}‘Ó¥jÆÌS³*I0Šç–' –´]Ûír¸¼¾xvyõ ß ¥4%"åy„™¢E[¥ÞF¹iƒ§õõ¡Íu€9)‰µ¬óŠÉFYVQ„¿³3üËÁIFOЀ ´BVð5â;û/î—óðùè_ý{o§WÕ–ÃßçÃæÛ Lâ—|ã—ÎgȇӚ•k‰HIdÍZ‚­±õÜ÷ÙBCˆ. ‰à{ôZO®óç·ÁÉð-í7'ÝÚ$ñ(\ aÿüÕð£Ue­‹ëᦦ¢­³7? ¤>[¡Þ¥%&üB¿žêõ6~DϘOäE ÏɾÔ!¹roCiAiÞP-šl0…¦€Õ†˜}]×Óia (Z©§–há7»ÝnºØMû5nŽ7ëi^–Ù”Ón¼¸Ú¥4¬QçÓÒZ+¥le¢Õè¯Qk íiä)K U–4Ù²,¥Í-’©eíÉIƒ;ŒcŸ‰#x„”€`ŸÆÁZJƒB—µD]u²Q‡SVše¨xc]›/Q<ž§ç“_ Z[[»-éH‡¹z¹¼9ÌÇõ0£„B%…bK Nmn4¡2\*}áÍñÍÍñ¦5?¥ùöt ÕgŸ_>¿¸Ø](«îåÙn?ìR6Ôu9Í·&fšÝTQ–ÒnoŸÿêoJ)ó<çl—W»Ó©”Å5*T’,¡U/.ö6 ²¼þf^f,§&m9¢¬O s´ïþüôä'éBðíƒzÏXä#Nê©ÎÈ;Z>jø~WRŸîÈÜ+õÌÚbËoºÛzU¡&TÑ.QP홬ª"œaœÓdÕ©Bƒ À6óT$ ǾŒÖg#$ÉÖ¸ˆ¥SB@˜‹4šŠHº§„2„JB˜zèEÁN»SŠ RŸŠ¡’ ½«QH„ÝxŠmL¤"4HO…7……Œˆ ˜Ž”`†\É!ò>¹V*=‚ŒˆÚÐ'3"4QÙæi1(C!J*I‘„ç«=3PUU´Ç½o“^SÕ`˜Ð!˜ íq €! h 5ˆÍÊ[Õä° Ô€{ÏeM)3èÒÄйP4è`6\@—F┦L Y™p±»öÃR—ĺ¶µF…DãŠPh$6eËÊ&°G¶5ØÊª#U6îÔÆiǽïÒZclZ¨G¼-Ïþ0êÀ·ÿÍŠ[šsùº‹øk¹øWmººý*RÚ¶?MGÁïR{IaóÅ£@3ê„,Añp…*p¢’¥z“ûL1w—û‚¯ï-ˆ*KkÛ˜žï)âåÑ"ø Ù_¾~ð–Ó#Ùäíþän{ú°áσX¾w4¿ýä‚-[÷­Gžé}¿XDôd%ô‘={‘'؇ÛÏ¿§HUtV'¬B…ÊqÊ”°lµòx\° ”R×Bç0"«™¸7, ,¯i‡Ý°¶º.ë\–Ç1»i˜v¥Åq]–ei-¢¶~–Þ‚*f דRÊ9—ÃÒÜ•ý~¿›ÆÒÖyY]"ËH6Ú-¨tYJÔ˜çZÉ0¸¼¼0Õ”ó8 Ck~8ÎôH5‰Z&HÃÜé•ÍC¡‡× %¤¥˜ÃN97ÛÅ^OéP—Ûròµš†!Y(‚Æ¡,áIHúÒbX‹Ç\ßÖ¹Ì6éét:¬qùWÏ.Ÿq9îåæ$šeÈCít¼ýæ›?z°Ô³l6ªb­xõæôüÕáp|}<ÞŽãîúúrž—y>ÍõF›¤ãx¸Ùå´ƤëI}Öõm)77u]!¾å“ýx÷gü‹ô¿yg؇«f¿EÈ»qæ[zžûôi,Á\=<<ßˆØ î”ò…–:8ôí‹ ¢ot\$”D*TE5àªÒÀ ‰ÂD‘  Ä‚¡†v„8IH#ÊJ…†¸ (·Vž'$Ál¾P¨“ ¨X ¡@ Ä†šz}i[犊ž^ª†>D‚I$‰šJJ6Õ¸D1rAJØ­ºŒ-ï`¡7oÅ[k­²µnj } LºQÄYDÔ ¶íEݸ<´öÙ‘AHÈfFŒ® ˆTÄÔ°á;nnûìÚ'10Ö‘`=¼4xe8¦6¥¼k‹¸™Ñ¢˜ZÎJTz #$ÔÎ'3{öÙó4˜Ì"¦¥”ÖÚ°¿,ëÙÝ.™ŒƒxñæÑ0ºØm²B PŒy˜ÒE.C€¥I³·úVã]~s¢³9¶lXÑq;BeýÇù ÿ¶È_a¿{3´Ù[q<|ü x›aSøPŒLî ±¢9›7¡pcéo…šI‹> vî>üø J¹¯mDpÎ%•»ÿÒóJç?íC„1ŽûÉ~bØiÆfDxrFô®4Ž÷iÆ>χmì[¯+gSUüÒ?ªGûž5°w&ßj®Èý ¯7fU"| ðjm– g]*T «Óò~Ü ºÖy °U–XhÉNJ,™–Òâ¸Öâ·óqž—ŒÉRJývI)C%Ñ[”)¥qÜy¼jÁœtºØ]ì'[À•4’Ðé;5êt IDAT¬D[Z“ÄìX×F¸j¾HYb¹÷{(ZsÌ©AŠik-ê*M–td` GƒÊshÎe.š(ÒÄ8ä4Üyíük¡šRÂz ûÝÎØ„MZWUØ £X¶ä¹íÒˆANq `¸H»ëýÅվĜ³µÖžN‡Óá¶,ñëÏ?_s­ÌióNDˆæ­üÃúݲEâ×_Œû‹é·¿ý5ðòæÕi­ÜíÄ\|‰ÛW·9¬«‹ðd(™¥-³—jAöˆhŸ ½óþŒ?ߌèϧ;zÇr†ð¢yè{þžqÍYï='~æ¾ûÕßjnýÀ!Û;=-üýþ•ß;û½QÙC÷Âj&iUP‰"ª¤ˆÂ(UȲ1S0uz˜@ƒH&ÏA:Ò_ÆÚzƒ—P!*´$Ôþ€€dHÙ}A£ÇëhR @Eº!›ö(P3ãfL !*Pµ$ÈÑÁŒÐ~.j™–uœ˜Æ4† ŠL™ÀÁ1ˆ&3Z0ˆF®ŽÒPÂyci{ ¨1Bé^vÐîOQJ7¶;£è€¸{•M9ßœÝU¼ÏÒŠˆôÙR£[„P)D’HPE8ÌU‚°Öª£¡j‚liÚí®®v*onn|)ˆ¤`+@5+bMUd0Õàîp¼þæµ%ŽóQ’­ká²Ønİï~~’U’Qðâ%é’¡ ’)UÅZ4/n)µhîØÕiðoµ¾ÛJíçU߉oå†Í^=ºkÛx|y8ͪ¿Âu]Ž+æ;Ú~ãh $b„W¾iõ25´ iA¨; VT$ƒï“Êî%x,Ò?b›vÀÇ-’m=¸›¸öû<?Yìz¿ìã»õò‘ù6«š’¿Dº¾ï:(yŠî0Ò“›õÓÏö4Ëñ~ ôw½óxôéËýòÑ?±ˆ(%û¸ÙÑ»uW·¨õnöÈ·ÕÖÒ *4dëçÈù#ŽpÔæmžUS3SUIÚ˜.‡ýäQ—ZÖ¥žê­M)§1B£i©­®Ì«Ë¤kÖ ‚”†išD¤µˆÞ[ŒÍ„&ÜÙZÓœ´¹eS*EÄ̬©Š[x+¥©“BÍ‚”ÂR ,1¢Í‚ãñ°Öåòòº† o¿är±Ó$§z<ÞžÆÓÅ´Öõå×ëRn÷ûÁ„Š8C²¿ùÕ_?{quŽó\C² Ðh5¸~óêKKØïr«Ñ¢~þÅóýÅôå^ÞÞ¯w×¹åãËÛåÕ|óò6½)¡Z œUêKm-”è%ΧBDï¼?Cþ¥¯§÷Æ÷OèŽ%c~ðžô–X Í÷k裟ÿ–n'>Éæ÷/þ¨ûÑÁi?YQI®‰TÀD B»Nábû£@ÑnÐX&’Ú£Én„í"N™%Ÿ·!èf(™ $u37vG%PÉéÖÕ=¢÷Æn÷2Xh·cïX•TÑnV "J¨PJ5ªˆ0ˆTS µ†L¦)U'ÏÕ]]‡á²aeHLEšk53V‡P­g²š™"´U‡a-õX—Ì‘È* ÐVïvËø%¹,ÝD°ŠìäZ³iÖx³ÜÎbÏ.ž·UeþÕç¡ÀwƒzÀx…r;ê™[–€ƒb²1ëËsœn—¹±OUáÞmï—¢í¾ûž±$÷ãby¢ƒÎÎãdüdñëC­û_0ÉO}s?Ë"pÖ¡ðÝ^!èóOƒ½ÅïñYçãÉÞ˸ëpHï?÷?y·Ný‹cÍ}ôóȃîÖ6S~»‚Ùš,Û•Ím¨Gžéӽƈ€G_ƒ)zÕ7{áŒÝ8äAB„‘(lÑŒ¸¸«††$"¹‡jSÕœÆaEDµÌe-u­­5¡™© â4¯‹åddXÛ‡uYN¥:,1 ¥ò´–Z\ƒƒ“›µŠ–š› #BPkçõ8#¥emu]*¥´æ`óuARAdiŒp: ,t!BkÔpFP¨é2ϵÖDD¡§ IonnLc·Û‰0Ñv6^fv[Ž6è´}®Z 4~ýúëÝ.×¶<»¼Xn´VŽuÿìê³ýçËrh­y£·ºÝE– 2å9Éétj_–”ôù³gbqyºØ¥½s[¿:Þ,à*ÃäyŒblôЍâ™û'šþ¹Xs?5Ï™wÎLÞÓù{‹‘ü:Ô³[ ßB oÁ’ûïóÝ3¢»´±søÀëÿð>6äÉ‘×{+з®ú”ˆ! ª%ˆ†P5!ÒÝä.h"J²»Ÿo¤Cv6cwÈ"7c44Hj“JviÙ±)"YÐ Pªt× ÙbŠZ‡AäÙSûÑ„èI@lN;)CB„ ªq;xPM€„4Ä ›A·ƒKøê­8×ZFXZÕš"2qCq  0¦>lé s$ÚÙrlæá " wQR7%wé\"QC  ¡]JÙB]H¢NˆhÓ ! ’„ ¸„)F¢’¡&U{víeJûÙb ª@Cê¢OmŽÌT* x×#Éx¹¯«G£!«[†ª*‹Y²ŒîžîÝ=!I–Ó±t¸*¤R“$QæQšô÷W`š2`ñnåt5w$ÞO*{«x¸ƒ>ôÕÄ;L&ß·<ÜÙÓýÀ ïá‘<„Xoqç>ÝHò¨è|J E $‡ƒXÀ·¡tÁA"«RAé©,=ìQ·–ÉÙLáªH)@#¶L!H¨TÑ,È ‰˜H’N×aOFqj# %CÀè=ë€$ˆ€8 Þ§U‚ ŠJ¢d@¸t´Ÿ!ÕD †4´"D!ÊP®+¤-‡UUÕsà¶ÅÉ­nÕ•"z‰®²Šˆ®憋*Ýé®Ï» „GÿŽ@Àº¯ghhÈ¢Ê4Q qQÕž§$ /Àæ² @2èFÍM”DPK)ZšœN+Å0hskë0 yTjI„ÓIz¨™r¬of´Y1ÇÓIT…ëAå-u§‹ ­ »^Iе±Äzn•BEM4!¬[ßO‡ çÆ}œéÏzÒ»SRER$`à„ðh\‘¬Xçv;Œ"_Lÿíÿü?¾‰oþ«{ù¿ý§›ÿóÿðŸˆ,‘è;ä Ò·%—:*­=Û]_^Š2‡S™K«€uOîM_¤IU¬ÓíéŸ`÷ÈÐå¼(©*HvçÆŸê~Á¿8?üô?2ªý®z« ød*Æy|ôB{¸ß½ÐSÏo¢}e]Ú…úÊ-þ’½æžhG=”žrVØš|w…ôà—¢b“ó n«Û¶8Ãó-"è>pJuÑ7;u V Hh*=1gÊS΃I®Åk+ÓuÊ)QV÷º¦”Ì”ôßüõ_µ«Ô$˜†]òiYÐʱÌÜç,ƒ‡³)€…ƒnfˆæ4šfA´F¯II¯®’’š$ê ‘‘T$¸[8T§áb—ìôºå”MŒM4X+]..öÑN ”Êš³å!±4ŒÓ4Bu-%v`ÖD¡‚ÖÚ›W7¯oæ˜à€MÇëçW»i*m`­y½©»ËÁj¾}yÚöÏ®%äÕׯÞÔY‡”“JH]ë²LcV«ÑRÄuӠ囯^~å¿ú¬üj¼JÊÃé››7·Çù´‘0ŒÃty‘.®Y£k–ÊXº±ÃåǼ?ÎK>`Oˆï‘ýñ©Ü·?0|ê0ž\­—àJĦ ~œðð×B£Ü"Ý:Oè-¢îâ °K‹µÓE,ÈnCô”>ˆ+ì#÷m ­ÛÊÍGKB£W´Úƒ7µ†“aˆ´>Ü(Ãúúj6RÌ, 2$£ ‡(-zÎR×]·~ÀÜÒUè€*Ĩæjnhõ¸8àU1‡À‰¬–ÂŒT„€ŒF40 *&dÛ Ò)¶OˆÚÛnÑYÀƒ"¾1«Ò§HšRhP”j›I8}f8¢"&hí÷½w9©=VÓ oëÜÊÜÖ“[’^5wÎÑD“fqÍ6T¯ô5i¡¦¬)„ÚàÑ<_\ï/ö뺪jÎù ëR‹Ð•ލX+¤)BCGŽ¥9+[ V…Á‹’-²ù ]‡„‰F<¸ðPü¼AQq×õ€‡4Ä  X7ó13þ‡éëãðõðÛÓ×_¼~5à0à³i8̨‘`ZÐ5/l\rȘF·ÚXÐ`@Ê(¥ë³ ªb=J5œŒw?¸'#ÝqP7wH„vÖ¬lÿ­Oò"Þ’Û¼ÇÂî“Ïé6Ÿ½í°ô] b¼ÕÅ~/Èø!Þúà>?ïGñ#t9õ‰×ÝÖÿ·iúDä.¿ÇD Ðó«Ç£k÷ ýñ­c=÷Õ€>¥ÖÚüµoŠ"ñ] 7‰>n§R©!Ñøè.í­E!³‰çÀ†»zÀšlDÒô„ý@BÈOêëÉSïê$?þÙøFÁ“ÜÇGëBe{üZ²Õ@VF¸Ð旅$½ïX¹-RŠÐRÍ]W…AãöõqÜça”©´2ŸV¤Œ—øŠ •l0?y9ÖRJ´¸ØÛ8æ ¥.‘sѶ2%‰ *ó@ /m•pIÒTK«Ôð:阧Ý4IJ“f¬¥­ëI’åa1¡®ëÜf7ÑlÖÍhSˆ¸Õ—§!€\ÄÌö£˜$SÊÓ>YNÍ[s‘Œdh^÷{“¢ÍÍîÚVe ƒQYíÄgyŸ–tóêäŽzªÿÍÔ‚j˜×VD&»Úû¥ÈOLÓ…17ýfm»i·¿~ñÕï¿ùÿÏëËü›ËëáÖßÜžŽ§û ql5í Ö¯ÞÌ_½<e7ŒëR–:w-ç'‰U~߯wúpí»/ø·‹ÛÊ"?®ô-EÍ]'ÆÝÎ:,çì¾õÙzZ,qwö|oÙ€HwE…‚ÐØ~[îâ&Túø•**Vj“Œ”îA dÁnPzHïš[ A 6‘Q4%’á ƒäœK‹Öšhj¥ 5ì¢ö9†Ü%°Ëg¸A'4(ŠH[D ŠŽp3!™P¶`¸#š¤xxAx¿‚ƒ5Þæ$pK ó•ê*ÈÚÙkdc‹PéΠI3ƒbq&¥³¹;T5TIh†˜l¿–TGµÑtä Þ»Ê,äŠÈ`có¤!d šè(ºS݉fÒBNGTÒ{Ø«AÉ4²! áR¡½ÂVšEE!Ù1³{ dÓ½é˜ÒÎÌJ)Ô€è ÊJˆc…)if¤"Ö$‡jÐÛµWœˆj@† N£©»Gm¨`mR"¼ÂG½IªPsš@EY) â\™(MLÕ tŠKkF5Í’h-Ô„ˆ,:h¤h$dH©Ž Œš¦l”ãW·bÉWÂ'Ão€ˆ#Öˆà>,`UÍÕ#õ浞j0 {?êN‘‚FÊÕ‹ëׇ¦‰CRZ” tjh«ÀŒ˜CŠä°º,kqTñš€NË’!¬3PãáxÏÏ—§ú ?—¯!&ÖãUEð ¤d°âjJ-'`zþ«ÿpû S~õãCü»ÃôÅßâöÿÖ×X–BÅ áv yÆM‚Ïë7õ÷Ù·¶÷†pG8’BTAm½©« ¶.á¡ôÞ)€ û¼Kó†ÇM—ÞôñoUAY8!à­÷jÓÝ[­1œÁ{Æê¦Ž~«È>WØòQÐèc÷Rì ìfµ/zWùöÞ E‰¸ëû<8}€XîNF<2>¦c(ÛÓÅæØG!6!·Á6PyîLùfݧïœi¼U<°>Kou»ÎÅý=>‘͆>²l‹¿>*(wo¢Ü4黑¼u;Äó£bãE?(T B§h¤Þ·Ü„¦ p€³gÎ1‹Ä»%ܨœç=ô —®ÿ@UH’sÚÁ­lAÖ #ΟTo &Q3SÙRïVz=CýÅΈ>%$§|8œþp«’Ís³ººkrËvK!áM¶xé(àZÛ4ÕaršR ww¯wf§mû“$˪I[ %Ò02|-¡D¶ÁÄrÎÙ`&¦òNÑ\PÊ"f*!!–ÖH@óñ°X[-kipÕDD¯˜½zõÚ“jƒaŠdEÊšS†Oò Ó˜ò¶¹¬b2ŽiœôòrSžoç㫵.MeÜï.}9•7_ßίo½àú¢NWW;"°¼YJBì/ñì9¯ž]Mû‹²äÚBZLy”gW©¨QQ«º¨ÄÚ¼™éˆ˜Ö#?»¯/®?ÿü8ä£J.«ÌGTÆí›Ãí¡Oë²ToØè2¢Ý\? ÄO²ÁÇuÞûpo›"ÈÆ>æyóèO` šÌL¡ íÑŠ’¡¨®@t#5x@7uI9@“«©võQˆªˆ¬u ­­ED i²LW¤d=Y»ÓعoBᦉ-¡L‰ ¥Åy»ó½”Ç]¾³¥Û] ôGƒíýZ镸ÄOÌØ¶NÂPG焉YE\ 3œÒé,é¡$…P‚Þ‡ "ºÆ&ä\_‰ÂÐT†ðÎÜNà€È! Ì  °…à§tfo^7EÄEêP-‚ÆM¢›¼gíª©ŒÒ•–-H(èFTÈ ] ‹˜ 08\¢¹×T )ÑV“t Í:³MM‚ŠHUiÔªâd¥úùÖ ˆ€J@Ô*BÏnx½8s@q–‰t_õîÇÇê%&$DM»j‹¶"U¸CL!i :NÂPÀCZ¸ dP]zâ.¶p$‚”€cPÈ Q%š„£‰xƒ`J;7$ÍÊTQ„ G ·ëŒy´Õ«[]$–Ö\¸ŠÔ¤%I PÈ`44¹€‰ƒuƒôw6õϳ$ßýÛ¿¹¾žÆ”_½|õ§ßݾ®±Îªvuq1Ïs´¶0zQ ûqZ¢ÕRÍðÙ•=ûlº¼U À´O¯oÖùvØçýõ4^‹–¦n)éáµiâîrÌÙ–u>Úó³«ë¶:`IÒz,‡ÛÃÍk¿½i§C­ek²¨ÀL=~ÞãÓOŽˆî7†mˆô‰@á»I¯êï*¶x穉‡:û §NAÀc ÝLȶø÷ G4ðqÄ  Öºø8ÎÀ$IÛº"*†´˜£8´ÎÚ»vU„„Ré=‡¦ðB6Q„xô)W÷`'ôPôyT 5”†„|âRv‡rÜÿÁý£CºÕPBU#ÔÑ]ð6¡A¥h÷ò5z!** "‚¨AEî#ˆ T5¡ƒ¶Ø"¤;‚⋇¶d£Âàð…Z‘(B&d£9\¤‰†À -GS)ÂT"±‡AÖþÙÌ`~;'g«»â—²7?¦VJ K(k™Kß+º¯|ü?Ú‹_ÿú aK·ª@Êš‡½H#˜alÀк–I[—ÎkÓ>ôг¤j))Õ³J­µF)Q©»_ávƒ @ß(GÛÜãYëûe¥—ð½E_ÃÔ®ºÔ^•ŠsÃDìÕ9ÿÈj¢äl"ÛL^¢'´vvÑ¿·B u²)û±1Úæ`Ú"Ü úynV<ÎßSâÎRMÏ›w©€B(¾½µAm'¾ eå<‡J›«Ì} iç<ˆàÙ*™ èù “ó[¤¯ØÖ>èL=oÙ&Û”+«¨Y63£…„à ¡ )”ÎÓ䦻ïÂÞwacG(¥EO‹“`cƒþÿì½I¯eG–¥·öÞfçÜîµN1ú IDAT5ÑdF6’ ( ª‰Ò@¨Fši¬?¨ @ÐX BAª”*3¥l#‚d„ÓÝ_{ï9Çlï¥Ù¹ï9›¬`ƒAð"àÐI÷ûnc¶›µ¾%A‰¾)B!lž–ˆöʇËJïYcï~èˆ~7:Ÿ/×7¥ú—G=ˆÂé8/S!éîî1¤HJW÷X¦’RA2C®ËT»‹—/®¦éôöíÛá°I)-'W…ò8n·Ûa3žÊ­ÉÊ=’~™ÖºèúA–ÔÊMiY$Ó|j¤ˆ”ˆ¨îÕ¡4`, TŠZÊ&ËLÂ+a5"Ì0Žãf³QM§Ó‰îYòÕõõrt_î—iÆ”²ž°Ô s­ªšÇ IÕ6&Ykõ‚jӻȋÛ{Èöæå\o¶ù¡øf›SÎË4{Ì KjµÆÃãÃ/^%µ1eS-S9žJ‘4iÊCÂ`KxÈê”ßÝ×1X~¯Røìû€¦óh<1´=‰4ñN²Éƒñ>$D›Ú™U¢ûA6y`Pz$…’ [¤-ÒVÒ`o^WËÐm 8‰HµXyY—mD>˜:’º(»¥G£U)Í1×jûÎD[bH[éÄ:"o‡¯ÉÃ;Wõ¿ÙÉcóŽãUDD„'…&[eimþÆFÒ] ¶þ”U fÕÌæÜ¯Í¢ƒ°ÖÜ€‚¾/NPAÚ5DUh¨‹x Ý¶ ÒÇÞí.æ9%–¤xãú“Ks|=ÝïT€±”(‰ H$U `b¥G²AL"U µÐQê²Dë²Ä»àPÖ^HÒ: ×µ˜2Êl&+öH@6ø¨¬MQ;Ø›ƒm!&eI¸±5ùMvì@ˆºI8'%a>[¿ÞÊ(ƒ´& îý53iÄ(CÔUC•5¼Ï-¼„«„3µl$µ0Ô0(>=ýÄz žlÀA"EU_'D„šd¯)ªÉ$ÆgÛ/7E߃ÝÐû)=<«‰¬A­·È[ÛÛÍLŽÿõ—8þ›ÇÿôG¿.óâ5Ç-¦*5°[¨ŒÑcl½PÜLÁˆ8óLœb¤GÀÌT5i† 5*)ƒ™„4yk²­R#>Ï1]wæÆ¨_½ízÒx5 kKfö,j„‰RDUIÐ×òçM|_æ¿u4ÝyÆÐ!­ ·>iø’Âë Mø¿cS¤@(¾YHkÏÍ‹F{XÃô h´K§ Z2A3¾ß)Ñ"qåý}[«ÑÑI]ÚÎáÚò¢¤ å¢/Êø´±i,µsS„•ª«ÑG‰õ°8÷¿ñvîY/´ž¶¶žÒÏ~—Úv;Þ0=ç´]‡hÍšA2Ä‚@tÌ©‹Äª‘^ÝjÔÞ˼÷ñj#ws AF„¸‡ha•^€ëêçe—è_PW#S»7~èˆ~‡›¥õÄyæÙ@ñhßâZ"¢’PK:Ï%)ÑÝ›Ûá1¦¥Ä¸Ûz°,îʺ3Æ”›OÇRP¦R+TQJÉi¤µ’΃"iÔBˆ$p+ MþÙrK( ¤ŠYN–s‚pYVä–r¶!¬ª°¬ÃZY¥ž’R¹,ËÝÝݼ7–_^]ç4l·›qsŒˆa“UQªÆ"(”û½Ú¨‡‹ÝõõÕå«Cøp¿ÜŸî|fql6Û´• ¹Ù§Í&‡Ívj ¢Š`h·Š»QËôx¬µfMª©LÕ+.vÇÐÁÄÌ“´Ú™dP¾·Ä‘oÚ}´ðµr’ouG$à9[ý<¡jC{Ñ¢lÖߢ6>Ao,5Óæ{A4£‘Æù†è)+ÔÍβ…Œí€áʶð>ìÒÅrSn?}ÄcÂ)ÅL†l³¹¼§¿hO¼¸è«®¹v¼4öi+J'Žr¦˜DÔóOÍè+|”ïzÚ®" ‰/ä&ñýràý÷w 6Aë T$ Ê@“t @©&9•eÕÑïêæAÅ(¥‚ê”Jh±¤$Œ@¥¯;Ò;­[çx  ²€ƒ0 L`К¦Ì WzYw#ÄSÚ¥+RÝ~ YàèYT!þ,JÈ…t2…Š&s8I—¨Õ½¶gH8QBÖÚ§È׆œÐ&(²÷¿>TkÃW×6Po溚‘D@­9‰ ¢ÖL9!UÐÍPt­7žm" XQ¥aÏ¥+Ú'Èk]ó „‘ØPz4I*!ðàRéN 1š¦ê!ÌCáPK™âÕëce¡š €bV3ô$>Hd©†%|!] f:xN:ã‰ï¥_7]Æ÷¦-z¿Pj,1J軋ÍxÍpµKe¨·¿úöù§÷å3¤#PuÞ‰[Ô $´8Û| áM…]# ¸¨±,‹™¥44rqk˜8äÜ(Ù•µ:+«€ÇyŠÊgäʵ‚—÷Ëþ'ŽJï¢õW0†B›Ý²UâTE„5i(©Ò•Kßñ¦HóIjû6tJ¹ˆÁ¢P„g•»ü&+Jý:.ÄWÞ›’²'ª¤¢H!`…‹ˆ÷Ø¥UãgÔ9 l­…ôfæ‰ÿеiìžVÊS»OIâ î:ß‚@¢ˆ¿yúÚΈO?·*¿yÊÚû=xîJj\´F¨°œTáy«Ž(ÅÝÙ£Aï(M2 bëy~^r~µ±ýÍÙ "Ú¯m3Û¯\_öýu³¬O®­þ*üÐýÎU¨íŸ˜¾Wk®Ÿ<44W‡Çt!¾*Å3æõ‘Rë2‡WY¼FÔaÔù8ß¾»Q㘓`pw’; ƒje$“)¡£Æ 6Ùîí»ûP‘MIP!¢±;lmL9¥DR ‹""aØäÝao9MËRçP6; :¤„‡P ó<ÿúóùç?‡\à?õëý•ˆ\]]¼x9–¨y»ÍÕR%HB°{¹µœ6ûÝõõåx9ÌËÃlSÉto©'~±Û~øq¾¼:ämªuQE™O©Ë$Ê”d€*±;u>‚j¢ûíîNîØ û‡2EeÔ¶vm†Å kù÷l'ù-~n¿‚uöm<¾ÆGô…I`<-ŠÖù•´§ôÜ\‹FˆÀLŽ&Ø,ý0Eµ IÔ,ÊQˆºŽ¯pøØ/^q{Éÿèâ§{»|øÕòé_Ü<ü²N¯9Ÿ†\ë:È×6KxD:cЌςÙ »Ó¤Ðéb*Am¡ÿ,‰H»Ê®± ØÓ´wGq&¶Rž‡yú>ñ_ø$(V·P44âtεVU•ú ´±n [@ˆœ Ž FÖÜÞA˽ƒ² »k§.ií –ö¾¸Ê8½6'œ>¿³ 7„ 2Ôü"$©ÞR&…+Úºµ©laÚô„ˆ©iÊ&ðSk0)U¨É!Æ– Eëѳ‚Q–çeE´ê<M)"Z¦ÂÓE” £c—Uú–^DFD›Q|'oò3šWu;“w]øK {5Wи¬ÛõøÒ²(þ}€µ±ø–‘³¥¬YUë) ÚÇ3Ö,ÏhM:Ö4Òƒ¥³à­m‡L@­âp\ØåÖT~5âI *ÏãvzÐL£~ÎH]×Pü†)à²jðžÇn¬¦&ô¨î>º;ïð] ŽfƒêçQôï’KhåyVŽh4;À ÚaCO÷Wå^bG u)H F뎫vLvñµtø¸À¨Í²ÛœrÚ:‚ý¡#úŽúuð,ýfê&_CÕˆ'ÿt{«f`óvƒB!(4S2ŽK™—a wŸ¦ã°Æa;ŒpwRT’»Ï±¼»¿yùÑõ‹ë«¨>MSºßîöÛÃK/¾”Ûw÷§SÓ˜·_\s²QRÎáð<æ…ÅO°Ûmº|qiÉnïoæyÞlFóqV·ËÃ%Ûz—vw7׊:ª¦Óãñb»+§éÁyƸc5ÿõý¯Çì_m§å4lpýÁÅ0‡«]ò›w¯Nã•]ì¯/.LJ»ÇŸýôgÆR—e.÷“€ YæÓròa3ŽÙ–R§‡ûÝáòrw°ˆãi ÷Ía'"99¯>¼øì“ÏO§åññ4/P¨©Õ¨"†4/þ[ýœ<ñ(Ÿ-aD¾µçëv;ÿqá+­nÏ?Ï_…IAœŸç{¬ÊY/„õ!*ET#j#a¨2gÉ)™ÙRçœmcYµ–0“M¶R"q*Rp©i»p´¿Þÿ*nyÃ+ùÑ?ÛýËÿî_øáïï^|¬ûáP†Oÿü¸¼ýìÝßÞSq¸ø {*KÚï/>{ýkQýðãîïïOW×WH)½y÷V6Ã}™îÞa¼îÐÒdƒ&v>h²–@Ôä2 Öî˜öãFD›v¼'s9/ˆÖ—ETP#šXÏß53gÏb Ã0M‹[Çqàøð€a÷{”Y[ž7‰h\4’H–I5`cõ^ÛîôTª2„  &ª)8¥ïmzÀj°¢ïîÕÚ~|´N£1‚ÚagÉTj,ÃÖ5…«”‚ÙK wÌU4ÔTm3e%‹`í’J°°Hh¨Uº»@ I"…¨êŒEfØ64ª„‹lrSmÊ%ÒÍL“8¥Ô™€ÙXk ª Áª%R6=0˜*LÍ«ÞVÎÕÕÛjÓtTÑMDE œà(Pa„^!-M¤¥£zåÓ!M4XÒœ,Ü)qjRD¨µ<¦q¬&¹.³#B0}¾@›‹Åá žP ž¦âK “Ðv×PŒê в%,¤Øšr³nÐzºÞZÐü>oâ«UËÓòðF8<¤/.7É?ûüïþ`³¼˜ç?ù£—óÓŸÞÝùüç·ã½¾° ï¦×P$8ÊBaU$…B`ÉT-"j­eqhNJL%¢5¢¯6`‰…QA3ËÉš^7‘žè÷^0&Gêy͵F{™ŸßÛR:*CÏ=`Û¯o]²„Õ‚¢ª$…ýü5ÍÃ×0Nƒ{íù%%ƒ)Ô²Lºq=Ñ&¢m»«œèÉ¥=¬¨^[U-ݶٷIÒv]mâtYåiç‡Q,Z2tNÈI-#'$¡ˆŽ•^èsü5‘‡48üÜËõÿ ÜC!ª¢¢¦–DMU è”Ê„lõ¼±¸ùH8'«ˆ­Ÿ¦^«Xó]£0µö_¹ Xí+ëÌõº9¿qMƒÇg)"Ú?%h–›ÿíüJÆŠF&xÝÆEÙFi°*m†ZÀº ®ûE›êNCJfêîmFÝI•„ £}÷ƒ„0<št~õ85´ç:!ëJ{JË/ €úáñ<Þ›¾üF•ë×ü†Éót¤/þÊ.Ó”¾É…I6Ž¢–Ep7oiwئ”T5ÀÊZêĈî IªƒzÔ‡ùñ4X ‰)£„—Ð8žN)Ꚍ‰@¨‰ófÌ9›ñªj]ʲ,Ëɽ‘šÄ‘°ßnu„3^¾|yÿ˜ó š—ãT—¢@J€ò³7·‘p­¸¸vÃÕ‹ýG8nŠ<×”e;Œ’æ]Þc#Âív[pº}÷n™Oãv3¨ j77žÅóf#²”ùaºŸ"“$kAAMy¸¾z™íêÝ/˱ñuͲ¶j›ßøMüáñí$ç­eÛl^M$™H’&þ¨Ó\Û4Í– ˜Eb*Id†ý8Ž[ÙÌqXp©éUÞ^^ëÄzé‡ëøøåöǯåâtÔ‰w·wŸ_o~4æB¿WâƒëÍv¹,±=¼Ø6ƒ¡x9ìF™ã_9Sq ñéãûq8NŠ›G¾ºÒZ¢V¸Ã€ÔìP:Xh³™ôØÁðÚ”sä—»S}†øûÍÒÒž¶C ŠX¢¨´AUuC Õ݆,Ú\$‘P†6ð^´t+Ú¨?‚T ‡¸ÙJÄšøÑªºgEœ4<ÛkGaH£²TB# Aq¯E’H GxTôü"C$À$’ÐŒY–:ƒD8;H¡ýµ!™âa¢É«  ЬÚâ÷59J˜üþãæ£7wM: ­…"fYç!Þ”»Oßœ6¶û~þúÕb·ÁÄ·Çi“_¾ú@Oµî~´-ã²} lªU7 .*‘ !m©ID³V„•Í Únm ˜ù6# ¤QÓ#‹fµœb•²µ„awgMµÂµÒ {o*뢤Y,¼ÅŒuKÿw(g?GSaËå~ý–岂7Ez;´¾)¶¶7ÚbœÐ=("kG´iK´õ™fÍjê².ý}žÚ4ÑO¢Á§çÒÒí2ò˜ò¨CR3K"2¨-á“/âB.&pz~Aûá}FÅôÛ ÎߦJ«à4†]¤sù“ˆKÓAœ_¡ñ,báüh…Ÿù g;áÒw¹ÏÕ©Ùÿ†uפ®ú´hjíVã/Šˆ²+Ù¬gVÕÖ#)àœ*•¢+±Í÷mH­Jƒ§\xi±ßíMg„Ê èùœ (µG:œ­²s Ä{!FýòSH|1ƒªYª~èˆ~vD¿‰*éßÕ*}1«ëI +!ti\£æ5žPÀ°Û#¥a·ã˜ÅQS‚ œcbõãñhfî%¢ÖZÃË2 Yæbˆ`¡ûâLŽ ¨aYDónU—²Ü?Þokí³à`Ãö"EQU…xÞ W/ö×v `·¿¸¾úàøpªsýüáõ¼`PÌŽQòbƒíåæêƒËq'û« x\§²Œãx¸Ú}ôÑËÍÖnï>ŸN÷÷÷÷·Ç㇡øç¯_ÏÇzy9ªêñ¸\dì‡Ý6³¡"¤"™É6—öðð†ìÄ4¨AìÝÍÝ´ˆšš‰Ô"¼8å÷ÜGô}ø*±Eb6 öù脦O¿v±gh¢ ÐlÙp"L¢ešK—iw¨¼_åÍì_l¶W¿<Þœ<ÒTü–q‡‹‹;4í6‡Û»ùWóé'Û_áÒ—mŠäŒ2D\›Ç9d.Cœ»À›Ã«×¦í›Ç›’ƒ?‚‡+©®¥°dP› §ZJAˆÔNh„4 Òù¤<ê²Z3À†úÖ‡Í …®¾X×Iñ„ îŽ^U5„BBÌR6&"0 .9$”Ax¢E8ápq×îa`*TSŠ@̤5 Id€e¨lw;¢ÅaD6,S¤¨+\4ÜÅ•!¤`!ÔV\  šZNT@¥•a¡!&: F‘A¯ˆ…¨î‹„Œ «6§D@¤‚`B‰Yeh~Ÿ† IC%BèÁÒå/ Ò ª Â|„& ¥fJ^–å±ËyÖy{TéàˆÊ(1KÒÛÈ“ !î XÞÂA(˜ZÄ.…àô³¨QãѪ$ # ¡lÊE Â][ì’3‚ðp!ÂÆ^\©¦bj€y¸Öd“á·tÄæÇ€íåoK<öx^M&#Uá¢_• ³ÞGìlçßãvHqvªœ£x„^^3î Ÿž–ÓòòƒÇWÿ~ü_`ÿåa¾ü·Çá~ù(ýÑ'—ãß§å‘)—ì´{(éµù n±˜¸ÂJˆ"µÒ/‡ªR4YNÙ<…(½1Û[¯ %i^gîâÎ{Ó€…ˆ»»³Ì‡¿þåÏßùDÙ&õ´ýá”Ô‘1L¾Ü—ZU¥ª‘YY®ZÛ”Úú™3ÔÏ\[mœ¶^}«¦£GF¾ÿ>¶¥‚¶˜TˆjJ ÃPjjšUÍ` :S[@EÛ¸‰ÃI— #u¤oQ¡¶,“Zò`–)µ°²lÍOÔ6”Ä\R$jÉàCÅÉ §fbJEHÇ·!£x mŽ¢šhRŒª ­Î!¸MÈÐ ±€Bñ6¾Ó0g(£`+DG k„65I$¥Ô¨ä¬pÀCÝà¢-á‚5™UVHÄ*1ˆäóØ“kWÍÃSÅB¼D=—Â0VGmÚŽ8.G˜›©Øe i °ZeœÃëiñ–‡¢P)ê Z[¢¢‰2)ŠfKp¯Ì×êIdd$:½Â]P#D’ ‚]ˆÈÀ0åMV)g È×;¶¿;¢§]I3°HP¥”yÌ@0ö{üáò“«ÿvwúãÇùå¼y“~ôéãý'õz>•Gýy]kµÀÞåb±m̓[Õ¹ÌÅ ÐhØ,Þ IDAT‡X†& £jU…ÁLİ,KYˆ°Àµ«”TB5ê²4‹¿R¥rdj³°…šKÔ ×)Ì“{½ž-ÍÏN‘÷ÇêLoÒ´ÆWx†û-ßK„ «$i|§Æ-1P[Ê™Z8HÈ 2¢±Î°uÕ©UöƒDT’P• …¶G“$ ˆ/Ôc} ·ºö[²ÞÂÐgÌ^çZ_*¼4èK;ÂÙÙ*ÏîVi†–¶ŒRsZz2›¼}"zD­p (zJªEˆm§ÔyŠ& Y÷Þ¢oõ%Zƒ:4eQÃÕµVÓ’ú”Xõìï‹«òM´uD¢$m[²pi_´ÎÔÔ#:†Þ\‘XýN *B§ZZ%óÖ ºÊ!¡.akF•¥y±Ý¹í5 ‰îF¢Qú|î‡Ñwõ¨õÛ™™~¦7¹úìâѳ¡ ¹©¶Zq÷n®­·Öñ0èÛí ª·7VkuwM’SÇ< CÊÊRÃÁ%:òÝ£”R£n®¶Ã6Eç_š$hf»Ýþññ±..*JÀ‰D8Ôd™¦ÓüÈâ%îw~1Ûêw·eztu]*_\]¾úðãããææñö®Î1aº/ ÊXÒˆ2×ã6<¼óúøæjóËéÅáxw8¼ÜsÀUQy}qå4Í,›ýV7±Äé4ͳήBÌ)ªxMi©ÇÙS(jpzlS‡7tˈ>Ëÿ´aW@õ®±sú\ 0ƒȨ’$‰G†ìÔ6fƒJJ@V1¤Ãk¹Ôñ…l~¬û?¹üøUl>}û.=0EªóøúÓ_ÿ«ÓßðÇÿᇻÛ_üâ÷×ï~ý7È'lÕû¼ xxûà\6—‡Ó2ãx±ÙÉ"ö蜗ù³[6“\Ø8îvŸ->ájûñ( Áå4ùÒúöÂL÷Â8‚G)GñIbQ¸èã<ã}·acõÔê QJDóé·ú€ªÚÖ _1a6ÀQ×K¨J228;\X]$§¤IÕU;bUA°Ð IÓ(äðÂ(M@QG3ËbVRŽc95É 5ØýÏ ¨ATÍD²†Ee]ÜAØSØ’À2$"º<žÞijë@S4 ¬¤C€LévŠbb!lµ@f䈡ʶSŒÐAÅ ¦f5P´Z¨ Q"ª÷”Ù`-€Œ hÈ&ÛÎ$)2e¨iÕxtN|Ô`u©*’l‰8–º0Q£2fo"¸NJt„#jÐãC ƒ‰–$„ªƒ!í%že÷Ò%%*ŽK5Bt,P—mÏ}6E—RK »Ü>{°D-Â$ލ¯Þl© óÜȸB Qá3PK…ä*‚,¾¢"–øÞÀÎê²¶Rá:yÈÄP€%£ È{Œ?¹ÜþWú·é/¦Ç›þ³Ÿ¼üÏ·¿øì“éÿŽò«ò:s ûlˆé,òðh/ûH7MìÅ'sJ°ŒaT I`jÖ¶ƒdÅ0ˆ Tám»aIĺͼÖ!t±–ù¡,MKFµ*QN)ŒÚâ0{áˆøR]Ù²ÎBðle}N"âwDV bbͼ¤ìŽ@(Ö|š"©¨•Ùd(e‰0ŠeMFsœÍw\EU" S˜®ðJ‘ %Ÿëņ̃PAK8b®áBUG€N.ô…eB™½#jÎ>m(ÎäƒX;ÏJ *ámïޢЩiÌZO"b Æp&˜ΕwÊ.%lêê8…<C¶ýÏ9.ï ³x>)ûø¤}zëûôMÐö<Ú^:“$"¡Š™8«2"ª‡ #àѹ mËïײQi-ØrTI1ªˆ¨˜IßA­h›ˆ¾"]ã7ðUØ@}æ½_Ù '¤-?$´þÍøÿÑ;¢ozìDZÓ£óç5À µETaZ¼,e^n^¿UØ0¤¼r –R¼¢ælID¢T/Ó\æ˜O߽ضR©ÕË2Ïó²Ô9¥åqšŽb›B–Óônù<7† «)aØdNq<ÞNÇ0 cX)>MËrZ Z–éÎËãcÝôåGWûŠ;’e™¦c<¼¹ sÙ—ûCÝŒ/nßÞ×i2*} …í{TD G‘ …Óý©.SºNû‹½ª™My°åíÃ]y4Í¥i³Â 5ATâK¯ŠãÓŽè·½Ãù¶ò‹¾­G‰ñ}½A;Me£fªY y9l¶cÏ´UÛæ¤Y%rHN‹W5œ¥dʱÜ?œ^¿9L#Oúë‡û·KýëÿëF6xxÀ‹Ëáãa{ºŸê½ÐQ¢oÿè'xšO—¯>8N'3ûðòzo¯u¼ûùgs:þäÇ?®»úwwŸ°çPÈëÍÕ^ÇXêY¤îöã¸É”@²û˜ß,÷¯§»·åÁëR*ª@.OàI4{Êì×lÍ« ZȦ±nâÁ÷ÐÛ-WYÎÀè>ánÌW¥ƒN—C¸Ö”Z´âŠñÀX›ê¥+ ÔBe·Û% CD•ƒf¸¬Nze¬þ%  YDD“j ÷XP(6(”U*a-•Å)çΠ2 ZúJ¤Ëñ%D¸`I"%Äší#ĵ¥‚¨¹– Dvݨì¨{‘ Ò쇩tJê¶È$JRJa‰¢p$òBpH“dJ²¥z™«ª˜!j™k,n0S“¢²UÍ2"ÀSå©*!’êêÊ¥.½Î-ΰÀ‰•9¼r†[-zk#H U†3f¤æ|"D¨=ñ–Õ{í@Dj۪ϋ´Õœ›„hŠ.ʦÇ#è¦Ò"PѵþÊvsÜû[•§¦è÷x¤¤Ï¶(xžQÊ7ð„$FÆöîø»O ÿÇŸÿô¯äô3Ë0;ô×õöîÏpóýÉNR¸ äzÂ)¨A7á>‚Xs}m@M³!IÞ¨YL¨Ho‰5 Ô»ŠUH ï¨w­1¼*મˆˆUk“E)ÄD«„‰¶àà¶û+²å=ðígò¬úG8‰¾îù‡î5j2i˜‘V—·1 ‰$mq%ªÈDŒ­3‚ ¸HbGèsôœ0´åʱàË £ç;‡Ú%ɵÔÈÑP0Mj(QP+PUœ—_8“eMŠ/Ã…È8™µ˜ªE„¡­Jšõ°åÆE6ÿY“ôź~òf®×§¬QYs‰žú¢Öp¶¥V{n\Í6‚³°™yDD²ˆ˜$í¡LÒ£™†À.R ðè[²è«ºXï#䚎ž2JÈÚà f˜Bö1‚ë |Úg>1ÙCõVÈç:^”°³xîÑww˜~CÑלÁ5ð+6‚_Þµ`¿UGJ6'´Š2DsÍrJÉLÜ—ÇãÍÃýTNؘ甴ജ¦y¢`pyqm)s#ž˜e©UrN¹”â9¼r©…3O§Óé„”°<¢.HD·! ÙÊ\OÓÑ¡õêzŸv˜ýa³%©µ¾{3cF5‹–âÇǹÖ:ŽÛé8#lñEKU¨¾Lûá"Açy^hœîëc­©%*O§Óøâ*I‚¸/ÎR“æÝnwyu5MS8p¶aö?ÎÕ9ìÆËñ…{@e»ßÎåíÛû×§ZºÒ§‡š­à–ßû<¢ïш¡—wE³ bªƒØ bª‰’À·—>RÅ%éµÄãé¾ÌÓfÜ=ÌÓëû»ݾܾÔ(?~¹­ÓmÒ„í…o’ÅíP/ËÑ7ŠÇù9?{¬·Ã0ïRåôøøxœ×<ÞOó<Û‰Óç7¢›¡jÜ/¯þôÅ Ãë›;„rª.±Q l¶[³——‡qcÎúît;z0¬$­@$$ÁV1 *Ôµ6-º6R« C@Ô(±pYíUg7l¹T¡ªrvÚ"RëB:UÔÕ #B#fŠJ4јD ò˜Eš.<ºÓ@ j’« :Q5ÓI‚ ¥Ô®Ÿ@37õöÍ%‰E¡¢3„ ‘#fõ`„6RPŸè…uËXgh÷ G¯ˆ–¬Ô‚š´#§X›N*”€(  ©nrÚ3D/¨[ÈFE¼¢qŠ\ÝÚ±ys`b)%ƒ \‹/G&.³\²1 óÝv$«ˆäÁÌŒUçS,§êË,F‰û ‹@§§j**lѶÕÅn Õjº(ç"ÁæPèê›oÛ²^t=¥6A> ¡ L¡¡ 1¨ µ•5SM0…ºh50F—¦€Æ†24†µŽH™[c³ä¨Â@ ;ÂÈ«ðêû&™[ëE>MË{ƒ).†ÝEúøO.ÿô¿ü£íã›ùüûÿïßàêÏoÿÙÏþù2åã'“ý¿ZnP7.>©¯ïà°…³?L‚yƒ¬Ø#ÃÃ#Ä`ƒå1éF›QmØf²k”(î.êÚì]+á¾[ôª‡tAJ¢([.WÀƒ‹uRÎ077‹(T]„½<Ž`o Ê:ÀÕ’(_Ç=7ªüÖoG¶æ-­ÏH;4%¤‹Úàˆ "ŠÞGG„‘¶äœwòT ³É zԳª-2Öfà¹hÙ¤]ÜÉâZàçN#€f<¬@5)-3š‘ŸRM{ˆªk¼ÿ{úY×ÞÀÎ]y“ÿŠHk?º§P"àÒ’žŸ-í(`wevQGf¯‘¥ç÷Sžu€*+ Þ¿–•²bçDºz­y/µu×=g Jæ§4½[rñÒ$§ìÀîã V¡ö‚g¶ËcÇÎôŸ/@E%ÂÛg¿/Ìfü½^ÏT‚M¸®ÛÖ;ñ‡ÑwõpoXð}MgõÅ;<ï‹z*›ëØ rš_Ê2é²È&Æ”5¥d†‹½ 6C p>N·÷ ±Ùàáöf;¨Wx‘Ì2Ÿê|,HØmvC²pÆî¾¢v;„ *Ú$cGRb™Þ¾½µ\^m“§‰ÇûéôP>sy)u¶ý¸÷¹Ÿüê´L)¥ãÏCЉ ÌŠ™\4sSKnðætWoç!KÙåã<½þå_æ´UŸÕ·Ûí0n½Äa¿/U–åT}šÈ0äüðîñêrY*êIöûKøæáî¸Ìð }ú7엄о‹Qô´šç—À{wÍ¿WŠÂïÖã 1yÒ’èžd6ïß¿Dj'{ØÊ½©`T$‚e!TÍöðlköñÅ&WŠ7z¬GR‹£.ÓCeåíétS¹ì/ò«ziÇøåÃÃiZ€qsqÈi¿}Ùе~WkÔËÍË_&ø bfˉHùåË+÷rW1¤­§’Ç=bþÅÍÍÇ·ïò&®/®÷oËñ³OÞ|ðâò {“×ýFw»í\âþxûæîø ÷z[w·ãX>Ü;ÄVÞ<²xÌ––{ø„8BjQÔj¨AZöAdˆê®3뽆€f¤«H &WgaÄL™Õ¶š(QƒAWøäDõ¾ #X½k¬x@)&’Q¢@ÍR’D ÔµVDä¨BÅQÙIF„F¥J¡ªªbY’X¥JR¡.dÛõé•9ÞõBØ&Å…0tïD#¤Ãµû€EB¤Ø&ì-]Ùpt%Ã^m+Å+ÝY‰*î z©ð€ˆ ›¤YŒˆpÕafE¦]¨ Y«*2S<™y¦£Ô‰KÄœ÷hÆDº„pG¡Ë2ì÷Ù5BÅ‹„IH³.¤­JQ™ÉS¨‚d4V.U’2¤á^l߉5„£B–´Q&S…fÀ =ó<«ŒT%¥ÍW5õÂX)`A 7 ÒÚP¶méÖêHÄ’m•³J˜'tD§o7/¦S Ú¿Ül\èý à]êÞx™î`i’"-ï­eÚ_ݶ|¨ÑÒô]­5Š$Y!*IÅ ·U¼¤ ^E ¢„J&UÙTº£ª þÛ·>º¶{Yuk+ׇOô Jû)žâˆ„ŒŠPƒ)"$è„£ÔÁ˜-’‚ÊX¥xÊŽñn)®¦Z>m‰ÆUD·VìÒG8Qˆ`oŠ|5»½§ö<·F„ Ú¢.ëyµ„#”ñÛ}oâÖ~{çèW¥dÌ犡¯ÛëfA•~†ÃU”CB,ª²æãý1WHJC_üøƒÎóôîîö´ eD`:!%o#ûÍÁ0h³f3•†q«¬eªôˆ¼AóÅÅÅÝÍ--ò¸]Šç_¼îvÛq7–S<ܽ;ÍsY“ãÆ‘×/¶»1gÛ{‰››ò«>íîñáxzǺ,GÿÅß|róùx8ì|þù w÷8½™‡ Äôâ 9çÛ‡ãR±Ýé¸Û+t:Ù`ó‡Íxûæ-j\íw1»ÿÿì½Ù¯eÙqæ÷EÄö>Ã2+«XÅ¢XÛjË’ A2lµ ýâ§Fÿ[þ7üÞýà ÃhXÕ´Z¤Zl²XCŽ÷Þ3í½ÖŠ?¬}nf•H¶¨¦’u(dž¼yꜳ‡µ"âû~_Ãî~*MýôáiâZóau þ踫‡C…w$åÞ7°‰Cûýó¿ü|øé•°Ÿãļw€óçùà.+“éÙaÿóÎ?³]ùÏjî~jPê/¨hį»8g>&¿úÖ1BKi*6»<‰&÷ 1¶ ¼¼ÿå/qåzwóE¦Ëå˜3W ìB«õÕÅÅÅþt|vû¼Yݦó`QBæ‹Í÷î§CÜ=y÷½ïýè»íú±6aļ݊9AuLùÕí kzsyC˜‡“c³ŠÏãªÜŸ>Ž!¼ûÎ;ët}]ÔOê««w¾¯·2 ïn\Ë{—«o¿÷ÞVÞ9¼˜þü»ÿŸÓôä5¦áP×Ýí?­í>Þù“çí ãüÎï?zÿ›—{»› Ÿ<Ýýå÷Ê‹ÁŸãô#”;Ê:ÆÝ×_Æ‘0[vÕgÃUk™6@*ÕZ—DPQ³ÀÄÅåÐV%ðªF‰ñ2…"lN‘ n$ÔÓžˆ!˜6‡Gò@qp+^&˜"v‹c‰Wâ"œOE«ªC8›Rq 21“8K²…Î0±sDŠ`†j£bTÂd–zT;˜33ÄÈ»š“žsx¼w\za& µe^kŠ¢ÖÌC.Ú/VÕö×äo‘?ºà*6W+‡ªG´ƒ¡‘p‘Ìݼ F…š¶VmŠ3GSž”÷ˆ°¾BÉê’$ #ó ®sQ9žL„Ö›!n줯7²=ùÜNs3— Ã8˜ë4[mPD±ý4Èfþè%Ø®ÖÇ»ýˆu›²;™™y\® ‚cv28UÇ  :¢+G‘̨¹:*¬WóNäè1DnÍêÌMÅ[€Pf Úª°¾«ë˜ãúÊâ\§ÃväÚ¢&Â9º†~I6ô3Ÿ?É@RŒ=A;ò0ר:4ªz9ãXý!äÿéñ_Î1ü÷ï<¹þñãÜ>ü“Oôcø3üø®ÇÚî^Vð{Èk¯çQîét_ir­sUŒaEOGÍ›òäze˜ïëî´oÚ( Çàd­i9)È)B—Aà¬@˜"RB#í|K˜Ó³þ©÷ø»(7ºGP…©º©z³%Èè¼r,ä^½nYý¹[×P}¾F} ùSfqÝ& _$NæîJÄ m>ÕêÖ]çfÝU!@)91ÎE­Á Ô'ÎDNÉ®}cÞm:oqYAnÚúîËïM‚È™¤¢î^½Ù"œÓ…Òf`ÃJ‚Àˆ‚»,(‚àäh.Fd uB§ÐDéB¾îZL|äÄC’$$Ô h‹MÌ«xŽF­q5׿Ë@& ðÁâæT¡öª–!‹ˆ7¢¥ïÔs¬‡²9–’[½ÁEá¬BPÅ$ÔÓ«Làäâ„Ù«ÓÂÆÌÙÝ^;Ô]µ3‘'bXtç&Ä 9Ç+ñ9[½Õ%ß uÌ„F Pn>+P¡½-^|©îPtY>,º|ADÖšz3´/fD¿Œmõ¿éÏ=‰º‚Ÿý¡`öD¡Zjf…˜s81uc‘ëRMÀ˜3rJ5ši#Fæìêd”CÎ!ŠÕê˜ÆH’B4†€z6‘HHÝr$1³5´2‘A«˜ZÁ˜¢P«ÞZ»¾¼tk¦aÖ‚'´¹ !Ä$!Æd±F¢!ñ£ ø9—TWp3nndP"9Àг”`Ø2©ê€ÊebäŒ;ôÄœzî™»¶yyñù™1¿h{D¶ˆª¨ ½(êS 3¸»+Ô íÿn®ïñ©8 L™Øƒ‚˜™HYYe6ÔFmq3qO’$öF!ææŒ‰…,’C¦@@pSsTFí©µ†•c`^Ü Ü–lÀ\´ä™’^“ {e #HûB5÷ëWGñ6¥VœN•žRædfûý>¥,ÂÌœ†ÜÛø¦ˆ’¡H”¥2)ØXŒÍæz*î‡ 5%IcÍ@ŽZ+9 K`Y­V1ʘs£€æyš+DÀVT½YÕ!CÊMˆ¡ ¤g½ü(€™·ÛívuQË$„q‡Ã}`«m¦ˆÃúbm,ÇÉ#»ˆ8Ñz=λxšO”)ç¬MBnnrÎjíåîvÿlwwª³‘„§Å‚´¢Þ²ú®BÞˆ”ù9+ùgJ=ýÀ'(̼Ì`«Xž™r¤$x|ÉQéjxt=Ü à!ð*Uؼ}D1g–‘b.’_¦g÷sµzquQÔ›Z5+ŒÊzWr_&ì›ÍßÐÝ¥Z›ª®ÚLæŽ]j3f&ŠPÞÃÑŽ¥‚ÏÇz l*§ª54ÉHÑb8it6¬6ìk8L÷ÏNÇg/·!ú·¾}£ý«õ›ÿÍï~óùñq(k^¡øãŸ|9ÞÝ>wÜJúû§¯æý«'_2±8tzö#E‹˜6f8^†Ð·Ô¾R%P¤H›àñX‹A›f#z•ñêÏŽZ`€FôA€%ô3R5WAPAjÍj I’4RŒ QsõÐ “¾oèvw@<±Vóîï#&½WC‚€ê¬J^‰”ê½³íW^dýrFë)¤=~Vzf“êÞÌ©9”Šä6ãx™i«%sÅlVÙD'ð$TEL ©¸»5µ<0ç3U+Éãf®3¢SóF³’hã…ö/俽àÇ|»O4rA*´§u~Yrà·ÞºNÛõWGó}™¦¹¬¼Š³Œº]¯2KSÕêÀ«õ(ͦ»ùd:µ67WÅÞhÔGlÁ) ÆîÞ \‘˜+Ø „ʼnœa^ ‹®0u˜ÁÜ–*èbt& 3s €ÅàÁÐÌš¹Á[Aßå½!pöŸq|ígÞïŽ%ЊwŒ÷òd9–]ÂAo”hr~oKúg—IœµL$lËë,ÜËy|ôº„c~“-Nçœ5g_Ô vF€—-½9ò"€rÀ 42“1‘“x`4Ps&[RS™…Ø]˹@o¾½vQ,bÈ9ÙœŠy"7 ‘gò°&¬¼{üzZµÀ‚^ùx§Y>|cXÆ-Þs…;ˆ±¥†o ±ª&Ôsð@ç4$¦ºp^&E¾$ê~~'àprb5·^¹DÆ$ÌĬè©[ÍÝÍÔà =‰=UÖ Ngt°æRVõ„%†0À @…˜{˜­2LûÚçôEEôëø0÷rÛÐZã­Á›{óÖÔl‘Ã0 DT‹6ÔÕfCpñF>7 À’D¹•VÍl £p4³Öš™‰H”¤P2€=rp#«Úê\+X0ŽW——âÖæyŽ1äœkmÇÝ^¡”HÕµYÁéÙé 6Ã[ à„<Êj3Žã(‡a¼Ø^íwwužã˜¶1¹étœÎ1®"ňd¤m®/o?šö‡ûW»i*f<¬ÖCŠ/EÝæÞÔº™ÎaÕþ¥ú…ëÖþTêô7Y_/¬DBFñ<Z §­/2纯Ò0¬§G;dî‚P yå†v,§:§RZk­©›KÀ„ˆD§£¢’õn23mMU'M)b-³™1sÁNh'â .´:™Éü »Vç‹‹­_" ›G±¡l·Ór,c ›¨¥8g ^+aÄÅŠîÛGÿúþoÿ~ã·/^îìÙ UÃ!$Šaû «¬ø‚žþý_= ÓôÕáæz¿J7ßµŸ¢> v({)Ñáa£ãzé×Ö\•VâÕédíˆêG÷9kEØákñHÆÎÜAKÎTN ÚEó.TÉÀn€Zoä1 #+q#óæ!ʈÁ½-åQŸG(Ã`f.9 Èœ˜QdS'&–DÕAµ¢•Ùš‚µžÓDL¢ru+ëÊŽÅ[¨ìwwð9‰5JŒuë|5Ò¦™–æpqØÌ\Jô*ÔX Þ çC3 FÖ•ÇBABJ¼º^Ë´å½! £“O“³°HŒCVƒ§B¶Wƒ·Öl.<ãªPÖªV ¦nÒ©ÁEqH’2ŽU¶ÔìÄ’²:·b= ÀìaëEF&º­LX"(±D€Õ»/¤»à=âU›;YŸõp<" i™!Q[“l¬$w‚6’Á­¤ ƒÜ\ˆ„™œ,p¶eý~ùÙéï¯ÆíÊÙ¡6éÜ3¬ テŸìùÝ[ë'ûOž?Zçýîåñãc¸ÏËîÙ-Ý—`q –ŽŸvÇÓ‹y·?…ЦP¡|™â9”AC–ëËÍvµöS㗧óc1+ÖcIJ3†V)´bNIxÅom¼À`MÍ{Æ ƒ_#Èš$ΩsXÚÝN½˜eWÑ‘N>"cͼ… ŽÔ¿p‡2 -Ú¸Ž© 0“0³j}C©gØüC¿ñ_B×Zƒ»ÌßሠêÒè>}@ÜÁ?}^Ì02Ó¼N¨Ó€˜]ͨNîP•ÒÙëÍ)‚ûàÏ;vîü…1¸4 §RÏö‘9H‡š‘»õ"[¾¨ˆ~=¦C}Ÿ¿ä ôÁ"‹ %Î9±(œÍÜ”bŒ¥”ªÊAƉHUë©5`ÔuÒR‹‘…ÒJ° ¤¹ƒñÏêq­fUMF¦î@­í¸/§Zš¡Ì§!åÍfusyÕZ‹1Žy8u?ï÷§zªµ¸ò>¯xX¥õ&‡œ!VCÎI]8gšÊ¼?ìLÆœd¼X}é½÷>}öÉ«û’r ÔPæ¹ÍÛMk àªz{›m–˜^Þ>+§¶;Ø«;ß§ªÎ Uëß“<”Äç±/¿Ð­^"ø¦µôÜÊî\aˆ¢ÆØ(˜¢Lè@ÙÒB a0aÏãêí·ßÚ¬e÷ôî §j›O(Ç<”Så[àèL1̆#JmÕ¡Ì o^ª¶y‘#‚ ñ¤mð LÕÝ•cÚ àÕ(Ì®•Bæ©ê‰T6mu½Î×Wøò"åv>>?žî[AõPµ"%ËȚí7kߎô›ÿôúkßÚ—ù?Nܶ+Ûr:ØaµÝ €0Ox6ŽW¿ñ­/¿øšýùþöã÷óÕ—‡ë÷W7q⿜ŸnVxë8Œs2¾¾Ÿ.+%«æv<Õ†ÂÒš!`šá9Ö6o­mƒ…LH¸¯h$LD²x¥—ËÙ—&ja×γ)hÁÌQ•É€F0W1»¡;˜DH@".l쀥ՠ D’œb$LFRm^Œ8ªÞN¤U7v·Ž–íÝGR¯'P\\}H ¸ÕâÎNNQBfJ$c–‹ÄÖáf¯“Θ«âX±§\ÇÐ2Z$ µç]õ,ìšnf&Ž@@€z«öòåËLB¨¦…‰<“C$e¡g¾$å§p<îÍÝUQ›MOÆSõ:(ØœÍZmÊ®5‡C,MeŒ>x¹÷œ"Jow¾yýزÃÃBË»¢Ä”ØÅl¶ø¿Ý ™­¬¦`!609ñÂb 0¬¨­ƒ)™)3Á*L•Hmñìç(ìð@É läó·—Eý£žhÄ4xÐ]kX;"Àÿâ÷¯¬÷ ùª¿+?øñ·Ö>þéqÿ½cnñö•Ö¿2z…KJ>ŧ·/^†²Ë¸=áT±‰È\<’ËGkÞåiµž<¹Ù^¬ëiÞ??×ã±M3JE"ãLâÄÄ)$µÆ)È&ðZ$j3‰EQŒ'" Gb+9+{µ^UƒiÙv/ ¿¯ÇóÔŸ2%br ÂrCÁh)œ¬+ïÎx…Ÿás~}Òþ ø ˜ñC-Dç”Q 8bWv¹ÁÝ–ÌkZŒ¹BÄKrëb×õ³²ë-í¯‡«ç?ò™CÞ €‡i?d1Ä­Ó1ý!6›I’ç„• 2ú4žƒ›‡j^©³ºÜoqØúC(*{-ž>"†31A{—በäÄX9F¡-8èQwaRHX` Z &f"&ÖE™¬o w{öÖÃx‡?;àÑ.[<ŸË»ìI¢I ‰™» ôÌØÅñEEôk"–û¼$i.’ \µL€Z[¯×ªn­=Ð!flS9¹¢mskÅ…ÀIÌÉB NµYµb®ê†ÖZ9͵VW´ÖZQKîMkAÊ]°×îïïa 檵MeàÀJbl3–Øg‡c¼|´¾¾Ù@Ú©š³Z”àah§yzöòÅñt,~ºØn6”nÞ¾Þ·W÷uObœt2çû{ûôù³RÊ0¬ö»bj`™k«Å?}vÿòÇ#îwPCйúrÁàÛCÂò?àŒè͹ý=ãýƒÍ2Ï$PZÌ¿°f¼F™(³¬™ñöÕå ãÀY˜7›1¯è`w{{¾ý`5=¼šno¶;§p¿oÅ0òª¸šK×|8¹6¶`'?/닃áÞØÌÙPÙÈÍ.VÛ:Ï¥”Ó|”īՠCà¤{š-0±e5ñYç¹ Õ²Û W¥–<ÄéXw{o±‹ zyûÑ·Òš‹2Ë„–Ãúä'‚UE}+áZ³/]lרµ8i˜Â“«ß¶,á+Ó-µiÖÛ|æÓQ¶V=´âGÏ€'Ð <^:mÝŸhÙG¦H7ï 3bFŠ€»šÌÌÌÕØÜ‹3Œ˜ÂÊ%ÉÌ Ú•æÞÔ´57³3‡(”˜ªìÈ}ɈÍCÜTÍšq€=%Ÿ„œQ…¹+¹ÁûêJoVw´/éL¸ ¬5k¦nÕk((ÄÃH©ÍÒœ›z[’Ú”©A”Å£Y€¡tÑ Å,™ÑL ÕVT§6rHëH™Ý#\¨©ÍÓÝ•rJ$ ©€gYž/æ³ÒQ1*Ìl¬d¤ÎU«{cÅB0Q΂œB,0–Ð3l‰zç»Û"ÈÐÜì‰Sälœ˜`è—Î’•¢ zJ uI89؈ìê…9H ®ƒûF¦Hçô]!êKB7í)j½ùÛ‡¡YÄo{üÓö”g­§~&pƒE×™ÒYßÙ?!»ÙZaC¤;·­ ·ÑY€NÔC"{QÔ#’›3-:Z>øgÄ“œÇ„)ÄD"ÄâB} _lýMòѯCQ´`è;ìg\fˆˆ1ŠÈ\ÝHEÄ€rJUDDÄÝ«)åœVèUgŸ¼9B1hÅLIcÌÁ¹L¦fÎ vhmBLe®Çci­¤”bÂzÁ.„2Ÿö®Ö':7"rÕØÀ‘Ed¼⊮o6ߺ*íXnÓ©¨7ÁÝý±¹íö'Š·“Î'+ UFŠ1†” uvÀJ{ùòe2׫ÓdÄ’rž¦Bç‚iÂ\P œ£ôîƒÐö\8(oÐñÿµsgì'~•bàßœƒê´gJïÞ01K€µ,QCZsZÅa›V«`r nzºßîêòe¹ùFxô[W:Êå­}üááå ?¼læ /Ž;wm'­˜˜\AÕûBÓûÝùJ"rÒƒˆ°°™BoÔÈ:Ϫæ`Ìœ²Ê\y.¼“qåG¯Ó«öêû ƒÌGs0Czt±ŽŸ~úòÿèû¿õÏ÷"½mñ¶¹ï‡ëÍÕ‘îî¶Ç¶Ã…Ù6ãÓNíö8}ùÑú½õ—Ð`²z%ÇûÇõ_ä«cÚVŸ÷ú²ÔåÑw'ÌÆ%_Â_V¬„*y·³º™»›t“qëçÁÙ»dÁ` 1ñ&.]³!Ίh¦ŠÞ dpGü€ˆÃ¸2g²H±G šFS2ˆ‘¸ ½™µ‚÷]7z>»=sʈpæ«ú9%P™ÄÖM2DB˜t5t}™´+Ó\‹Àh²ÐQˆLÅ<©BÏÊ/8€ÙEõ,s÷Úf#ˆ»(")uÊëuÑYš1Éddh>·©AT¦*¡€ªiukì bvj…T€ÀTÚœx4B@0 XH s|#7K¤Æ’€ÒMY™³ÈÀ`u»³‰Ùò AC‡-£DÐÂKþÁDŠE ÉȉL!Î"¡§^ƒ¹{£Žžy3ŽD‚fK𝾠ýRß ü'Ôrèn5Ѝ°6@7î_ëÿó“ËWs¹xñ¿ÿåêÿ£+<Šx&8%ì¸ t¯m¾ò‹ãÜgäÝ ]n‚Þ¸n…õÛ±ŒûišaG—HÃfhíhŠˆB@ufX¯ü£R ŽHa¡l;«»¨ œ@Á8R ÎzÌWk :°ãé–dŽ¾Ñ¦%¤uéü+ÈÜI»hªŸ}²lÎÙÚñ‚UïiÁ?±þëy‰»µ¢>¸ÛEˆè¼Û^¡ˆ„‰‰„™á péâ)z#Ô¦W9ݲÒ_D˜ŒúŒ¢sÖGegIÐyoMo(ý:™­EðÂ}e^¦f|˜8?ä™òâõ{3u'¸Ô NöF”Ž/ƒ·>2?Ïß;¨Í¬‚›“;ŒÔ1;ª»º›/!½(öa‰{?bÍ| ðqwr&êÍG[¢Íz‘ëö3µŽƪùYT„dŠO°‡þ]õØâÞºé>ÔîˆìP#²0#d¦¡ƒÏþ´¦NdêLj2sð’`Ž3p¡?¼?f°I ˜„⢕2'ó.k<{À¾ðýê?Š{sF”†˜^­Vy`C!æ#$ s 9 ²´™ˆ|Ò£GJ)Óþt‡6USÀ¬µ*)CR­fn12CRJ®cdæÃé07@lˆX_'Ë)3|:§£“cŒ¡ùxÊ9Gṓ§%HÊâÒB¢4p+d¨U+“ çÕq>–æ „1z´FµÑ, Ã6§<2R)MDLdãqt„1mºŠc*ûÉŒk[¼û¦pE#mµŠÁ@FNýêýŒñ‹Ç/¤ß÷ÓÖÆ³¬¢¯{L$Ä8ºm32!RNÊ« +ñQ¼žê&昇Æeg¯ŽíÙ·?xçŸÿëÿŽ~#òåúö¥ýùŸ}òÝï<}ñî>}u:p,” ÄÌèñ…@k-1Ÿc&Ü ½OЍhƒ{f&US×èþêþE0pgmÐI¹P!iyKáBãuÝ> 779g:îêñ)¾öÎÛãîÑóïpO´›æ¢å´ª§ÕiÿÃwëÿr~÷›yö›Ë‹›ƒ¿p\2žT}š+ñ*ÍOéãÿ{÷áwp£ÛÝì/øÐÌÖ²º¨Ùviò»úÕÇǯ¬õ÷Âõïn.ÞF›ï§OïŽ÷öÖ_|ôÑ=ÿÕÇí ÅsÏæÀ`Ú¹ŠlÖœºÀÊÀ­[Ú]2×kœ]Ù•áe¢Ä™ÀfjÖ£L…Á‰ µŠ´ææRMªä`÷``•]ÜÁ »Ý ``8…zÑ׿ÏEË÷ЍoR¤LddÝcæn€•VÙÙØ(Œ ‡‹AÞºGk½æ°òfªµ€NhZÛ,XëS˜/†%”f%†Àb"Ì #ƒ°$Ñ:,dÉ…aN­˜ÄIÑ&u6Ý›žà3c4‰:¯ÁY7R'w©“"9ˆ$pkÅ ê&Âΰa‘½wÙ )èœ`knbèûŸ‚,!‘¬l†) Yp\N)F}ÃH ¢H*‰H½Õª_K€Th5j@Šav”~ÕH°ÚÜ­ç¼Äì |˜Äs#€` E0t~¯VÄùú–oþÍÿòÿ<úßx'§ÍßÈ]¾Óùß{üI.zª»ÝéÇGßÝ¿ôåHµ»‚ƒHŒ5ñ• auͲj·§§ûã Û·W©Ç'¬à n ÜœÜQA<¬‰†Ö"+¦Dî„èÑæ¹1„`Ed DŠÆ0¢nÃÁâ B |®T¸×4äÌ­ÝTyÞ_zgfwI™Q¯¨ÎS!oþ÷r0| fíåЈ»…–ÆÌÌg!ÙYô†…›æŽÞÀéÌ%³(ˆ@jo@·Aî=ݵãæý,Ó®f#¢žlÔÇ;~>Ûr¶WÑk)1”ô&gNÍᦠj¬æŠŽMqµÎJ ×Rć2½ƒàÔ °jK™Éƒµ†¹a6r[Hg|øB£VG7CqBO^Ó‡Üa_æK=ÎN±Ì¸ô³;Ÿ>;²ó„Lb8¿þ·è¿•ÿzÛsñ,ÙRr¿qcgç€"F‘,ÈðàÎÖ?.BÓÊDÖÝÝÌÝ`ep@A€×ŠÇžžÔ™ Â̲èÍýó¤À‚ÙCæ }fT÷ÅãWâÑš±3›-Ô€ÒWkÍ둈BëÕʬ iØ\lB`ªìe.Çé8Œi{qqó誵ֶm:ÍûÛ»W¯îæcu@UcŒWÛ+¡ðâÙKo¸ºØ^l.vw÷‡ÃÎÌ u}…Õ*¦!çVJ†”S.ÓdªÛxµYOÓc¬µîGfܼõ(CkM¹†MÞO»éÇ»¢Sm§ᄦåéÓORŽ”› ¹y|yu½&™ö§ûûÓî8)$üt:ÌóÁî> ÃH1r|ôÖãýnúäé§Â)ÇÕÕõÍýýËûû~C…ªtÝžŸ³BýïI v¾@__ªKˆ??,:_§·ŽeúùoÞ@ägŸ½õ¼þ+ÓÖg&8ó7—µ…IعïxÝtîê-¼÷Ór˜.·WÐ@Í%¦ãê2ÃôÙ³ã5Ú°¿üþà_~ó¿þgï~¿~øªÞïÄÓãöÖWWïoNSýäÃ};ž´MÖœ{¢ié³JÙ¢”è.NWÕÀ1…Üw¢U@䬦9ÄœòQç"O¼§ _½n¾¶ŸàK_¿º~;‹Ì)úuÝÌ7Ižmð,_¦W¯v)®ßyç7äxõê…®óo­åîÿ/¶O¾òÍß¼¿{þ8àE^Þíâü•Õæ-œüé³ÿ¿}ï;ÿÇÝ7Â?!º²}ß¾9AçýñêòñÿÙ_ìðò û;ﯿñ›ß¸øöúcÿÞa¾¿ÎþòÕôO®./îÂá;Ï?¹ka»¯…C(ôµ¦Õ`MMM Öˆ™a®ÍáÎÌDðæY†ÑØ­¸¥Ò8ñÜæ%@/ÀJ­^zŒQ‚ ¢SvÄäÙU«B͘UºB1rÜиNu>M81²tšéáœa^t/Nî=3Ù¡þZ½B §dP0‘ˆjeBŒÆv*wPaå£ó ž"¼µ‹ÆÑ­–§8Ä•dÄæÈ°“žNtµ2è©[0Ï쵿‹p†K- U/‰k mj˜màÞw)jÅÂL`S2êÚ—¦u¼žOÓ0¬N÷ €\\ØsG§‹³uT­›{€l`SÒ°Š–ôP:̓ 0Ru…Q,r& ‰$ƒBWB1³AR•â,uë"óÝt¼¿$À ža3P‰*М@9z«!p­S™Þ~™CþÐú^n\çrÀÙ± XK>”ý—dûÁÛ>üñBD<Ö?üJz²½¨O?Çó+úáÅú‡?žÿ+ñý*=—ð,ž^°¡õÊWlynÅlñ„1pØdE¹¼ ××ãÔŽÖN1a57›Çdzïb»ˆzWçŠbÈÐvš[m^™5ÔFªP@àHDì]¾-X Qêf±…Šm»uÎT記ÝÉYœQT *°Ç03šCÍ+-Í¥³q”ÔÝš—×ϼ‘!K®9ÌɺíUôƒSÜúpÆ•ºþ ã̉ˆ©§ ÈÙM;6Ý€cBÊ<™’›²ÁÌ@Ö¼1B? €©³/z<é¢Êž«äî„=´dtu4£ºÚY‹ÈwÕl:@  ²LÓìb”~e྿æã¡žN ˜Yï3³,ÄH˜Ãˆ(ç #µR§c)­AK™T¸¨ª;±13àîÌœs¤ HAKÝ—]‹ô ±ÖZg'kV«) Òˆ|CñÈõÍ LyµB,’R³Ymýìμ¾k­“b²ýaw|\Å«ëË8ÄÃþôòö~µ]_ÝÜ„îO{zõøòæÑ†¥<}ñénß³ ÂPÕZ[›QXq¤SÎ ?œ´Îešgʃ÷N‡¸Ï³œ§ÿ5ÍÄ×Å/¬¸êâ¥ì\ø—=”M@q0Q$Š)D–•—u+#A¹ÇÀìÁSX;tØ4KG^ù£÷·ãÛx^~4Éý,æYjÅéTîÇÛîẨ…Taµ¹S” 1U¯N`>™›÷k§”²L:d£ŸÄÏwåâ:Ça@à°2Úêð®ÞO_û'¾9Å«vÀAËi0J,<æÍãñþ¶5)q;Œí*–›LïnóÅ_¿ØÕ?ûáwþÓï¾]Ç«‹Í{¸;a}ýµÇàÇ÷ø“Ç?úÁËÿ°ÚÞÿÁÿô•9üö»ÿïŸþÉ>Ú|—oF ˜'ûúoÿöfÍÏ_ü»ßßÒ­÷‰vÈíVW-"]LCQçðÖuË8%ßÅ8ÖZ½ã”ÐíªjVÁ ôT.ö¥a¼xO—É™Á[&ÕÏ9¨V%wo Bp&f è‰#LàÑLâ!'1ê,\"í[O5%(‘œJp =ýÓ IDAT3œHDŠ®äèíò Æy¯,ð`“B_ôå°TŒ‚ gµÉ Å…+“17’àÄ.Ž`Ž  ÔääìU*Ã*`3ÆÝ3˜º«+9œp8•9„Sà58Ĭšk Õ¬z0!ŠÌ¦µ‚/޶èúYÍ!Æœ0h˜[«Z”…šŸº¨g ‰»â`3Ô wjÝCQgeQ·—ܺ&TB„¬gO;;BEl™Üµƒ÷ÉÍU¬@»ó©)HBhDÎÝÉHß¹CÏö÷³íüc‘D?»2òÏ%.0¸Â" ªWÀ×À_‡l²Ì³òÝ!%øýóíåæòŸ½7lÇã~òÍÝÇLÇÆŸ4}j¸íÕ€6©(;`°!Â#U)B‰YÉ«6›Õ¥°;*Ø8©¿¥ÚZk@^#o(­C\‘dY+êh).Ða—@N^ÜÕš„Œ TûÀÌ "D†ˆD‰ÌLFµVóªæAàÚ}6K‘ÀçTS"‚›ƒˆ¤5±ÐC¯ï(?×H$z˜=ÿ­úïþzíèuQo~¦¥øÆÖ:=¨Å–Srb?ÏúGaƒ²ËO”Kh‰k:ƒ ÞT1ôr‚– ‚ðÙdÔ³N–/ÏÝŒpÔcp%4¢™Íܡ֪Òܨ©y3RgZ±}n/Þ)¸n^ÌÁˆ¤‡ªc6*îâ GcT`vPþ©£30ÑöÆß9 ½ï Õ_Ï…þÚ…K@ò†…´o1"†\:Ó ^nÈ}åXªHè™\b¸[·;f¬3RÆ(1e0¼¹‰jc"ó7{l0õØ‹ÖÃç?±ÑlÐóÝ•“¶d_7ô³êÏ…ö¿óy̯tqÎÜˉ%tõŒLàž@g96±€ˆ=J 56c÷$2pS¾€¼7$ŽsÁƈ'³©¶½53ËiÕZSÐÄW￳z{ûôðâ6Ì/ó‹Ê‡?8üèûgOï[i«„r°S5A戅:úS¸{‡n®='¤Ðï’föÀÇS„ôèÉÿÏÞ›5Ë–WzËÝ#öyòLw¬ U¨Â@M¡»ÅVK­n™éMfýô¨?¨'™ô ™¬eM&3š5›d7ID¡æ[w:cfî!"Ü]±óÜ[`l€GäCYݺe'÷Ù¹3"Ü}­oå¶ÙæÛ! «÷ïÑ¿óà›ß¤ë[m§1ÌE'Ê ¬$®ÛþäÅ“ÝÅåôr;u|Ê«h>»wúžgãä¿üô“ð¿}úÿŽ?þïÿ»3ìnÚ|ûä?¼o‡{éÙ{²í´ºõÒÿåûçÏ®þô“Ïÿ¿) Ÿo?ýÉÇOï¿ÿ.?>Þ^=?ËSz'žöÍMy² SÆd°¾;{÷áê-œÐKÛ¬—Ÿ9CÚÞ Šyq”%z‚îfÂ~pö;¤â¸É•͵’û  ±sW³¨˜%DaHCŒ„,ÀCqqŽZqݵ—ëæV]?(‘-@• nÐ;Ø ñ¢S_ô/\Ÿ B‘B4« žˆÉµz¦ÙÅk•—fh`T‚• T,4)ªäÂ$&…:7›fs]2à EÃhÀQÀj‹€‡È‚;b{ï,СÑ"š£N®·Yo§£ÜkŽ–…¡j®Ñ™%9¹T69“€\…`,c„“Ξ]”£ÄL£“Wåÿ2«ÂÂ` 1 PqˆzWÍ€ÔÃÀ‚æb±6F¬ÌdP0„E¼3k3Ä”€Ýa6š;“›B““ ‹šÈt ˆ©yR‹¶êñ…^ëÈ9 ±¬:>îéÍ÷òÑï>zðäöé®E9F:Åé?iþÞ{·ãþË?|2›^ŒÓ07Ïçùåˆ+ƒ'skÛ&³SAlá¨ñBÅJ*c禦íë~½júºÊ š ÊÞÀÉŠ{.È1‚çF9WS›KAÓ€ÁÎâÄ6*n–ŠU,q-ÎbfDFÌlÙŠ*àÌ uùªä°  $"– }ГÕ]½¢«'þ«é´Øôõ—­c™Ù¸¸þåŠIÝÅ«©0¯£”zʯ'`ƒ1½ÆŽ#çŠ`¦…×P}.„÷¡¬§…YGôª0[~óÚ›ã;øAªQgA’×ÅÉuö1#3 yCKª ¨²QqÒeÂÄÎ0çÊK3? ”2œK3]RF—ÂÎ0Š»:jnP6çÅ_d9Ãà™)»g¢j«d '®wC})Tì§Û— ¶Í‰ÈP;-Ý( $k׋\-pE¸[MjR}oÌ\ªÎ`" & úÖ»@ 2ÕXH ÄÎN,bhêÅÄöZ±R  zgèK~®Õý‹«ºîô{w1Z ,Ó|%öé7¯8yv+¾Ì@ˆL&Z­V!Rˆìn%Y.3ACó8“Pß6ënÝu3åœÓ4_<‘RN)Õ˜c¦Puº6k9­OÖmhÇq$¢þ¨wy+¡Äl>ÞëL¹ |õåv¿O]ClîÙ§œ «Íº[·£ío‡:·X´$eŸ†ãÓ£³‡ç§÷Ï›¾ƒ ëº³³3­"öÍñ*fòþÅå•Hw™,dEA9¶±£FÓ&*©-c˜KádšLSÖ›í~·ŸS®™ âVuÉöÍ/ôëî€|퀈ˆ*¾éèP]FK/É©V§¦dJäåÓ³.â&ÇëÊì&…"ϰ›ýžZIã^¯gÿüzxyñì‹ë—Û!_>/Ï?^|â7/`3ÚÈ)Û‚ÝrDê°”´úVýÕ*[í°Y‹Ô«ˆûas¸•ƒINON¿ÛÝ{¯9ºÏY†Ð™ôÁM½4®q{cW»]Ÿ±ýhŸŸ344Òˆc'æðâùÅf}´â7y´éÙåô´Ý¾ÀõÅöÇÿîEÙó›·ëó¶;—I­™vô©¢cî??ÿq~ÖìâºûÖ÷¯>ýòæÿùòÝóÓÕ÷¿» <áÙ,@'ïß9}ô¸ïNžÉ'­ )ƒŠkåŃ̇U]Du X¬§ä/0“Îê“1+»9؉ÝÅ-7„HÔ@ZòÀ&dH¨øXõøÂˆž­Ì†™(«ÏSD ^€¢ªNZûnVJITÛ.kßu —L ©VdSh+S‘©x‹’ ¡ aS!s/pv@Xé8"8G 2ZðQÓœ c–ÜÉ%Câ`=Äq;Šp$cê;´!¶9PáâcFÒZ>A¡ŠB(I‰6 †‹[°„âjsA²ÕäùÙJ騯kU†DîÁ©!Ž$‘¬U678z"u'PEìV2­8‰:ÃØ LBà MQÁÅ1Õd\¸dƒ),Á|‘XUª­  U‚‘Z5+³W}ÙÏiñÿ=iâ¼vŽ¿3ï— €[.ÇðvHï=|ø#Ü>Y ÏÎ ¿%ÿõá½fÿã§{òSÎ4çÉnk_ƒjQŒ:KÑmUy9ÅBÊ<Í hTf¬ŽW›¸0²rήy*‡%–²JPchÈd¡´ª£‘Ú= âÀÒœ‹C\½¢Cjb A!€ "ÎìÕ@Âb±D8ÁÁ¦‹j¼êÏ̬ʸuB…r„É–‘ÈÒv·jæð¯H¾ùga‘Šr€É3¢»à z½õöªã_5nXʇÃÔJgrR¸ø%I—ÈPÈkç⟢`I€¥œÂù0¤SpW{E‚YìzFæ §"ÎÕÑgUŒp71«=žª£š„|wß‹&­^¤\ÍKõóP”: :ÀÁ딛ȳƒØÍQj°qÕ‚’"UѲWè½BÌ-µÐB¬Åayå òDBÇXz÷è0ÐLH@©›Zêg]Êé;âöR;3s@ Þ‘·€˜Á¬˜™z)^@T¸‡UºóMë_ÕTR•ÜU¼U•O•+·ìÝ•ÆN8xŠîÆDAÕˆ°ÑÓ%[êÑß¼þ޿̬¢ö™øP2 DnV¦9{JE§®mºÈs+ÚÆ¦íÀ¯¯¯Ó˜nçÛasF¤‰ƒsÒiÌSšS*G«¾“6J›9©m+…[HDw×Úõã® õ¹. €*bŒM#®6ç4çi»¿m:é6V¾¹¼:_7Ö¬òj;ìW›5¼›÷ùr†&Ë–¥ÐÅ“—"|öè44˜v»íp!¢²¬ò\©‘„ÛUk2NÛ6´î4O9;)¶!¹~±Ûnó8×¶‘8˜Ü™ƒùôŠÂÇëü Vá¯WýT¥Q•wñÞ¼ä!8ƒ`*ŽHÜwDf!ëqYŸÆ–ÕFÝæHÔ±¬âùÙFW³øfLñéËt¹;/¿üäÓrøŒ´ºeÛç¼µ4XBÕ6dž¹cwÏYgµš‰µ…[DÄÂL4N9 5MÃÄÄ侺««#ÁÙÙÙ¼yÿÝÆ7;/·Û‹1¬8g·Ô4e•_æ›/‡i*ó:§{]wÔi³KIÈ·»áÙÙéñÓ§OS.ßxãÑé›?ÿ‹«Ï?úY­O'¾~šŸ6aî…NÛn½9jÛåç-Ó½{÷ŸÓ—ŸuWùƒõÓÛ›#ž{ü⇗Ÿ|ôG<]ÿËûæƒï=èîã~ÓRÙž¯âéÓÛUipVÒn¸±‹°92®Bˆâœ€ª…( C!TQKn!'3v&y&*È…’²1¨á&wÀ$NRr•0Pœ•Ä,Mc”:Ì)äÀð⪖“ú}6ÏðB®&¾x© Áª‡–½Ïˆ5SÒÅ*wgs3…² › &ÅJ…nBÔ.æu‹Ìp!1PnÎ œ@Ù×b@ÓRãh˜V„<4¢ì Ò1E3†3Á<*F%‹D:(cöYw³M‰U…‰…LÔ(% ‹ÍÀ+óØÈ^8PWËiÈ;¥¤\`ó#dGIa¥(©±£1¬N“7b/çÇͦß4G5y,9Kæêx€u°²Þ¹G/h[‰«@‘ŒÜØ<ÀCõ­’{„Ü”AV¬,yŒ!‚(h1ÄÈ´”\Ùe!0 ™±»‘U#¨yE‰y½à0%XÜŸþjm?àYÉYà•Ñ÷ÓuÍ/ëƒ=dŠVGÍAÿÆ Ñïxº ’@ÁáJd Ç´’êt‚ðœˆÔ—’­>‡ìWú:¹ˆÃë±¹VDÌ\3@ë[`™QW\Aõý-]¦e P¨2>À‰9Ô\ ÔDÕ!ôꦪҫŽÀ88'6¯§~õÁ 3LT…iKb ãÕ³LÜjcÿÊ—waR׸7ª¼ÁJ¶t˜Ðwðž±Ö hV @„ îc8AÜÍÍIÝ•`öʧÄu3%F¬:góbV²ç‚¢HîTTªìî §ÊÇ„î¦óòÈa¹?u6¸Ü4®c^BYfåVGÝ eá°~«°¨çSýCyÕ\a‡°!váäd#LÌf¦®šÓH0‡bà”,ÏsžSÓ†@"Ds.sÉãMРGwʳ–²h…KÐi˜gJÃ0Ä–sŽs™ J-dÅ´­ÌÝЩºJ”u¤“³³H< »qÜϳ½¼|±>]sKýQDCy´êÎŽòœ.ooìrn¢¬Ú†œó\~þâòéYï:Á•ï¾ý¦¦’K0 óÄÓ0Y6¡pr|Ür`"U-'â$b?î§9‰àlfK ´ÿÕç?†ѯ³òšJáUuÄ|—QPmóKEdI…¤ qűéHñ)—¬õgê»—ØÖÔEÑéí~“ÆVV· W9è§Ó‹fŒëi¼+<³!ï"ÆH©p)àè¦j*M$»Í¯v¦¥ ÏD± Q„˜Õ¬äâjDd!ßp?sfAßðqwtÖo ‡9ÑÕÕuŠz{»óÄçq¥<a1sþD¤ïº¦ë Q/ªååèrÂ<êvJÃþ§ÿ„l*ò¦mãj¼Á‹-íºøð´½×Óª4§c#æ‚i‡éË/>´grüðóë-Ý|üÑêÛoýöÂØ}þéÿ÷=}çþ÷ÞÇ7‡yçÏž•«¹ý¸;âsðñæl=©Le2ÈÀJž pÐT/Îh&Š5ÈΜQLEÀ2l‚© g& (F%({?M RurV¥àâfžŒ$99“ ±T «Sax"fµŸC0â°DXˆâÄd\Á±‚ÉAˆ /dâ%#yš“avž³sÏ¡iúÕ;Vó‚p%8Œ‰r½'GÅ£"2§Ø ÓÂhßµ‰Ý¬˜ewµ¢¸Z›{Qx²De—§Û‰øœ …`s1 (J‰î¤CÎp¸’+jÒ\Ò6ë¶`’ao6&D R¾ÀK…SƒÝ@nÕDì¬ÌDÔ±DT¨: B¨;Š ­à["ó*0öÜ6âIØœØ <×uÕ¸@ n0YâO 08+4/b˜J½ýøvíHûßÅ…ï§Îäu¼UOº ˆ/d!i)<î7mº~È8uÄR³~ûeÖ€UÄéñQ°|õñ7Ÿ•ÕÓ€næ}¢Á‘k<Š¡º­ ‘òtÎk «¶¹×uÁÇ2”}Ii·öP ÛÉ Ìˆ=¸Gè:4Á­Èœz´ˆG/ÐbÅÙLª²Ž‘X˜œÅBð(W-bƒ¶E¹‘cdPΚÆTÛö,dfÕ#T·†R°4QϳKΫ­cñ^¼&az5¢±¯ÌˆþÊןÕà lñE»Ú«ÜTè_¦;RU¦be0 ‹™¥ftFI5BÎKÄ<¯Ôò3™X$Þí_‹Ðνҫ `‚0sd¯aî.^¥&^;´üÚ^E¯?ldÌ"pƒ‡[g I’w¶×ìR^¯9,j1YíêŠÑéÑÝÕQpÀyWÚW…­¯“ ùµom˜r%ã0˜ªá¡'?6L=Ï@4w7‰S$Áè@ã`øO¥1³SpCq7¥R|Θ¹À Vàj0#ƒiÉòÞQîWMà†=…e€ç^Ë!e*ލr}ß›™ªªê\á`YûÍëÀIwY}¬u=zôP-[™´ÌP7p !cÕ69OiÒÝíµZžs‚aÕöÛ4 (ÉJBXõÑÝÙy»/¥$M½7qn’§ G„ržt3Ñìãõ´gŽ}×ÅØjž³ªœ1é̉›64]ïÁo†ë©Ì¡iÈÂ<Ïãp›“w«–„BÎÚ„¶Ø®®.Ô[Ž¥_5mĽӳa7Í3™Ke;•2é*4A„‰ÝJÎeR›²ã´Û©*н ¿¶%íC^—,ÿî…þÆ*ó×ë«W†×#õ¼b@X"I#¡“؇ÐqèH6î1‡ ­[dO%Ñ0è8—¤½¿¸·34Þ»žtðÞwÍ‹.úµo<ð„<‰ÎÁS‹94ä´”dž²—bŠl`*dÞ,*é;Q_… šiß÷ ²úB mÛÆ.0ïÏ7íæøä͇ÎÂQy©/n·ÛtuöømÆÛ/•’­N6qWʶœØi´£ÕeÏÈmŸÛ~†«<—æˆ>üôÙé½^û|ùâ¥Mòw?øîûï> }óù‹ñÙuúÉpõáãþÛ'-nûçs¾¸ýì'óÿãþOžËõøPºM<º¥ÿëóÿãøþ¿<Þœï>¾}ñï¹ÿäTþÃ7ÎÞúÖÓ«—?ùÂÛ[Ãܮ𻴣íÖnA'd‘*/Õì¨ÊvXíWE¨7_‘¢x¶©Îl˜CD nUeCјc`g˜¨³Ô¡²Xk ¨ž­T@æ%[šYR±Ù<¹Í…Äe!:bBRŸZ˜lK“à ’Úÿ«j7ƒ2rÆ\0:&”Á˨X9µÄ¡iV$Ð2Í"$l”DD±YüôÍãàˆB¤&PGˆæ¢Z"Róbf¦KLÐ!jhAØ931SµÙÄį½Qõ)QÙª w«Cr¥”´Z‰,ti[*Å¥82³zÎ&"F`f0D5ûâ½áƒ‹¨FK×È6ª„«Jb¨tsh!¸Õ7¨µ¦Þ] ‘e¥½ª—.®xS Wɱ *Kæ‹}F_Ò¥:ÐÆJ7êÄt™,T%—«úŒÐ"¡sëGBaLêQ ðÑal‡ÆjÈê t·Qu97ws˜yVJJI1äìª0)×ÉžIp ¦…×$Ö¥`]䑯RœB ÁÙ •‰ƒp0‚Ù!F+7}*y*“•šâfr&ûjÎÿæDø÷ó%‡Vâr¬Žº³ûÇL6 ·óS‚¹Y!öD9ô1LSJv£f˜{”Øõkï;HÝsÎÌ*Ú¶íûuJ©ÌižÇ1'4nªêTy–`å<Øx=e.眉¸û”Æýv—¦1ÆÐöÄDf`ç6´-7CÚÍû½µ%ÚuÝùúÔ×Jæ%päã~:[Ÿ¨çq?\X>:oV«"W/÷ãíhÆMì9™haòMÓ ÛÀf>O6æ2¤|s3ß\C…KÊõò-ª}T|ùß½üÎú:úèï¤åçEXfDg†kUPMÃpG!‚šö̰š»@ä`…ÐóÝåúôøK¤'”öîƒz)†t‡yÕ ®w— ©ãå>qÀè­å°‰ÍQl…)ë|“Ó¤'éc¦\0"5M,I…^Í­" M`bß­ŽŽÎÏÏ7Ç­ðÔv¬ðítûéçžuÚE²áÙ…K»¼:=~øøÝõÛ}ykx;<Þÿ`ºý|{y{ÉkX›ÇÝ¥Í)®úçOo†ë`qûæ7Îû¶{ôfçí‹ÜƼ¼’«—ex¡ƒÝï¿ùÛïÛn¼|òl¿{9nö/>»éߺÿp:…­>ÐÏw_~ùƒ?|þÇ›—m· ß[}÷„ß›ŸÝÜâú‚Ƨas|rzïxÓÇeu ß"éÒp­gˆ;Š™iÝYÄì\3.B\›Ø<ÀœÕ9›&°`@ñ൵NþxmlŠœ¡Vµð¤bœ8ÎDŒÁ÷ÒäÆFò:‚’YQ. 5Óeϲ»ø 7¿ƒ $8g;1- mCq8!&ÃN±e_šÀ±"P¤˜SoÎjB\À`â`¤,q¹Tz˜ˆ5Á„£th1M^Ô£PôŌӵaÓæœsÊTTm?—2oÇáfï¬@2Ld榄D\ß­&¯³°ˆ4MˆÇf{3a. “svv‘™ÃSÅ=U°„3±Öß^l6—2yl%¢11é÷ÛàLu&i„£ì¶·ÄÎb#¥°L-F¦ÌZÉKqdEV+\…û#0¹ÜYÝd…—ÞüÝDánÆîÃí$º;ª}ý*úÓä%ÜÞfŒ:iêdh™7ŽÇZÞØ^<ÀøÏßZ?ü }÷¿þ¶ró>ûýË ˜?êùåÅóa?ºs\a`èÉÑ%cÊœÝëO¬Ý7D(±³˜h)P7PÃY¬lÇòˆà-œ@G`ƒ ¬…·Fo,E‚¨ƒ ›)’„u+k™¾˜ÊD)˜™%öÄpĹ…. •ÑÊ©!j™òË1jBq1ˆÏÀl¦¦ºˆ&tF].*,€¹ú„‹JýõË—¦Òá"üz;ÌllûÏ«‰¾ cS˜¡À$àú¡ö†H"¹ …³ ˆÉ+_¡ö=‹¹˜AÍ+®L^‰ÕŸÃhm@do:_)Ô܉–Ø¥*0®œÌľ`r7Ò¹ûÉ!ÔŠL FŠ5Ðڡ殯¤hò„¿Y:ˆ» Æs7_íîĵÂF—ú5¬ÿ “~Ï2×Ðm8 ÕƒD¯J£ú‰-T " @p0 |g£r2P¿"‡[vâ?xÏ IDATG€PÈ æ…pm(â¼5jhL«.®š^³Žä3HÙ‘•s©ÖÑ:®¬³ êvÒEl d‡ãEÂøTÄ2Xœ­z•Càð´<©áq¼‡k" pg*äÙ¬–Ï bãp‡~©ÞðÏœ]|š¸t"á~ðWÓk½ǯ[È÷«‰Ñ¯Yð‹^gCÕŒÍ ˆ:—m ØîŸ“ëýûgÎÝó—Ïö%7G‘ãÑéñíÕíå md÷ðþù¦ÙØdk_ÃnÒI:Ù¯ºuŒm”/^ÞRÇ}ßÇm»ÛO3¶mxpò`,Ãþé>dG ”b;4ˆ\zÚMÛÛ½ ¡ëä®%ût9F–Õ£UÈ ›g9{AŸ#(ÖÖéíÍîf?¬bo %´rrö œmíjž(—ôâö^·Iã®;ŠmIm™bh®_<ÑÌ7³·ñ¨íŽ{¸[ZÅíÞ†Ým‚–RLK}ð’&r7ÃrpÖùŸù-øÙϧÿB*µeÚÿjî¿2üÕOâ¯V¿šçÍ~ÁfÝ×^?dÄNÕ ˜óTíjêDhD„Y5»*"Øíµ£n;R¸V=ÎÖH·8nã̓ùjXwÍåËO?|c?Ùï_þèO£?? œÚú8ì?ùøz·ÑÛ0•œ‡UÂͻͣG=¿šûƒÇß~—»ÝËg?œíz1_›à$´'ãp…ÖšVÓ¾¬W…áÕÿÚf³Ù|úÙŃ7ÖSšÛõªYõeŸ&^õGÏÑw/çqÕðÑ´&úÅþÙFí ëA©ÝZº÷­ß¾=ÆÇt}´yx!|½ó'ÍãÕËf¢6žmWÝɵÓËOÚËòöÛßúr¿ß¿xqŸ~ç·~÷w¾÷ígOŸós¢Ý†¸éOO/NíÏî=ëßðÒŸÄ~´”×ýÉ?ýâ埯޲éj¾¸:~óä“Ý—÷ºãco÷íÍtôâ/¾økxòÑ“ï|ãý·¼ý%¥ÛÐt Ïoú‡˜pÍ-ÃPI²^<±È2Ê«6]8Ìô@&Ä’©+²™&¥N‹˜S¡†âQ›Ôê3õ¨&^­K¾œÓѼµ"ee»‘¹‘ÈΉ¼Õy“úk$3e˜k%G‘y€ ‘€bí2ÖTxdŽ`%¨ arÑPÆy¾Ør#'”Ýý–WMÒ©`‡5ñIŒˆæÅsÒìêO;÷äÅ„b'mD´â¶/6eÛd“ÝY¥µöX†›™cˆV²Ê­°Þ\!÷$©ødP£B!C‰}L>ÎMÓõ«ÐvîTö¥›ØæPöf;£1»š`YÒìáF®*u‡3Ì(±$‰sŒ1cŽIk k¦bÁ8RhŸq!¸¢$+I‘KSö§àÒ Àu›r㨩 ÂܵMqc†íºn?«Få¯Ô$UÙRt¿Þrˆ«Uwx{m0¼>“&0X+„·m@ zBãhRÉèZ¼ÑwSø'ÇÝ¿9iß9ë}'ÞûÝûWgüÙ0~|;mÞx|>=ÔáÞ‹mmUt÷ú0ü`Ü õËÄ{µ>cÊѺèkná½+%G/sRov§«íƒ+´3nCŒë6{´vÇë<ñ=.(W¶]–‹²ÛOùÞÙÙ£“s£ùj¾‡)¹Û¬ýörGìÖ»h‰Là”à ½‡î|5ºÎª$F¦¾Ï”ç¡zõÄ\;¾2 fÌ,BLìfs-_ bè#³:;«zvËä…à„À Ÿ˜˜Ù™¨Y¹ 3³Ã–çêzíc±mtW>-m~§eï#'vrb!!a̘)2ZöFh­ Þ0µÎ¦a$Oì&5;¤… `ULƒUPÅBB#zAßbÝ`-h% 7 Ægßïó–Áh&®T&jœYÁr•;›IéqÅ¡(Ú´‚¦‘&B„Y˜`ç&[˜4Í:¨!#¯H€Cýd+X€rhA´Â;ò!+sq$‡’››Çظ»ô‹î0‚3ó!X–v©Úù‘‹SEGU•Ú%ÈîêUçæ>º6brlÞ;C7„.`ftlFVÉiб'S'€:gc(ÊÔŒ¾È3Õ¬/æîÎÉ•ê|剑§z w£Iv^Ä»Kz.¡NÓ¬6% As8ÀˆÌª+ ‚ÎÉæŒ¢ìÎ5l¶–¨KàjÒÝv´èkÿ³OTÌôsNTwYwMÙR¾žÇ("¿àûþj®óWåÇøu_ç×þÿä\jˆ¡S…3qdu½Ýßê¼ÏyÔwm'Ôð¦¬iÑðñÙÉt3ãÎØRÆn·ë¤ïº~Hƒk523K±ïÚ¶ÛÁ\Q\³Yq @³õ}$eŸà#4š’k2¨kú©äBdf ]"³YJšûUׯ~¼XJƒ»MÇÑt?繬6µÑ ³7}{$Ò ãí´³§Fzõ°—¢C–ÑÏÏNÖqݰìæyÞOÜæF0'3¥IK)I=”Ìž™± Õ´Ç;v,-kLª½úçÏ­ˆèWRiüŒ×Ì—_ Q¼z}ÿn)QÈÙôÓ÷‡¹bÍ©W×V²Dœ?$¦Nm”ˆ{çxóm<¸Îxò!†gÃÇ/J°Í¦‘ÐöÍ8Œ[ÒkâkgöÐ{»F›¹ßÒ´ïóC:jV“¬7«xü ì‹ëºy Wrüþû¿µõgOvOÚ÷Þïœoþâzw14¹p˜CSŽzQ iBl5&Øjµ:>>>wM§2 Ãn½YŸßËn©dÍÉ…ûs5å ºZÇ#iSñÑ/ž]®ÎOîµ÷϶ÓC„UÚ O¶ÛÏ~øå“ÿâwÞxëýǼêÞyûìƒÓóîÉîãÿûÃo=~cÍÞ)g[}¾:]~öåÅ“›Æ⺼Ü?ý°<Ÿù“ù‹úO¿ó­ï¿W.¯ËNÇOâúËÝ® ã‹+lw>îWçñÁ»§'²*/ÆOì“Û´}öeŸ¾óÍ7ï?Ê»ëë«ZÂ1VM»Ý‡ìØï(«TwG[ÂÛÍKm4ú‚ ­òµ»¾–QA¥ú2#H)ä “¸ÔÌ Ù)8ÄG*{×dÅœ a 4:öB™(©…I5 ˜Y 94Èœ±èû"ý¹9EZ¨šl0rªô_bb…Gæy ëUug4 2ÛFIˆ-¨ÊÌ`w·6-Å3kQò”JÁì6k`ÏûŒäU% Ê>8·æl ¢-¡•`…EÍ'3W»U ‘Y©xHV€¢b4å"šXÉ åíL3|§ºŸ±SÌE³ÃœC·¬BDRíÃT›Ì@vò ŸÝ'rv‡%O afH .f¤0hR÷›à bJ˜·F“—Ál4 „˜c9äNº£€Ò%¦Jb‰`ŽÙ²ÿ¥¦ ½–[ÿk]‚ê1ÎÏÃÏ|;'s*d&u^ ZT€ÍeÝËiÇ<ä#ÆcÓ÷,¼9GýtÖ…ã^¡—?ùñg|Qö=ÞùÎ=m}zàéX6yJ7n/íèL|Êk/0dE"˜ (+D.@2#Å:#&ï2ŽN—ˆ—8“•Ç~v/Á‰dš²Ÿ!<¦æU›·ª/&ÌùÁ»›¦ã!§”(ÅÇqžo¬(¼ h¹Ø”,GFìñà ´Ç@_"9;%INgPƒ¼ÇäYU ™4P­"+€! )#©ñ6… q¡ƒÊlɶ!'g'ýšd˜Ãí_,gô5j‚ŸÒ]Öú‰î jÌ®vø['¸W_„–ЊµÍ:ÙB4àªIeŠU̘"%Œ '‚p ð–Ñ58njED-ªr×f6¦¨SÇ,ËÄLÍ (˜+ŸY+ÔCùA)ë «Žu¨‚ô€Wîu N‹žØÁP·º]‚LÝî$¨TÅu¨.\!'# à¥2syá…Åp¸ò%²“Òš†€U/þÓùù˜n P!d‡œíÇ)i(³ëL}ËM»ê¬o›FA׿mEZÊdsrX¿:æ{†“ÜŽÊÛix6ªmóiØ\_&ûðù=¹·JÓ6=Í7Ÿ¯»ÿñúoμµC°V›Í»íæÝøÝ‡ïÿÑÿüÑí7çvŸïß^¿•\>UºûØO©íøžw»ÝíõïÿÙ'?º^û»â¦Ç3;» 7cž³•îîäòè=±›íØí_v}7ØzüØn 5œŸÞ^}ô“ñå´ùå6í€H$?㵃O@Ñä&¯¾ U3ã05w#q'7v§h†B$ôZ˜x ÅØ‰½‰Žj»ŒÙR ¢ð”¨äŒLE‹ª“û ²; “×¼óe3»+Q¨[TØVZj=6+ÌÙÅŠ!߇·© krðjJ{L\¡ "äBAˆ ‘ç:²svÏŽÉ=!kÁDÈ/:¾²jm.Œ¢²ÄB¤ (}o6*Ü%pÛµÂìä–³øcˆÂ¥ ¸±*ygòÄÈ*0^ÒB+ç˜îÌâäõ„S ¤È@"B®“s£à8p°Œœ:iÜ]3l6šìAJÀ4ÐD<›ÀÄ‚Z  Óê­#wá*Û‡35(òplýÛëÒ¼2~ÖŽð]IvñòLˆŒÍ¸ ÂÕJÆ,$ëÙØ±ž´#í÷€ÇãøÐcîï=:;=¶Ý§—?yÖwøïã÷å‡×_ŽkŽhzz´ÊÒMŸ•²Ñî¨)š\iK¾ Ø3¨“;‰);&K1øQA»‡_NÝQÚžAvS¡NŒæhÆÄÄ5Ñæt’Ö, è˜IWÃýw÷–Ê6阛‘e¦kš/y—‹ÅÚ®ò»ˆÍ)Âî½s6[BöŽBC{L“(Ýko5èäã>•¡ »+ ËœK1W€}X$qïóÒÒ¶Ê*³e"¤†W,l23'ø!âåN7}G[ "¦W ä;êY5-Ò×ã­è«z _dk†Â¨62†“±–’®9K‚÷‚ŠeÒ-Œ½YHÌØ;Á:byxÍ«aOÝ‹³àîJ…âp#s(0ÁÃkçÛW}Ì*ä*(R!W".®²ß…—_G`õyuµ‚CJÄ+‚Åš÷z‘À^;XKÈÈJÂÚÖ,<‰… žª ‰Ÿ}>?`œ™ø"w¯CšW¤8Ô<¹ ap äìn„†Q"(  P_@äabúº…¢”âd¯ÏKêSÁ¯yîB„|‰Ÿò×þJÕÉpW,ÍW?\³ÝQøM“¯hmÂn³iFÑJÙXløÎw5‰RÝ*¦âg̽EèTy¹¿Î3þKˆú×Us¿Äûþê®ó—qÿÍ_ç×¾¯C‰84’¡(KETJÙ³eˆcØŽVÊjÕ­Ž7Ç'›¦—ëÝ‹æõ½ÕêÈo/ö×¶KSHÃz},|JÅÒˆ1ÅÝÜöasÜ‘…› šJ°iZfÑ\æãˆscŒ!ƸY[Ú4’-õûdÎLU›ç¬– %4ÁG3Õ¦ï;ŸÒàÛí^ ªÙD¶»— `>&ˆ[dp vSìf{­ÖHXõÇ«ÇmØÝîç4çlM»bŠ©ˆ%Úï¦Û+›F˜Õõú•øíðàá¯ÿÎçøõUõËK7Šë×ÂÃ$ZV ¥ H§ç!ö¶Þä·ßiþ«qï¿ýWo|ðÍfõÞÛ''›üô‹üQ£«†zñô%•igš]”¸˜ÐÄÝÌmöh>Y—³£·~û»m¿~çw†í~¸z9_|Ñ­î·Ýãßýö8òôÎ÷o>•ôGŸþŸÃ'a¸üÆ= ktíÙLëy{~4ïw¥æÓ·mËŽ>4›¦KãTƹ_¡mÚ4Íi&Mëo>FÖÕžV$SÊÃÖ®LÓŒx|–o/oøQ|úƒæa>}ƒßx«{ãͳ³Gk4sˆ¥Ð'¾¹Ù_¯›ãã7ÏŽîy¾žyœír7\l÷?þüb}vöðü¸l€–ÖN°Ù>¿Ü}øü‹»ÇßýŸuý~ó ”¸ñ§Û—/ÓúFÞÖéÛA/Ã7ÛöüþÌz1ÏŸ_¿Àíðf:ß$¿ÒÛ[½Á¸Åô²1×x‡¯{žï6õ…ªT¥ÓV}@Xèun ˜«-¸&€LëÖAÄ C"5L•¢`džƒD…IEHÕ» z% w·\1¹Žþõu—‰ Ђ¼þ­;».Î ¬€¡ÆnÌiŠpGT˜;©ÏN±p Î&l.\£«Â6*"ɨ8Pr$ ÙÓ8K«0¯¢€c$Ĉ&'·Ær[ÜÝ'éÊFµ˜©‡¦¢¢ æÁ…(£¸•Ùµ˜* I,"r%n˜6]äû «¦¤.b4#ÔÌÜ«CÜB`Œ r7³lÔ8!‰»9c&Ÿ‰a(ª@ ¢=BÂ&„`%ç;ýÙŒ%a„P„”QàÙ4×0ú[ɳ¶×GêþÚŸBÐÃß°×ãXµÔ àÔ 7º`¼ZÂ\GG¸_pRpÌÔ ž|º¸I»aìNðö?ÃÃþö³²þÑÿò×ѻ=ްòöäºwqï-‘[_ó¤ÀLHµgmCÍjê@Ý@ž—™ ÏÁ{Ì1ç(qÅ] ÉgKÔ4g*'ó¤¶Ã€³×GëÐRRË +.ÓmW2_SðÕ³ÙÌ÷bs†Ó÷©¿¿áØcKV¦ÔRÑŒÿŸ½7k’-9ÎÄ>÷ˆ8K®µß­÷ûFg†‹‘f|3¾èê7ÈdÔ©Q&‘¢qHŒH€ˆîF£»ïÒw©[K®g‰pw=Äɪºn=ÀÑiýPV·òdfœwÿ6¤ªè*×+7baVzתïÈE71óÆ«‚‹Qí}hÖIc¶vÖÃ1 dŽœúiŠ]ȵÝTáÆØ×ÎÝ?׈pçãè„´„A†œœ€är‡’Z2KÎ’Y4x#fž0•e80õ=’Y̼IŽý2eµ’©"*™j yPpì½*«dœÁáÊ:_𑡇±!ít;â»e¥Wˆ#MÔ‚Q¶©ñŒ”s¯U¡ød¦1,ª9ãŸd^ l·¡%02qÊQ »×Ì "c£ÌB&C4’ÝÄ6¿ïtsdÈ»6 ÖÛæ(Çó -”\Ña… H¤dÆbkÍYJÄU@ª(xT.‡Æ*$'ÿI¶¥®Ÿ ¸¦¦Cî cúD;tݙݸñó¬ãFSDŸè&v~;CG©€³Á~è©|£½Â&;‘A¼•SìºGÏ<8÷©]¥È§³Ý¼wÿFt IQJ馸U_ôYçó¾îç}þ/êñ˾ÎÏÆšÌ, ŒPPY–Ž4¢-J$4ˈd£zZXé‰úÔ«‹“Ѽ.FÕxbî,mÁ•§2 ï>‰Da‹ÖGéz98œG'ÌÁ—šTeéËq5nÛ-¬Çv‰Û²Äh<9š—õ…+ÊÐkUuY•Þoݺï{ŒÆÁ—…Š´tM_Te5íæ¦³1™$ݨª: ‚óL”"ÃûDÌB¨J.]5©‹Ù äSÚ||³¿J?E‰©ke³×›íпø9^5Ýg}ôß©Ã}†¼‰(k9€—`YD9œ‹šÓá” )'rï5÷Ûß™ÿο©Þzûò`Ô Ä“¯|éó÷÷À}]ù9Á}¸]^†¸ôº$4lÉ; !ð”y>9~™G#Ü=¾÷ß Ç“ƒ{G“Í’7Ïÿéû¡•2×gËû­½ôÆÛo>zŠ FÕT'uL¥sÐóMùŒ€¸9žÁƒ|Qyõ⌷ëuPtI vãrRsÑ\®ÎÏÎR/ûÓÅ"ŽiÖ·´^Û¢Áz4‘)ÿt½>ž©k–ëÍñm~õË_øÊ7ï”Ej—”¶ ÓÅÒyßž£Y,6?yR¯cU‰#¿Qþ¤{ò´^/=|½x£mÜÉÞñá^qO£”>6§“bq[ÀÒ,Ðd(¸ “òÍ?|kö²¸§‡ãýbrðγՇOg«Çfß]}xàÃÅîîTqLžeÂÅ2Aï0;6»ÃÚɨ !˜ðað3ȇŠÂH‘ µw03Œ)’‰YR#¢œ=ê$'„L Eï]ã¸gN%o šrƆ̽¡`ÌÓd.càTv|9ƒ¼™tÅ¦Ô  iÎØÓR7 ®sT8ô¢]Ò:Iheå5$*=ÌÃ< ©‚ â,1'å$¡È”`cu,ˆjè˜UU¤Ì+˜„‚냀Me9¢®G›L!`ë“Æ^¼ÌHT›= Pcl ÖYô$J)k 9Û #%cÍå‰Ë£d¨¡‡ºA2îK/šRŒÔD”Ä%¹ÊÃSÛ·f„ž­"K/)JŒ¢Q“9*`äÍ«D5š#Od–çÙÙ<ÃÞ³1‚7—£ªð¯˜õ~%8ãËBN=£]eæêf´êr&MÒP'žx [ÀÎÒ&UÀ Ž_-ÓóîéLö›£h ½Ø~Œñoà+Lö­ÑËóª˜|íw&Í»Û~©ñ=Tuö윞5,æ‚$¯®B˯¨$ õ“§`nj2M'*–¶´5z@°ŒíejýieE\õÛ «ïPµ®G}ò—it±®¶2®ÝéÙ¢óÒµ)¶ê—gpä—¬Û¨MÇ$ã2ÍæÝ…½1£Y%ÛJÁp…˜‹ÑºT:âªêUû„–EÙ{ï”STIÜݲ,ª`ݦ$‚ç–c>5ç " ú—"ã¶–3J¯äãÌA¹yÈ’yØàñlŸÚ½ ¤½î©høfÕLŒ{[ævšÄT1ñ$ Ä…Ç\1ò°€:YDÒ­ÁÈ ²’©v\9TLÁ((œ‰RTcË6™ýE|]”"vt/åt"¶ÁÛ„XAÊ,»ÈD¬ƒ¸@’¥„¨èõF“8|ºƒ˜e—f¾3ÓÎì­áS§dÃÀhÐÒÊlø]pRTͺ£ˆ+4 ÑCyF°CpŒ‰‘°þÜÏ Kæíb‡5"5KLä*Ïce‹šÔDØDiÈrÖ™Ýhxè³æt;ÄçªMâO ‡v£w°ë¿“uE–ÅEyÉrã…€»¬ÖlbWîæ;KöŒ]e6gôÿ=f‚Ÿ1äýçÛDŸ—ÕöyŸÿ‹b1}Þ¿ó‹ºÎÏú½À$irp%Æãº®k†@zgZ_€Ì¬ðÕK«I“ˆKÒ(_ùÑt=¼ QbŸbŸ¢B(ÙçùÔ§(š¢ôQbRFŠª±aæ” <Á݈¨ƒ-.–ëUÓ·=” WTE=®ª|Û¦mE¥…»^¢Š¢hb?Þ¯K_'iG£r:.SÚv횉ªºäP) ä òÉc2™ÌÆÕÁ­CXl»®›u'ºí0S6@ê4Á»aÆú³ ï³?ç_îúùÿv;”íýw›lÞ4åZH0dž*‘9Ç!˜ŠÜ½Ãßù7wïß¼ýV3/ÏFØÔ+-êq(ŠTÕÔÆ$QÚ¢<åñ£÷!–µ›”ó»£éË®<٦аgöŸ<ö 6ëKjŠþôàV›Òºµíß~÷ÿ8§/küfÈÄðêdSßíÎû‹µŒÝ|6šQU[X<µ&Å®75íÓáÁaÌÇ“’ýf½\.——1I꣊¯¼«ÊM×ަU¨¬G¿ê,ª/Ì3‘¥v³Ý›à7ó/}m>9IaL“ºÞ?¸ýðÑ£íör6›Žœ¥ÕÅ“OòŸ?ˆëj<©-!“ú£‹EhõýH[r6ÍFlSj˜Nüñ´íÜýO/Ïåý_”7¦I>XÀøx téþEz¾ñÝôMšÕO¿ûð¡¸rÿn{Tk=r¾Ün•|åßq“àq¢Ïty©‘‡Ð ¹ŽùS(QÖ²¨ &(ŒIEûNˆlð0²<-53õÉQräIœE†ªpRS»qª›AUùF™tÕ™‰A‰ÜnÈ€3‹9ìwx"ò˜ÚÔ£Ïcmñ‰E£b#(,®[-ÔWžKÖà•M3ãK"Q‰I{AÏ$JI”™ zâ J['«hÜ’7òÞ›ƒxe_Àsd¤ž4Z4MH¤’úÎZQá(¥d!f¹AD›½ãÒÆ Sƒ»’Ç SE³œ§éR.*ÄŒ:˜TÄA|2*À%s¨'ö̉¢QbŽL‰¬3DšÅÈ9öfŽ•Mœ¥­4 IDATAçHÈ™ ±äšÈÔ8Ç!88ÇŽØÃ1ÜϼÀj³_êþƒëuÌ/˜h!‹.rš8#™\°]RxF`1ÅZ±¶zó¯Ò½oßúÎ×Þ¿÷ ÿàã·ßþâ+Z_þùqŒ×~¿<ø—œ_ôíKãñ+·^^½ó´?_-îÇxÿLçç¡·ùÜYHK4‹¸Ã2k"`Öu@Œ;EËæÌm”&J$E0ü¬ó9ö´…üt{€ÓlÛкgvã—æ>8ߌ¨oœ›;“pjþLeÃÖ4Ñ,Œ±wP¾TÎ^ž®GºÙn»óíTê’Jhб7\p…¯ÅZí|nbÖ™éôh&¦b ö`K]Šè""Y±ÇÊjq'ù‡9صÃYÉW¢ôÑPÀÓ‹ñ—WI€;îÜ'V‹bÊ zyË‘J§ a„2 ‡¨€¡ƒ(˜ŒHfÞ\‚÷Ô:[‹^ å±ìʬÉÉSÐN4IŒšºc£‰Áˆ,£¦dÈó—!.p6¸a2Á1¼¢WŠF ¤gÌÊdP1v9á ©¦œ. ÕóÑÎWz`µå­ïj…“ (î>d¢áú,ro3 ¶ˆ²Á·’ÒÀÀY¦´í¦ ÈíP†âóð5_n0õÎnžš™ud™¸Ø“žÊBK¦Ä±¨èz!ÏÉØaØÅ0°>/zqIØÏ¨®Ú!Õ¯÷Mx#\j»ÝHH;ÖaÞŒvY¹».ÞëÎcA`!4$C½¨ Ê?DûôÚïs)þo¼ÏÃeÂÍ7põó3?‹]öÙ¯ûyŸ¯¿ Žÿ*×ù šÉ%Þ£žÖãÙ8gbEQSvf츠BZY§uçÚThbÝJk)rAû”¤—®kšm×¶L¾*Šà³Èjµjcû>¯hK’4‰ôê½/¼ŸŽ’ºR8*ÎO/›¦kšW¸,›f8ð`—XUU5ªF“ñ+o¼>6íz±|ÎèÛn%ÒË|6)Š`†¦íûF lÎw1UUA…wEèÛN …÷½šÈC ͦݮÍQ©â$åÛDü³]úgv8ö‹ùÞÿ{– ]½cÒ+T-ï[žÉ11XKÊ÷ïÚo}óöïÿÎË_~K'å3ÆYRlcô±†ß|ôáý¦µç‹…(m¶ñ¬µnv§—У'wÊWߘÝûÂèð¥'Ï7¤BÚ?ùé&v6;t¯Ÿ”IŸÞúÒ¨¾õöžu·?¼¸µYœg‡gMYLŠã/ûãÑVG¡Š®}¶ù‰¬oLFXwÉ‚óN)¾|pû’/'“QÛw]Ÿž^,ºˆr„ñl¬E6L\5)jëRÑõû*{mLÍæå£i×5¡–·Þ8¾ýæìy{¿[·Q'§ Ýœ·‡ûõ›Ç·‚­çÏž=þ§‡ñõ/M7'ÅbZ\Äþã·n^{åNÝÅlú`ùLŸ>è6祸»¯Ýž¼‰ºzÑWÏÊÃ;Br†g?ˆÎÏ~´ç¥<>©›ælóúaæ¾xùäy\üØ?鹬ÝìÃíòkFŽÚ~Âß½òî„È[¾Ü@ŠvUÍpêáî„ LŽadÉ ¬ˆ`§p ö Œ5A˜²<†ÂY eˆvf´KtÏ)D ÊW¦a¶‹Ù iÔL®naËù'פó]pÄŒ "ãHÙT¢QàC¿6 $k¨ðp¬ƒ÷EEÊ$‰’·>¡Oe‹‘¡4P@”œr *ˆœ3Êï¹½tlŸ+ ô´qhjT‘)K|ÂÙ0‚²Èú¡d¢Wƒ]ïZLìÀšEËQ;acc56xPWl½êV„ÕS@RiE#œÀ)#Â’ƒ¦ê„Î;󎙈4&ë‰`Ö©öæÉù…sÁ9s9ÿÅ/$Iþê76ÍÞÉF7U' ¶L„¡ë‰²™¨™$ôÁ[¬­KøWÐ}Gèîü¶›¿Ñð¥û¢”ß Íé¶ØÔ|Þì奎Ývé*ìËÊ]ü`󸬔Eܬ´ ¡Ø Z%Ju„{Ú§Œ-C=RéÖ=?kâpD¯ÀO6-ÍëI©¤PrÓ5>ë­Kl¨;èºö®dÌ*MÄWlE¡5i<×ò™TgâN£5˜ÑÖhO\÷Ú4Ü™ïOF³g—§VÝ…Îêrä;èd¬É¢lcinÅu&Ñâ¦ïÚÞÌ\ÅÕÌ'Ó¨*IDT”{A rPÇΑ9±”ùç`3ʑôÓk\…îv Óë±¾™Ù5 È1ÅfWc5ä1×”ÈqŽòÒÆÉ™@„ÆT@‘œÏlº\µ;s Òb›Þ\ u [%ÖÛNw’ ôd)o‰"’¬‹èÒP ¹Ô4P¬HA’›¢Èð)9§ˆT9{v+’$¶ º 3³ &Ï4¸ÓÁåŽÈHÍìZ.Cd»Ì ‡f“C´Aå-«Œ %´$&J6>´Û!ít`á¡kàLæA½H=k}¾/eì7ù]d„Ñ“U.2ÇÊŽ½Á{ Ñ<“c0KnÆŒ ŽöB|u¾ PÍ7aÇ T£k[^ìâˆÌ²ÃI_ÎHÚ¥©àESL¢ƒ7·[7å;,r°y·ë«pDŸ #ú,/µÏòšû,–‘sŸ/}åóê7>ë:ÙÑ/ù:É3À—4×u]‚,õQUwÖ¥¨æÈÈ’ˆ)!rï÷;br\…¥¶i»˜’ľézxŠEèŒHc©ÑRÕGÀpŒP”Î(uDê _ÖåHU»Ø÷—鑺”‰)†žˆ€¤¬‚+'äÔž½ŸíŽö¦{sÇ…hjÓª*؇²(Âlºëø`2™êr±~vz¾ÚDú¶Mgž×ëõbQ2ëÁÞìèàVñâù#p±mÚÕª•AXa)w,Ÿ‚}–·!ÿ‚0¢ÿ`Jz“íàALä‰Ã.·¡$W¹Ä[L9Í\RW”qŠ©gßš#9iÛú쾚SU¶M±Œ=FÇn·6S”#›¾4ºõÅý7¿6½÷JÈ$äå³þåƒyo¯—ßùÖ½ÆüNÿñîkGý¶W÷°g?ü­{‡QõßùÖ§«ï¿cOŸMËPésš °Ÿ—MœT夞´±õ½<|ï§ë®s%£ôå´v$‘lI‰Í\‚‹ #qÉHÓ˜u\UÒôëÛ“òàÍã {öäôÇéÉþ·Ï<½UßþÖWõ ?ß>yüüááÑì•oÏ?ú›Úó°-›bòär³‘¦!yéë_L§öà§/OŸîñòx¯šÌæåA½°æÉÓ‡ã} ·._ûv}ôÕãTÔ?Mç-~ðàÇÿáûvz÷ð÷Þè`‡{õ«Ç‡Åósiµ§è¸uEÙ¤ö铳Ų£ræjD¾±ÎoÜ ClÅ®AZ3$ÃD¸fµÛ€éÉN°€c U#£œ£jÄN…IY%°9F`.ˆH%£Œ68,AdA K€ËþÅw•Ë>$!³Lä ÄaÊî ¹3JDS§`SsÉp⼚X“£¾@æ;/„´‘±z$³ä( ³AºHO$#ÑR²‚,É»¤ƒÒÂ,€”,åúˆŒc'–wÏÁ>;Óì(‘+Ù.y$ÿüNBÃgÄ3æò„×@ÆÎØ""@¼t’š„>õæÔ›Q-B°'6ïœ CÒ‰8XPJjC frŒáÝ“ Hú/Ìürw=\A30M¦.W“WîZÃfo °eSaNù4³ æ/ãàë¸ó'ã[¿s¼NfÛííÍÁ¯¥'O¾øæüᣦ[ÅñzZ­ýó'Ïçëå?-•#+÷Cé1cöB.vî¨ ]ìi5j.>¸X?i’o°Ñ܇$¡¥„> S´Þ6«-ìBk‰@@¡8™á‹IëM‹öqœÌê¸B\Gœ[}a~-}«]‡ÑI¨ËØv Z÷áéïJP:ªœ1Òwm#p.D£éhÛHêàå¨$Ÿ ÂIEÅz,8³š“J%1ÅÁ?ƒs×´#5‡kÇ9³kzWéÒ'*C"Ñ›¡/|Å/hÈ@dÄìwyeIÞÇÐne’—æ]À9òÎ[Ç„@¨«³Šµb dNLÌ¢Hˆ h4#5Ä„¨ùþ$TRH9ˆ$_núón4Ãyçdb#ŸØí”V9›s:˜»2Ù3&Xn‡< ÌLr.C•@™”§¸" 󰨙˜LÁ xBIð°´šûœ<7étãæäõ9]‹µ>ídßýœ\JStƒ ƒ‘ °Äpl*l.ç Ï͸‰Û)d—ÈóBtÕî—Wñ7Q‚»j~0p ³U¶»î”ìªfNŒVóÁaWF”|5½Ô'•«ÉîUÎ]iß캦¡·Ð§vDŸ¥‹ù¹\¤_@‹>M÷y=Ùþµ*Ñ_¶>ä_IJ®hºŽÉyPUØ;ÜïM»Ô]..Øt>OÆ££;{Íbuöüy߯>m·mÏ5S£`k™7“Éd\4Ùfµ¨Âh2£Bù²¬ W˜XkieëùÁ^àú4)¦e¨ºMÓnÚíª‹’TQEEn>Õ.öͶã¢rÎqYŠH[Yw4Í'ÓÅr¹87–.5½¢•p¹YE(‰Ä³ç«’öæã£ƒé|o´XžµÝ’ˆÚ&u}Û5mÛYßk×§¸¬ý³§§“i½?Ÿª¢,êW—QìùÙŤ>¬ÃÁ“GçËå6ˆbÃøêvdù\XпÖzø…N^Sýü—}Ñ¢0ƒw¸º²IØÌ'sÎ<ཅP@ö¼ð*U­Ÿ¡Âúl­ý¬ÚóÝ6¾ü¿þÙGõW..ç˦üèãóñþÞ†G‹ÍhïÛ¿{øÍ×Þÿà‡\=¸ß^öëö—–5ÿøýþÉþöô@¿÷§ÿãôí“ík£Ÿ 2øÂçÈ(›]%Vc€=JÓ"õN}a¡; Á¶& CnEQ)Ø™«! p¦(¬T’la¦â=sEìÔzål0kDšH¡E3²HÙîöº#Í\D4Çh€-˜(ƒ]¦6¨|‰O0gfÄŽ¥º'€*Pô1jŸÈ•Ž›HJi#k(³z³8(“š)‰s Ëȉœ%*¼÷®(`I$ªõF{³1îÅl8ÑÅ71Ã_ñæw#'DvÖð¹\ÕøÌߣjpÞNÙ d³îö´ÀW_þƒ—¿Rß9Ûåéãï°WñÑ­—N?|ºy¸øðó-þéºÿ›¿Lj³ó~<žC@³öÖ—ïí¿}°H—Ë˳ýæâãn·Ó˜·÷Fó­~ôHfwâôÕ—>¼\êó8Y¹ùY¼¼Ôí:¶[é»Nz@ËQ¨}r”º™Ò”mݨ˜òh[l¿³àÛ£9y:“¢…?n.ô½"šघ¼::,Ví“ý„Ïl¯Äl_ƶëc×IÛ@›1Á’8À)ºÔ L¨Lã·^­Fãv}ãoÿÇ?¿ÿ§úîr9_¬Ë~rxr¶^Þ~ûÎW÷‹ôïïýÞ×ÿþýuëíG>~²¸ü?ÿó_~ñøã׿ó¥u\>üéâÃÿâÙ÷OŸ½zëÕÙ­Ù~ÇûÒÛåÇO֯dz©s]<Û«kíÎÃþSwxß­ßß;9iêGÏÎ[ٶͶiz‰)Î.“¶UR2²£˜$ާ§uÙÎdzq©ßZËþîë·&¯r¸¥·ÃÛ–ëçÏlÛÍO½ÛŒF:öº‰ÉPöú .žÚÔqª)ï•õ­Û ¢›®ýh{<›r#OÏ.·±qu-­¤8,ã¿‘>>OÏ„·‡£½¢´£0úæÛw1ãéy·²Ÿ¼¿h5þ¼òþó÷~t¾½Äxì&ãÑÌ…q€Š’n©(‹k‰­ìŽ%‚·æ­4dÑ‹c¦dFJž©\>sá éJ°›uù»é£3c!GUY¶)t»DÛ©˜ Y¨4Ø-„Á:×@lïŸÞ ~hÉ®ÉßÙƒ  õJ€YÁpLSaV1Òy±ˆÐ8tö $#%s°^EÕRXÑPÇ›0˜ŒÙ‡` Z˜0jI…4š%R5qed×yë02„rðíÔ˜‚À™$0Š®#w²tCiGÎD6³äHu—ÞîŒ-''@ÀYàŽÓ.™7ÿç‘30›3xA…öä÷FÙjË%q\¸ä… v 8â!õ^>ÙýŠú#ºvàÖc qÎÕ:'­¥jhÚŽùÄ+¥ºÆÑ+øÃ?üÖ7¾ýê>oû?~öÎŽ˜}åµ°>:ÿéƒþ—zé ªc<ý‡Ç­•ˆñÙK/óè¸ØÿÊ·¥g§Íh&õø~m­òÅh:ŠÎ]âõVh4‰ÓöP«ÅÇ>×Ñ#;yNrÖgrö¸¤>ư5.1ŠQÝ™,–ë'«öR`#SìOéìÂÈ£,|å©âØo b—´O(8sŽ+qRÄ^Õ<ˆœsŽŽ"‰”ÅAƒ}N¶ªT0A>ÿÉ’½U˜™HˆÈíÜ'-Gtê.øÔÄW6Wì<’I„0®ÅGÙÕÀ¬MÖª™h©Ošv(ÖPÑÃŒU€˜ò"2H,(O#ÌÄÙÀ€”á1ÜwÞ„¯,³?³ ]£@–•BŒÜåe•”¹ %jÊ` ×#š©"L•þy‚†»ÂsØŠÈ4ë8½©‡• DQCÊæÞÖB–§c+‰†ÝXM jš˜dð³Ú\c8&r ç›3c&öFÎÁ¹lù¨"JìáñbV7VÊ5Aî@ôâ:q7  ëgH&PGÌ»Ëô±Ÿ)ø®<ÞòÃÛ (’>ݶYÓÄŸÞã|öB¿n‰~EµéNÈÈ”Í<. ”‡ ڶͶۈD_x¶í6¶Û‹Ë³åº)<…²(ªÀ쵇GE°¤1uBÚ÷’œ{˃G ޵ؤu]O§Ó—]ÑYgí¶kšf»iº!&–ØS‘ž¤QÒ¤pULÉ¡ðž˜BÁ®Ä­{ÇÆiµ ¡—~ÓY[siµ>/oLÆ:ªÊqUÎEQmšær±Þ¬:DræÙPy4 Òkoi%+G»$œ ·Ý4q“¬÷›U£›Àȵ¿Ö¯Wìçm‡n~bÌ`&Gƒ)9B{p˜µf_ûrªšœ‹tw4ùûÿ}ýôýï>øÑã?úãßÕo¾÷ãçßûÞ?=¸ïÞyÇ-ÖnÕ™›¸P‡~qþèéû¿ûï~÷äåíá½ö$ÚÅ“öµÉìÕ½WÝ+'OÊ‹Ûóùý§ùŸî>]ŽWu‡ñí´/¬V ­Nß8~u^¤þî¿ýËÿ´zúÁø8~ë7Ç¿ñrë«wÆöNÿâôƒûçÏ[j-‰ˆˆ$oæ\Žx ©‘ÔZ$óF5‚÷ÔßÙß¿3«ÖæúÙjuÒ¾þ_¾÷õ—|Ýާõ¶®÷gmß«¹:ÌÅ5‰û=Òºhæªâ{Uý“ƒ4Ù±~ÒŸOzé$è[ã½g%]4ë-ÍJ)¬+&õääð¨GѦ§ý=LýY}ùîåÇ?HÏž-_ùö͉ò¸èÆôÞÃæ~üãö§8{ŒbV—Ó;GêD-9pHH=Èö‰†`!çDlF ACf”9¯DÜ{ ¸Ü#%#c&ÎfoWúŸÝI}¥¾’Wz`%Ù©c鯱ò Õ|‘¸;?i@ÂàÐm ÒlUg&` ¢1+‘ˆ“q"ƒgc«:p õ ‹` [GPˆ‰e]Áà”› êòeÜx8Õ*uuŽ˜DalJ¤€9%Jvýù]§—Ñ  ìüdm°sÜqþ²1)çŽLD 26#Óh tYŠjIÁ¬J$ ½Šw’ÁcÝLÄœk6ƒ%S¨™‚cÊ¡ödWCÒ+.·¦µ]Œæ'~Daúä’Ñ4GC*¥Ii( #èôì94´íÎ\ÀË{wéÑü?nÂOÏ‹ûI¦xúNZ<>pV<Æè““=¬ÏÁ/cúŠ[AÞÒ{¯ œö›È±A»„Ê‘;?Áó™3ðé2÷#_7º9•K_OË/ÐK«qùxŒ‡Ú-?LÏ l6Q¢[Ig½Ÿ…ÑÌÕG½E”&[`ë½g¯¦I]ÊÖÅ=ꨵè¦íÎÑ/Õܨžaº·ÞÌÕfMrquqˆf‚Ee@J‹Xum› \ 7 Çó"%¤mN.Ñ„­¬ ñ¼¬LKïᬗ¶éRo¡‚!°—ØeûàÔ«5Ôw¦jlYÓfÙ"@wr½¦#Á!§Ö Ö]¶t0Ìâ#‚ËÒB6€†QNî„Á4Ç‘we ä΋Ò N2ðk Î6ˆXÇ´]&‚&a)Ô€ŒÀF²'¼ víqPüƒˆÔr¬ØNEL¦¹M) …GI(s¢4’™" †Hð%[Ø¥ëÁ<˜™+HU£P'a†·r„ià l­+œöB)"ALøFSDÃ;'‹œ›<øséîc!ËV–Ȉ™Lzc‘™0”Ù˜ŒÈT…rà.+e´N‘P$3!Ë}Q~uçá¼¹À>på}aêÈ™ß)µ•8“Õ`iHtص*6È$¯>µ›¸Ù yVy*FWÚï›&‡Ù¯|÷Kƒ}ÚHf0¨¸ñ?üÏ AЧÑ8ýøo«<}a!e±oÆŽ ûØ÷­±ù¹àÎÚwëóv½E]ÛtdÎ9xW.(YÒ˜RRx4÷ È4Y[(iÒŽ"Öig£z‚š{k»E¿Ú®›mšNëÔG륇d©JJÉb»®kœ£ª.êªOÊjT(Åd šWºáútû Ú›Ô•»˜Š‚©Ý¬›­®6s¢hZÁ<Uã‘;[o“jlúnƒÔÅ6•ÅØ¹B‘R³\‰F‘{@~vÐòk׸ÿºvˆn åIȃ²ÍUWÞ×Ä#ªPŒ\@’ÔlúòA}²‡ýÃöoþê¾\€@ÇM7ÛÛ{ãbõ°mg‹·Þ:¸ÿôQûèÿzöwç‹Ó¿ýࣇÞ¹/\ÝúêW÷7_8zëøÓÓ÷þ±ýþ™/6Ó¶;û¿ßêÛW縞V |øèï7ï.û§>Zýäǘ¸t¹9úúW¿vï•/ܼU÷ѻ￷Þ>_¥^4±cÜ•Ð1¥ÌL•™¼"‡›ï…R¶ýHlßn‘¶ãqÀ÷ŽoŽ—— ÔµËÙÞ<ö’ï·ÝD'…o’UµU¼=xg¹øáŸ‡Õv³°_ß=œöŽ÷WÏÎìl3ÃhsÑ ¯Î çHE/ãVN”7òîžÞýêþíù­õéóþæá‡ß=_=ÚO÷ßkNަ·~ É IDAT‰½Û,L§“#«ü3¥²Øó›Ñöùörû¼ëâ§Pƒ)‘ß±¶<‘ß Š2- D0eät¡ëÛ] £Ûiý-§i$lètð_Êõ(]YÇòàJ†L|Ï^Fª Ý™} HaEŽ+{VCvéÈ´¹Á )CLƒ7©ñ =ÿ[%&3±«4?R!ó@b$¨¨ Hœ „?’ÓAb0Q3—çLFC‡GžÈ3QðE255&82ç2­Æ¢)™’ ±9†gbÇ"IŒ®­®ÆºL.e3áb˜Le€[r«–¹+ ÇžøJržy%dDFž‰ÁN‘g¼É’A˜Ä x!(Ì”•ÍòJr´„˜©Y"óyyˆdÄΑàz7ÚYѪ™.5d¡Szúåî?/V)7d)•08ˆ†Ê0ö€;À¿ÕÔlíë)¦_Â×~÷îW_¾õÞŸ}tö¿¬î,1‹èêâƒgÏ~ÒôåoNÀ^ÂÞ+óÙ듽?zoUؾ‡CEs…Dí[`¥HþœË1îršðK·/Ñt =¡ —~?ÌýáÑ+#;n~K¦¾ް¡]âlg’¶ýºðî¦c_´} gæL4!%qDìdŠšXÚ´\¦e‚8öî¸I“m2 Ó£Z)Üâzf…l×ë(Û>ušJj‚b?¸Y¥¥/Ç“¦iëbTÔ(¼«¥TVU'Öo»´–¸à "&çÍK”^½š)“~ú)zåëµ³iþ¹ÈØÌÌÌDÙÖ?ƒfÃýå<à•CÎÝ0n#1‰d4ÓÀ¹/Š–H×Þ/…SR­X(µpÊD’Ò…kŠŒÕf;ï|á9zÈ„•EÅ Ç9Ì<¦Œ1àÉ<  hܪ5ŠF­xŒ=¦Òc˜(e…ŸS³hè{8–^)yBIuIEceckœµõ†>i¦½ˆ»A6¤Ýžø¢¯Œb6ç4S5…9S ‚'pð½`j&„ŽHó¶!PC2˜Zvø‡¢(ȲljpDdÞìPT—\9W‘ŠÌKdRâÝ Eƒ‹C®Zößά88#±]Stå²pó‡Ö 1›¦+zÈ ï³P½™ô£yJ608ég÷çvM²í&+ø4eÛçÔó|^/µ_?þ«Oˆü­«æ#‹ˆÈ{›Ï‹ñ¸öE‘ºdlÎS¾(|JmŸ:0Š ¾@¨ ön³Þ2JU¤^º^Œ ãšËQí[‚ö)Šô}/­BÐÖ©åé© 4Y¿mW«Ufû³¾iÛ¶O–„Õ{| ‚›nÛö(\a./‰ƒÂÅÙÁ>¸˜X``[lW)õ³i}÷èàÖÞìÉý‡›óóÕÅÅÙÓ޹ðÛ$ø¢ÞÛŸ:a—¨TmD4í‰)¤à¼$‹$P?ª'E±¹’þ#£1¿~üú¢L“ËX}Þ›80ØC1æP€Çäjö0î©\ö>1_œo×M£<çŠùå…<¿ØîŸÔõ¼•í&.Ñc>Ù|»Õ_ÿ™ÿþŸ㣗Ã|þ¸?_uø»¿oÞ¼ë¿þò“ÊŽ–—íÙS½Xt7b'³¯ßõÕ´éÓ“ó:Uͳ×gG—¾ºÜ\>¾Ðöþñ‰¬æo~5U¯>Cõ4Ëà¶%O΃U* bvJ¬&”Eê O<‚«Í½QMn»QwúÜmûý£jTDÿîvj™›†º¶XƒSQ66^îëÑk¯ÊÑhim#U²¦o7Ms]zyÑ>M›ÐÇ3·,ña·ýhM:¶ñd­ë-û0õˆÈüÑjÑ%ÝŒš÷‹ûWvÏõîჷöo?óo*âÍÇ«õÓ‹®‘4¥qe“B¹–Ƕ]m] ÚœB •’#r.ó· ™«Fo3v‘Çr0¾löYÑ.ƒ ¯*! îï²ã U»ù+ï0¿@²S.ÉÐ Q¼2â¾:ù¯ü+ëØ|ví¼| »Ãõ¦úÏ,Ÿº9Õ<ë,a(q„U½‡‡) ¢šMåfP ²((냲d™Í‘¦Áx‰Ä,'‘€`ˆÐ¨Í™æêŽÀøŒ0 bÞé´¯EÆ9q>3åÈ̈‰L‰ŒÔ¶1)ˆ˜Ù•F¥Ávôº|""{!ýƒ`,Ñ œ=Ís¢=91œ,#±yBp°èxçÏå€Ây€‚'M7 ú‚DËlma&Ïš”•aì·€×;›ÇwOpïöF_Í¿2;yýÂᑯŸÈªFñqôOšö¢U1Ô7ÅøK8úÖQ*:~ÛámAùt‰í%FŒ(cóGæ¬ïCë­šs /.&æŠàÏ»I…ƒÃÉóí•QÙn½vÛv½N­C<Ÿáà¨ØœÓê¢[œbµQë×{ÂŽ­¥¨…9f–ä›TªÔl‘qkr°X.Oû´øˆ{ÀñºÅnºçÊWËô…YwŠy8=]nÎÎËóíºíQLQOªÑñ¾Ÿ—üù³Ó"ZEfe˜l¥_·ÛmjZUõ-Ò^à=¨@tÜ HUD(õÒj„æ¶ß3¢AÑ¢ÃMÈ;l–†iÈû»ßô.ââÞ‡Üy¡euj¶ `ól~wë«Bˆ¤sžSB¼ÆŒ"zÓ§Sµ"Á%뢭”7b}›ì^Róx…ál¶³¤6—stˆ Îil  v˜W|§ ÇlsSß§œÏ³5[KÛqö¦ÅmgµcVˆ™ªõF ™Ì¨SkÍX‰É“9 ÆÁæ4ª” zu{ 9x`·O&-Ö‘õF6xËfu€w#!SMfPe6S‹ÄôŠP6ÝßÁ Ìl¬jÊffóÞ™SfcÊ£ <.¨«¹d¬šiƒ&J*$KªÂ6Lƒ†ïýŠk{]ÐÞdÍ}¢êPU¢Í;~5 Ð(;ž‚>6üË4a¹k²Ìºä«ÖŸ #úÄ&–Ó”~ýøoOGdW0‘ªyÏEQ¸{{SW"í’ “jÔh\ôÒ÷b0*Q–~º?öeAÌͪg6%e0X¸€«\9©ˆH“™qß´]Ò>‚âÑ´Øn·K¿L½4ëífÝ)0ž–` °FK}²d\”Þ9rØl7Ì(+žLÆõ(€µ‹m«ÉžÅbì9˜ç"E=.z…¯ÝþÁèÖÉA{y¶xÚž­šn‹ÙA¸}|K7›&IŒ©í:mÔõ6æP#glÌ£z>žV¡öId³iÛ¶u®rÿ{oökYrù}kEÄÎt‡¼CæÍÌʬ*‹d‘-‰­Öh5º66`À€í¶ßýÏø/0à7?¸ ¸ûÁ†m¡aØ–(¶$J$‹U¬1«r¾Ó¹gÚ;"ÖZ~ˆ}nf‘Uj–š­j¸yHÜnžaŸ½cÇZëû~Ÿ÷U•-CUD˰ítþçÀ¿züâ=ÚuQñ€oK£!Ë€¹·¡šÕ툃OÚ€&*ïcUïœð¨¶p~6ÿø|¹©›D>]Î×ãÝñÃg?¾u/ìßä›'LJ;«ÕæöÁÉGþÓÍÓÕ£·Ÿ¿zào/§t ô1ÿßÿË?ÿäüÉ×NŽnÆ´Ëž¹šVÍ›G¯|ã$¹É#É]sº·óõõš>xïÉÓ'ÿüŸý?é ÿ%ÒÇÍ_•Ñìü‡ï<ùéó‰P&8 kïÀLÆ$%%ÏTLE4çxsoçÞô°iš±ö!\€VùéHÆt ª§ºùèüÝÓè*íoFûËÙíWî¹Ñ®[<©|8ØÛŸŽ¯(Ýh&}êh¡ënsyþœžóá|‡çÓ˜&’7±šTûwvwêÖÍÓÅ'gu>ÿŠÌΟ=‹i4®5ž]\}²|tºY»°‡ÜÄãë)Ÿ†˜Â:ä4mühÊGÓzĬ9PG/á’‹jŽàJªÄ‚aŒ!Ô\™YA³ñ ’‡ Ø«*h›ùB/¥\tf¦%|të1³!›QA.§ R£¡¤2x[•ÑÃVS±Ío-Ù:ûm¹RÅÑãƒò: ÅlE»oLt8¬5igŒò '&ö 5甋⢸sˇ0%uP‚:3fs &egDƤZE¬´}?¦E}Ò¡mqï6^û:þÉõÝú7ìòÚì=¿œ?˜„ìÅáaĘ´ÓÉ®õ1.ÖA$TüÊí–ù`´çŒ-ŽhtŸ&Mw}Zt›®RÜ­šéHwVëOÄí&¾5j¯ªêawú =xœªîlŽ‹ƒqÛ¶6jà’¶†‘Rô•#u+¿>Ë9aÇa/`Vá`f6Á+p{}R]¹ˆ˜6ëjnáa7z,.w9æ\CÛ*ìîrÛŠŠ®×a݇^üÚ¤“œ¸Ëªdæ0k]³¨p sp5¨i—Zv¤PRËÙŠçÆ–¡:¡¢$¥’Ýú‚¡üÒ¦åo±Õ!03ÁC<³gõpjåëV¢k(?ÀJìM•˜21A6,¡Px)ü|l²vªù%³ŠÙ×YžÊDÄŒŒÍ”ˆ˜ ÓšnŒ›ÛM8Ìr ŽÅWJJ^ Fž…[·ïuÌLf’Ñ'‹f H¦ýpiB@æÌYðVWVw&UµÞ2 ªŸì¥¼l h–ëÒÈf^‘¨<3J+Ä &06cUˆ¨™ed‡ G2ÌŠ%‰ä-E²ˆ¨ ´! eˆ‡ Ì3¯æiUùÙI&ª}Ÿ»ˆ¾GÜÂ6l;Õç¤ò/RÍÑÏ8W·M¢¢õz[ØRìJzÄ–>Y¾>ä‚mx©g/—àÿæòÆ~N5Ç_’•ð+SÆßÍCÕ óä=™LF³ºm]—W1&ƒ8ObFD!„Îê@UUUu=ݶãˆr¼Ž‚¯YÍY4on¸ñ9«–4?âÞ|†Wq¥‡»ùÆ;ÓÝõr#1¯©w¡ö}êDE¡½#[–@Á@M˜\;jÆãÖ¤¼Ž)æ”úÌGp,Hu£qj‡Åò»\b±P4Õèpÿ¦ož_\,–g‹ù:¯­°O¤N" ˆ«0MÇÓv¹Y/®ºõr•úc.Êé![Ò®™ú/ÏUUý댉Œy`{x"o`抜'W§u»Û´>kÈÖ°÷F&~Ùå‹Åb£×ñ¬·nêº?ÓÝ[8|uï7~û𵯵ßþÎí7_»wµXež=ûÏÿðƒ>ÿgÿÝ?]?ágëõÕ•>Þ¬XÖ³u>I¨>y¾×ŽîíŸhÄå“þÃÿó_kr÷×s]éùòᇋ÷z4r¿¾óæÞñÖï¾ÿýÇÿ×?ýèéøèÑeôËKwQ¹$x5d8Tus†°Ò¨Xê\ ´¶n¡ëŸ=ì» !ŒV´½_gãvmñòBæ7F¬.¼¤öâj¥Ëp³Ùì<î,W«n4ìk79œÜ}úÁ‡Õ޼";;k×ÍóÅ£Þ¡ºŠ‹þÖšwÙ&ç³›:^\¬O'T·kÆÊÑ“˜%ì7·ý½2w”pË·‡mœîuþ.6¯¶“ׯi|÷ÝêOõ=œwøÈU1vún¢z{¿þÖèüቻ}–›O7±ŠÌ>Ž{Ã$œ,øq|ïÑì„(ºž÷ó¹Æè[íýÉqÕÌôjuüx§­|û<ÞwÙöó)u•-Ò8w£õ¯ëÎ÷Ýîä†\…å*_~ÔãªÓc]Ý%ÜQwÃhj]¥>TäuQWWá°»S-y£ïÔýת³ß­/FÝr±^~|áÞ{ŠtÎþR§ÏðÇè©]/Ö«M^ð¦?±¦íÔ-¥_Û• rëàë1r'‘ºd½:5rU®*-¨¶\¦†¬Ù…óÁ›:¥¼ÍQá„Ï!´šY‘¥¾Œr~yRTFÌz ;. Ða íœs OÌÈ#€ ÉZ“§fQ L¡÷ð)a1ðÁ¡F ÈJB&%cÔ†d¶âíS+Ùd¥/R4{g5aBëy'¸žTwC §¶QªD”™œy œ/cr Ô™yµÎ˜³“eGH´èkÕ±q@P& VEˆCpŒ$C!!ö^ÂÞôEQdf±D–™…™¶Ý.ÀÜp°J˜Ðõ4†È• \µ"–frN-UlÐî*£@ò˜ÈÔ@"ÐHæ ŽU“351MYú,]DŸ‘’ôzÇõRa\¦Cå¹Ý•ý|`+®ƒòmÐ@a¸C™†]®ËÿúÌ";°Ñ‰®û4ö¯žÑËáÁeõ+²ÂW[ù¼˜,¿WAJ¡ÌÃÃêQ=™É÷Y“HäŠ jy4®&;#çµ[.‚gxcØFsÙ™÷Þ#Ô1\ʼnhV´ö«øðÎìøþÝÝýÕÕJkY¦Õf© êȳ÷ÁsÅY¨\–jªÓñ”á|Ã\™²¨ €@¾ßlš¶Òl¶1ª' ‘f¤Øy—0r£IÓfK’«¢i„&bmGk⬤N9¦œµw*1™5ªš³Æ¨ó‹åz™S‹'Ëf`Ïü݈¯¾Ìø¬„µü𲄕¿ê÷ö’Y¹<@CæeCÌ„–¨êeáÖhσR”$yÙõ)®}²8_ÛóÑ;Õḑº˜–‡Çî?ý¯ÿÑßôu³~q¾üÉtºÿW|$³oÔGcÚ©Ï/diééz=sôäùé¯ßYŸ=íVѽ n³úë?ÿØÿ¯ø-¾uïþ~²ÝÉÞlæ§çyµ\¬_¹uoüæáƒ½U§çW§ùÉù"íÂTúœjê‰ ¹äày—%@äsÍ çiê<_®m7W»h';ãÉÑÉÞè€ÏëÓO7çç.ÐLž.»]×êy3Aóêï|]³m¦½úÂM{ö‰.çwŽÇ¯¾ò­ç§Ÿú%òyp›:T³éÎí>>ºj¯önïNoïÝÝ[¹îôá|º³ûêÍ“óÅcN•³Y»3]U‹e~˜|ÜÛÖ©–s±ó8iÀÚb³S‡£CŠ{¾;w¼Ûß#P¯1!Œ†mI¹1” HQQQc“Ùöcƒo›CTRÔ Äƒ‡Úl«³"ÇžÁ0Sƒ3’!Æchæ_G­—ÀR¢d”ɶV"ÒëxÇëí{‰«7“t&S+´i"5cUe51¨"2 ¦fT‰?³+Þ›I@"3U¨‰²•i'g•aÈBÛý @P†²#ÏT1¼ÁXaYR*Mcc"R+b+ž(Rr›L`óJZfd/o ˆª˜²J!¤’ª#¨ØŠH~áòÁ”‰ðe•2ÀÅaíM3ÔCÅÀ$€•½`ch!¨®”(«0%ÏžÌdÙ4'Q"v*ˆº”™(×¾ÎCóËx…—U=¿¼Uèsäø?3q0¨ÂàT'ÁÃ¥Y£‰8>Jv¢v»vG îß:žœœ€\üËŸþ‹ÿétÿ/ ŠçíÁ»û4/m¬G;¸y û¯ÉìuÃëî‰>ãô†Ø­¦ý§Kˆå‡8ûs]T{‹…A.q¼Æ”ñüÇo}}ÿ*¬ŸcÉD€eêÍ¢¡7$hG‰"žçÀ!Ð !*,ºa6C ‚߆!_']·ä®$¶m^²l“[#H´”¨åsRfGÐ@`c‚÷`†x3¨J`¬cç¼cc£Èà4ã¬àL¬” Å-ÎNêàªBÍHQb¦¬Ò›t‚ò'T‡Q²n›qå[—2¼.0>ÝN¯«åëzI‡L\1Pf !³;—\¦¡-#%±Ê¨0Ã˲*×™¿6Äß ëozPæ]«6}f þb–¯Ÿ¿…ü²Ñÿ_›ñ_ös}©ãS°Wƒ~ÞØ¡ðLLl¸WßâS;­Žn=:ÿ0‹¤®‡X®nªºálŸÐÑÑ{êr¢¾é6XÅqÂLº^ü¤Ý™Ð¸ïSܤcF>;Ÿ§„ɨÞÝmWÓÜ´Œñjtb™ûIç9ÍOQMxTOVçËÕ¼gr“iÛ´,èSÎ;fÏTûÚ,pRv^lÇM»å$««ùìþx-ýf1w™ôT³ë³4 ÔúËË'‹yÊ23ïLU­ÛdM uö|„×—8à0ƒb ZÎ×yƒ~ËÙs §ªRP“ü[3}Åçç–ÄOÛ´·ípù3ººnjðù÷ô3“þRç­`ÓëCÃeiÛ.”)^ŠwÎÎ*RCN: ~VÕí2¹Ñ‘Õ{R%£e\?Ï2g^Œy…Õr7­yµᾺ=9¼¿wbÍìßÿÏŽn¿ñ¨Ú[æÜµ|œÍ¿7›0C\^-_ùÚíO?úñ£þÒíÜ܏Щ¹qøp±öí¨c÷ÿ>{dêU\ŠÕOþ‡‹¿øá'¿ù›³ÛwŽ]-UÛß<>>9<ÚÃÞzþ´Î£åùóñë{“Óùríqê9WÎ… × ‘ë•9´¦V‘« X&ä¾ Þ¯hfãõ_kèõÝ›;‡?|þñ³ýôñ쪿ƒ':_éfr1‰}ÞúÉówÞ~80¿²|Ñ?|¸~buìŽ]Û<=[?¹zôí¯¿ÙÌã‡?ü©]ôoN¿ù÷ÿíw>Xœ/ýÞÞΫ¯5wšÉÎèÓ‡N›pppÓ¯íø¬¿xððþÞ19wpˆ»Çí´Þ}FnTg»3êΗæaä 2‚e‚ŽØ DTÛÖ?e‡€4(#™ä4(Bo{ueØ4²ú¢fPdUƆ)&L`òÄ r³á6—‡è>rf¬5‚qÉ$±A?¯FDÌTDîlll`"#&rìSŠƒ ‚rÉô!"ö.« 9–M„#ªL ‘q’lfå9ÌY‡È5¸…‰ÂÔHËpDÅzâÌ\ ¶Æ®H%K,Ì:SÆ_Åö 8Ö %*›>¨ööR°ñpc®Ë@ÍØ¬&f 3öUé´:__1{U͹ô+±c"æÚLÉD ÞŠ'ª4Þ f9—êȉS˘À´¨ÿßo?îÃe—/Î/Û`•÷9Ç ­šÛhf' šêc§O×ó®E:ð˜ªçDmÒöj×ëýMZ\`¹€oo|øÁò2ù÷/rªC·K­ËܯÆ*)d:£4ºêjL~í?<:ÝI{ý„ßÝ২NY«*ù®$wéZt3F~"÷ï¡X›¹‘œBRè0âØø…Y/É”»g›¨d3V f^ò&Š÷a—RÒd Ï}Pm f¬Y­¸¹ˆ N €fŠì²˜^L?GGYòˆ˜ JJÄpæêÌÁ¸Ä› `Ó¦ï[Ý`’©„\4…ÉÈL„ šƃ!™²‚9•œ¢'°‘“7r í(Ʊs왬ªœ™ªFõP¯ÊR²îAm]ï1ïnzŸs jŒRÔƒGí˜nº•äš+êôt-‰!xCÊÉå¶ö¬½i/Ú›E²HA&ÈZESÎ0¶h)IŸM Dð*ò\r•Laʽ÷›ŒˆªŽ 31;vÄDª´!Rs•g†¡c^›­ŒMjPƒ¦!ª˜AÄà™‹™f«PGä5–É’"å€ìjPHU-ǸtN ‘R¶Í‚¨ˆŠœ‘$“I »#§ÅÊhÝDº¢‹$vER­/<ÉLæ‰Ø ÁvY•À¦`1§Ãg+•( Î0è4Ü_XOv$ IDATaY F[çøòý‚®!çÜß¼3û…gGÿ¦TÿÎúûŸ=ŒÌ_êø|îñ$Ò¼m1®G„Ô{άÃ÷IȦ¢I-nr—,ƒÍ9rž=ƒLDÓt:®ÆŒ%IÌš“¤.wæAB*è7}@ÅÂÕd”“°À"÷ޏ©¼3ï(¯û¾Ó%ùqöQ+æ1¡Æ:öyu!«lM[·USJ*‚XûP×U5mëY}¢¨&ZSeŸ7¢kišJRê.׫´bÑó'›T×.!qÅuÃUbî‰lÜߌمզßô]‚:ªªÚª¶,›ÕúüüœB½Ùt])éòZÂã‹:H‰ì‹N·¯êüüù+®Hb_>­¾rÄ6fo(‡JÛ¤Ôê£Æe" Á1ç&øš©a¿×Žƒ‘Wruk"WÝêÂÁ&•IµTíŽf!ÜZÝš¬BÕõ»38‘i³ªÑ™§Ê×È“iÕÎvöÞý³'?ø³OþôÏÞþàÉ&RêÒõ1¥^24² Ø`^Ì«8UU»õ½«¿üÞŸÇ8¸Ýݪ­„U^½}‡2½ÿ£OR‡ý½Ñ8ìMi·¯ƒô§Î¥.[ŸEÔŽh›¸íV² ‰®³TÓÑnk­©OùàäèÁ½*|­éûz³‰Ÿ\.^ÆŽâÍ|vâñÿüßÿßßog´ÿú½odö³££x¼ÆúñbÙ¯/úyÒÜŽ2wN¥Ê9ëSÉõ®›åg]¼Œù|ý믿9:sýüQKt§«ùúÇ냰ÿÆt§»€IüþO~´ßîž=_Ü¿yòÍÃ{¯½õmus‡žÜA3š&¤uÜ˜Ž‡¡ï"#J0Ù–C Úf‘—í&Ô8oÕ-ƒø›Šìí3qã<ÜÇTÍÈJôjžÁŒL‡¤ ë )™BT_4h Œcƒ ¬[,x1-i©¥péGfçqÑ•UZhÁ¤ê‰y›ˆê‰È•™ÏPq IçC*ÐàØeº6A0Xp&c²â+®ÏRƒÄ Ún;Úb.S/2*°ñëD@l¥ÿT¢‹D̈Íʇ³°T¶×]M"*éP€ Kê vÎØŒT`æp žÀ¬~Ô2LÅQ¥–aÙ D¦¦F¤GÁŒŠÙ`3282X."#±S¨m@YQlS ˆj©˜±[Ú/ÍFÄ/ý /†UI›sÔC´ôÒSå´ª09ÆÑ·ðúëõo¾zóxÞËzyó ö—ÿâÏÛÉÓOÒóxÿüCQKÊ$KÙ˜AË–3%*ô?$E™–‹ªê@Ë$VC©“´äÄ©YÉÝ&âmÕBEÑwͳŀ4¼Žý¬ƒ<ØÕ`‚ ”·*7*í$4Üe©/ó­"‚ó¿¬MÒíìõøÛŸÏý}ý¬òå}²÷^9* 'Ž#h–¸Ž©Kñ¼cÏÌ`Ë,Qž2+D7’bÊ$IrÚzBGݪ_u}Íu[œ÷J¹ªª@a#©[#TÚT­S×ç…E8 •Wޏr7vv¯&§ˆ²Y/\äŠ}Bp«æ^Si@pÎ;†óâ¼™xpßË"^­®Vãq³ìºuZw†Qƒc>Oí4M÷&¡u®ñ¾v›Nc22ãÀLŒÝ¨Æ 3S†ª®{Äóüæj‘»%rÂÀ"Ç ¼ÒËÛ_=~ñ†HÑö~ÁPØr‚Gv‚%UU­Ç£>ÉE\±ÇFc/=‡0„ýø/wîúIk·Ž¦oÐÑô,¼Ê;ß|ëö«É«ÍsqTi}yÖ½ÿɧçÏßûä§ý÷ÿäÁÛ?îb‡Æ]§)n80;SA/j¦Ñà̼ÁLGj.e½ºB×áéÓXrö~ðŸÞÜà¡n”2+‡ªî12cS2e³ R˜j6f˜å!]O¼GO¶ä´ˆ«Ý\O—ÜAæFtçÖ§ö,µx~þAƒÕ¬`œGTÝÕÃ?ï}ëõWëüÆ·ê¶ýëø“Ó·ßüµoø;•Mõþ+÷WÏúð(,ùFËý"-—Ý&Ê“³ùã÷—'¸éÛê6·Í3»©Ga´s«ÞYž>^ög7nã¼yÜËêé§}”[=µeÿúo¾óøâÑhñàüâ÷¾ýÊëo½~Æ^¹«M+³‰»ÓÔ+`ávö‘®@q`'ö€.ËE#Æ6w1ô"p¦ˆÊ¶ò6Ò—×Á[Üöç7øzÂälÈ‘xIC>ÔÊŦ·½cÂ,€œ•6]ë]„ØlŠ'«T­@Ùˆœ¾»R‡ ,€P’·ÀîBÒ+<¤¯WP:¨Ø­l§lˆ5رoß¿3Ûg‘q/êÆ’·-lÀ\›¦È~ÖªW>ƒ UQùM.‰ìι)VU@ ŽÈ“yP`ue«"¦%°ƒ9‚7Û–£–É ¨®ˆõD©HüÙL‹:lTˆ ŠªÙLØÁ;†säœSûÜ&ÒßfµÕÏý·Ûþm׿¡% ÚWjlaâ¤n09Æá¯ùߟì}²²;{÷ió¼¾Kë†Þù©ú?~ø‘Ç{-¾ßÂM±ÚàPç¯ÕúÖNޱœÓn?Ÿdõq—ëÝz:vÖʸÝLñiŸþò“ßOë wî£Ù? M÷ìò|)Ëßá×GÝjw±ÁêY·z¶‘3%±æ 8‡þø‰®s}᎓ŒD–­Z{ðá§ïõyºÏªùj³äãE/8»ÂC ºÂ…„ÑÝШuû;µƒ¤ˆ½êx÷µÇOóåOÆ÷Óè Ó+´ }Êk͘š2ÂìÖ(Ö¶nõl,ts—65Ÿuºè2AkªG.L|`ã5Bû,jF!acì{6†D¹äɼ¹Ê‘0—S”y»l Û×’pü¥ÕÅ72\A”c ˆ4"ͬÆHNWP!b‡Ì\Ha¬U6b‚”ê–UQƒxæræ—#È ¾V§‰Þ|Ana]„!™uð%’ÄHfKÓ+(€5|U{,Dª “¹ÙŠÑ±™GOH„’k ŒhPI,Ȇ$Ȇ°WˆDuá°@†X4Í€‚«™ãªZ”ceßÛ&lÂÛÈ›µHš*r¾ ó`DÓq6cbïØ{gÞ±cv oP%(T‘A*cKfQ‘ IEŒÔÌœŽÌ,e˜ZÜÚ¿ ªfÂÃe:D%;bRõ¥¤F@®Œ¤!*3úrâàÊ\§ 7dÛŠ0‡¶Q‰»“mT/m¿&䜃G±ŸÌX·† ²¤~™Ñ—£lÿ²zð_VÜôU͈ä ð;Ì_‚Z®/XóüòÁ"@-k|P¡æ»þâüu…UHÙQv©ËÝ¥uKhÇû3Ç>¥<7M¨–ú•¥ºiÉ8÷â",¯M0eÆîlïàÆ¦?Ïh™»ìœ9é%Æ´êR·ÆÄ§>‚ÖÐ ÖPÙ%IÊ1Æ ”3V«n¹yˆ¦Óz³è}]g3uêjßmÖàªëSN‹ÉdV»jÖL6ÚUŒ%ç(¢uª­úÜm"r†äÏ9 ¿hHôUŸÿ¶©:ÿ¦ÛÕöd§aÿ"4M¬Gu3kŸµUL|3ñ.36Ò_Ì{í®Vι&Lw&{Óñ[_»wüÚ¬;X4žêDu^¯ÚIºÚ«ÂÕéfñüœÞÿÉ“ïýÉGï¾}yqÇÐE´ÍL¥Ùô½ˆššLˆDùÚ‰+dÌä<¸Ͱ3uIJ^#&x‡6À–‚A•.–‘mIÉy2Š)¸ 3BTIäŠØƒ\Q‚©9¦ÌÔ‘Þ8Üßž'›4Ít<îåw½áî­éå{¿spóþè>9»üßÿ·œœý'ÿ;utÏÝØ\<ø“å÷סŸþÚþ2,ÎVßù^!Ï.N+ßììíRåà´š;×cþ@¦ÕE³Ûîï¥uªvÇ{·öçgçËpÝâøÖîî86ad§ÖVxô£ŸÎÀ¹?ñs»\]múÅJεéYt>†ŠG;cì‚ö‚@NVæ%c@æš]*äxˆ)œÒm$<æéu¨±më"-ë‚»j1̈ËÎþ:lÑ^jú ³7µâ ¢í/“ˆ1Jt’A†ur07à­؊’•`cØ”Mýö/!õ¨hÍéz½-oGÃÒ––Už™®Ïz²²ç§ôØ’­¤D2¹Öäz˜o ¬Xþ9Ìv(D/‹]¯ ¡áˆ9ÇFÊ×déavÑ¢£çë$Ô 2e-L§¢ëŒ – Šx° ù³ë…¡„‘C85&-#3Ñ*à!¢Ä9ǼÍCÜÆŒüÒMDEý[¸r…(Ã+ ê—q@ 8ÅØc2Æ×¿¹ûµß>˜}ÛfÇÑlZ³WÿhŠÑ·Gß;_õïÌ*Ô—ËøY¬¯ôþmºuÏv_ÝÚ,ùùZÕr®Còöݪ™¿sþô/NíF'˜cüú²âÊ쬛¯¥=–Ñ.wÊyáÆã¶jk7áO›ó¤§Èóu›0鈼s-š -qRúñþÞ./°‘eÿôêêìU˜a¶Ã×ü6V=Î Ý©â-¦m¬é1M#÷Xü{—{&÷£y&×#U#è!d¯Þ½}#ÜÍ{'W²Y¹ôàê‰LC»ÎRo1à”+V0gfÈ}`v梈¨¤”5E˜(¥d‘,9ÊŒ òäÊ G0F&8")qU[vH1s¼ÈÑüïS‹\ þ­»¨#!Ê-cfPBGè‡V…96sÆfæ ÞAÒ5F 3† Œ`δXMJâÁsEY ÿeà5bK13.EL‰ Î ŽÈX݉ùhU7@cäE«l—YOMçÐ…Ù‚YlóàÂ?Th)D‰”À¬2 žœ±(i<Ûë‡ …Ñt€«2+3œ)Z ã:)“&‚²fQ…^ZtˆP!ø"aTp¢žàÉ92…+?kÎ"}Òœ¼EËIMe±2NDuffy;O/qHÌ(Ñf6pų̈Pwɹ`TƒŠASà"JÛ¦øXØŒ‹›v1y«køÚ[µ\] dÖìÏf7:KÏûeÞ™M®뀰w¸ßîì<~~;ƒ±¦UÃÖ.nsx ÿ«Çç|~¶Ì×¢aæâÁ'cdžš\mÄQ=\LÎ]ö뤩˒•ýlÒîí†ñH%}çkß<¾·ÿØ=;;}¶ºêóEwþ|óao~îþþ«ÝÉñ>úÉ~øÁï<|øžžžò‡T€àBCJ’ J²Nkò½"é6p¥ A|ë•=‘s43tÒÂ3XÏñ|§ lkß*×VUÃt0Ûíu½Ný*%5AÙA¶y¦fÌeƒ,¢ãP»rhÛƒÝMcËølžÜ¬ÆÇ­ü‡ôïýæè~ÿä|g‡þËÿö?þûÿøòä$¸°Fw¶²gwgš7l÷jsu9Ù©>Y>÷ûÕè;®¢ÆÑ8-|~«ÙáþOƒ»¸ ›‰›Ž£«~ó¸é6^*ê6¶itîÆ™Zyýî½k·SMöÒïÏWsÝ(®öÇøøÙÿäÇù曯°Ô;˰›ÚéQ3‚óÙ¼§´m² sží¥Øþ‰>ª8 Ć2¦t3Š:æÚݸµöÌØŠ‡‡@fn˜0 ¼rŠÙhcÆ2|çÃsDõ”­&¹XwÎppwÿÑlüÇÕý4Ds±vµRÍ}ªlLÝìâãåÓ·O­ÇߥÑ[·1Θ ­ë›ÉååógË'¡»±Eî)ñx&i:ñ3j¹GÚéf…àƒC3GN»ì_ápœóN•óôr¼s§#¾ÇØKû¿}俗דõYwùø}yœ0>’ºwT©7 ÉáÅ«åƒîlq¼Á¤gg¡ kó­U».Ý­ÓÉôÙA»®É}\³FÃR›”¦LÇuåíb,}bÓÌ6ªœµ:[ò¯Öˆ2YS¡_"'µˆJÑY$ÎpêYfcWì‚æt0#29gE£¶Å$ÚßT+ÑBVö:V8° $ؤÁa…EPœBÁ³ƒÍ"Ye`ÀB„Lˆ2  Õ×P¢— p`‚c†«|ËÂfdPÞB -,4CŒUFªlÄ8³eM‹>?ScN˜°«¢ ë<ê…ÙŠlé¨/ÁÌcv5¼bÁœ%Ö‚ª@Me˜Gf˜ ´Pö<Áy¡íˆDaæ†E<“ó^QÁ6hÕŠkQ‘ Xo;×í•-ÂRÊa,ê#|]UE¦š³Ä>§¬©Gê5'΃e28#&GDœÍ`¿`X˜”È »\ ÆÌÌ0¦`C$[E¾a_‹«Á 4!hPf±JP”×2Æ´“&x”!Ã$CGHˆ¨ˆväˆÈ (›æÝSr ”ÞöW§šûªœëÿæ_Ö~)Ÿ÷ TsŸó 5 ªœ:™ìŒnìí¶¡Š«¾_n²ˆ'ï —c‚¨ãÁ  G¦ªI¥3ÉeŸÀ~‚«zÄŠ+ª$¸JKÜÑr¹Œ):‡º;$IªªŠù9ž=œkâ>EU…±¥è>FM$Q Nó•kÂUëMÅ:‰ˆ±‘†Œ,ªªŽF£i;…æÐøûû}Út›«úÑz<›&äõz“S׈QJi±XÕìI´b·IÒ]..Ïúûwïõ1÷¬ÎÇ,HFŒ*yÀ×8ˆűٿmççW5#ú²LÈ—CJ¯É”’6„`ÆQ\ÒqÝÔ΋ê<®•)zOMÃMÃ]Zt¯ë´ºªúÅÕÚõÜd¡Š›êGß»üàüáîâOßû«|²Zôºp9 8îSX§DÎWm£û¼pÈ‚a…”P0€’Hß§®‹ T¼2DEë(¼!«D¤\I÷Æ«‡±n½]f‰bF &Š[°´t—s²,«ÓÅ”B}÷í5OV/žíþýøêáþï}óöøjƒ‹ e>¸³Ÿ‘n~ ÓöÙÕé_Ïöªo¾r‡!ôÏôôÉÙóùùþmzÊëU\/yÕ§gç§m7®ãŽõ£ªÞuÓéäpŒ]Ÿ¼,Ÿ.EsíÆ][íNƯ7tWFÝøÁ½X®öNF§7× z‚ÇaOÃSëÝ¥ýÚº¹ï¦ŽáÍÔ ïàE9Dá\!¬m‹"€!n`ÿ˜žÚÄx=#ÚV4÷cÐðµ ¦ˆßTpf24ƒ³K.;~ºs¢?¶ÀíYW^š@ލ`– ŠÚÊ`Š90yPÆ "șۦ/ñŽŽÊmsðmª™¶¡‡°ÉV H » F^hµ@ZP¶¥Æ£b%¨HÛ|Ø!,Î £$€øúòqCMB†aD cvf2há1L˘5“nãGLu˜ð¹€!µp˜&iÙïi Ë,{»¢”cGØþÏ<À&³R°o¡º%ÜÇ•/ú¥–Ê"**‚m};Ô2b B¼ë¶Ý/y)å­Ç©´b ØH™Å›'%;F†Ø;< 6Ü~ºû¦ko´:Â3²¿?»ý÷žø«eÖä箪jñW«q7~³ºóâoÉVÉæn‰fZkd™}ç|ªÜ%7Ù¿òæNóÝÌ6˜0ïpæñ°Û¼½Ä%Ìcÿþë%r®®rõtEëg WŠ%jOuVŽL2ÏNöfwyÖæ¦ß\>¿Ú<™WgæïM‚åUZAŸ÷ï½¹x>§wtýxýl.sðø_}¼c%Ó_à>e€ªª®³ÕÃÝ'Yë(JÔy—bî‹^È*LÂL†) CÔ¨©B¤8œØÔœ(pã¸2Q3sJ/­Œ–I„$“$ˆ””eREVVe˜¢÷X8´jU$[F,ÍVÑqvž uÄ ‚å r¦lå@f5h¶’àSòÆ\¢bäRS¨‡W0!&eʃ'h.µA¡GÚK#äI)¼ÍRi E‘C ‘-g…ïAu¹¦U5ç˜-+r†nl­ƒƒXÞ¸ƒd#)¹âJuPŽ. ])‹Ì¬2®É,ŒÈ5消œ ¤ÒAãplËÛ†7W58À•BÖˆ”Y#4*ÁDJNÔ` …7xhÉM"83*D1ͤ%%–K¹øªæþÝó}¹ã󅪹á"å—–SÒ*¸É´¹q¸¿·;³˜Ój5ï˜;ÇlȽIÌæˆ} BV)©‰Ô;ŠbF¦Ðèû,ÆÁ7Äôb~ISElÌÛd¯bfÍ–ºœº()òBû:orÜtKË¢½êýZ¹'Ë쌈˜Œ9vœµ÷¹Š$w¹×µsJ!„œsVñŽ šúÓQ[ߨÜ>dï>}öô*®RŒ›«äœÓ”»Î8¤Øõ‹ùÕÕÅY¿îI š«¶¡ÏN/ý:we«Ê Zv:d}˜ 9þÕ©ù l@^¶† ªÇ0+ œcGäãºjÛóM#4®¦7÷šª¾X̯®.ÖšƒeÛt+ñÞ{£‹•,$« VÝz,Ϊš©kîþì½É³&ÙqåwÜýÞˆøÆ7çT…B…šƒZ’±)µI+ýZk«¿M;™É¤Œ mZ"i¢uÉØ( €³rxó7DĽ×ݵ¸ñ½ÌFÙR½EYVeVÖ˨/"®û9çwþîG·ÿ×§x}SšF}–·\Üd±PäBȃ¹+±»Ø›ªn‡Ô‰àC¿1®×̬nªÙ`ÌàKÎ5U¿O9¥~o™5=Ú,ÈU$.+îTJÚ—l®®&̰JÑ’ÀÑÝ‘})ËãÅüèÝs>åÞnrxñ_ÿáw¿ÿþÅEšOÐ=Ûß½lÑôߘùåî_µÝÎéñG›’äôñã‹.~㣧?û_ÿÕì>˜çæÉ>nåô¢9¾³@Ë«-‰-†}\`‘gß<êÖ©Á8ä~»M‹æäáxýd'!K¿ï÷_üÍßt»c]½³í7O¾??þ£Åö{9>:ê¿ýÍøÑ®nM—ðHZ¤½oYàTY#vpªÔwiÁ¤ ”"Ÿì$^õ–‡%Ãô™ÐƒÆr(!qk+<5Á¦\ñÛ2Ê”I"€ªùkÚ]€Ü…iŸÅL›×dÅ+LNgS¨AêlnÎÕ/V_‡> 'U\âi&awן¡Ù„I¨G¨ºU%léþÞó[ÈDoX‰ãÓå«Ñ¯ê½ÐÁÍtIå¤ã'ìÇÙÖßìñ;ìþ§Oí8ù—øÖ³#ÒõM?J\îÍ_|y{yu¶Ö~ÁQàOúÝwßÁ“ëûô9^ì1œ\a>àœ{MÂõϼ›ËfÖ CÓ:d3¾zÞ†åÕ‡Ûå§³û¿îÓÏqA°êºÖ°ÓæSÊ?ïóýµ^ªÞ kãPFMœbH¥Ùl€;ž•°ÿùM¹Mº°¶ IDAT½»9Õ“æwd~çhÊë1IF¤Ø6-¼@_ÃflQK×à çÜ4C˜go3"ÏP|ßIÙtZY`»¾×éh'~»¹ Ø*Âzb›‡Û¾/ †´ƒ4ÙgÅNÉMÜ ›©côc¬a=—Q=5xQMVô£Ú×ÃC&BáÔóâkøß #p Ã,¼?ã÷† ³­ñdäB@6r&w‹µŠÄ`yÞ¬à -â^¥î9ˆÅ¸žPjÅ…˜ê#˜DĈNÅ1VWXѼŒÔ3Œ¹Àapl *#H˜ÑßG¢QvÙ«€£3 –‹)˜Ì(»WVê¿wÇ„Œ66‡‘“y) §äŽ‚=ÃÈŽ@ˆ aÐáŸhåùa"T¼6–‘ÓävãÇÔ«¦OPRÊL5”XÙ`2òB…ì ;„AŒÀÕ*B)È ‘Œ D“2ÈæUpö¥;’DpK2§°D\Pœ{ p#Ϭ٭EØ¡°÷ä¨HnSpšÏ(̃ Q0’á#rí‹È>µsP:B¸ ˜›3=po¦§¸U€ƒÓïn"ùͨ¾¿«üoš úÇÒˆ~Óëó+=ч ‡:sÀɆl3Žm'"´ûÍæ.ï5vq&s"2UËV’R`1a?Œ5sáÊžÔ …,q¶Ž•­é"ŒR?û5Ì›"š6të®mÛa—n¯nóàJXwÔТ¡¹šnú2ìÔ0‚Ü<81ƒ!f@6µÜ,ÚÅ*´ó˜Ò¾Ï=Ü‘ÄÐtó¤%íú&†Ýn'Áf]8½X¬ŽããgÇÙñj{ÙMBûÌÌMÓx§ó¦FwšûÕ 'Ë®XéæKé›ë—Øi7;žuë´ï÷¶«{Ø.•±ð_#úO½Ž‹PY×Bõ€Å Ê÷ GPHdPÌ[,¿ÛmKäûý¸§Û6 £÷¶^,/ÎÏKôÛû»Ù¸>ib(ÅXãy»zrq½m¯îýþ-Κf¼Ýo÷@;_o†×.c”ШæÝ°#αsµÉQ¯þ ·nÖ”Rvýh`³ª«jã”RîB²ìE]†égŸ}¶šu«ã£nµn˜hØçíýÐ++˜'m~9™ó…Í»¾ ·4Ž<¶üð›ß|2‹q›h×b~Èöêæß}prr\JsÔtØŒGGët×^~ñåîo{ù Çëù‰7 7Jq”e#·×€>™ 7´Õ¼Õ›q™Eú{²Ý»§ë?~±Ùw}ž­–i–fÇ£Äþ»ú{~Ùõû‹¿ë?:ýãGïüI›/¶_\ß<ÂúÉðøf{uõùÕøRQbœ·<‹6ú!ìQ5ÃÓÅj*†Þ¾œª·ûmEˆ@eú'Õ¿ýf.:¬8 ¼¼ù{w‰0Q¨€¤Ã°¡îV?o•q}8y©éÁï7 EÄJ$ZF &Ð:ÿD'W†žâRTx¦ÅQkW«#®Úl©”‚¶8uu«U“‰Êˆsæððgü% Ö@oÊ«F¤o~’¦‘Ç+ ›©ÞwDF„‰!^[dÁîâÓˇO •9KBÍ usxp«×YF“ѱb˜È*œ˜HÞŽ0MÉ«:…âPÁQ‹w5+<[Vx)¥”iRypþîBDo?è¡åþ€D¤Æ¼ûsòwúV gjkdzßìå|­ˆxçtFïü)òÞ?ýdÙ¬º›øgþéýuÙ­Ž_;^ŽýIJÏ ¾{Á7Û€! DXEÌ¡Û-¥‹ŸýåË‘vOÿÙBœyŸÀGíÙ9>½,?|ÙãC,.q|4ÿü¯ö7wŸ\-Ñ2V_¸¾€–bcŒÝŒOÚû–®ïwT¥w¸ùèöåËq¹ |h@ºGºWjÙÅù‰ô”w÷»û}¿l«®ÝôûÒ­á ñE”õbÞ6rD¥u e,Ã}ß‹ïJÙ%@CÞíQ r‹ñÛGï@"Nƒ˜3©Ì-hƒI5é¸sq¤Û9vyïŽqº†GÌÂLÆ"Q-K"ËV •h\óIÞtab#±z¿Q!¥ öæøž« @ Ÿ³<ærcX¨³“;ÈŠÁ ƒš8À±:öÕ+ˆŸT-Ê:¡Æ`D æIÓvõbÎÓG*DŠn‘®âJBJb…F" d„Q0öVÀK(¬CAvQÊÆƒ“#¸·p-+ .pJ¦ .5%3›ê7àînÕOÌo3((™SUàÙÀŽÈ¢PD‚g‡ƒ´‚Ýj¤ìF49]«@Péh“…¬Þº ™œÙ¹ (´R6)À­RY„<Cj_¶0ƒÁ^ÄrˆƒáÐ>G‡Öð!9šÐDHKMGaáÍ íÒ€s) K¤Á>¬‚;!d3G¤Ð!Ì[·`Æ…£x!¸šªK-ž#x dÑ9:‚îÅ©À ¤®0ÌáÕs[ÓáÁ–ýÕ§öo|ü]õðü•¾ý›^U£¯Dl§¿ŠHÉj( w­(Œ53¦@}rv·Û! Mh›&l6›Bæj„õò¨kBò~s£ýÞºîhbhº6§¬ÙzlçëE²þöz' 0ÉóëûÜ­ðèìììñIÎyÓo˜E@áÊ×ϯo¯¯9:Äøp ÜQ¬‰A»ûM! :[ÍH¸iBÓÎÛÌÅ-;‹+ˆÜ{gö»E»‚åù²».__^=yú8Κú‹û[_¯‡±àd¹êb®ë£ÅžÊv3ô£5Îí|v|z~s?ÞÞìÆ=òàvH « ¤!ö_Á[øGþ|ÖcÔá(rø‘ã?èþúatµZ’ÉìÂNb‹Ó£Îh{u_(›¸ óy¿»˶‹ ZiÚ8ŸwëÅ\f²í7»íl5ÒÑùQ»èüÓôñ_ÿí'L¼¾sEJãÝýør'É–ÇÜR’rò‰œ¤€Jñ©ÑÒ|‡ÜÞ€|,#`jxžÕJíY-pŠ¡¸esiàäÉG#äÑFûЯbŒm(PŒÁ Å‚´Ý¢sE 95‹ù]¤ÜÜ,7ûÓ¸üƒ>hûõ)ÝÞ¼øë?ÿIùâäÉ“œ~ð.}_lºÝÙvðöâõçqn/¯?úñõgãÿO »“»£G¬æN"/ÊØ÷~û¿þlýï>{z±[>yy}v"‹ÅêêåÍ»²X=ýÞïÿÞé“e\#¿¼½|}½í_½¼º¹ºä÷gôóŸáãôò“>þ£õ—³O~öÍNügË'Ï›¡‰·Ã޽—ŠP›ôòú–t›XL^ºHš»O\V‹Ðxâ "øæ5‹$sh@|è¾;¬A8ªTvr7u­ÿuÀˆT½k:9ðx2?øÔ@T¹CPU'u@§ÓSEP¤X÷•4Ö>i㚯v7‰‘6A#±gË!;¥œÝ=„Àê9çéErš 6]‡ƒPv ÔûQ~é1yÛ*F$ &&‰yQS¸C DÄÌŠ»ëdŽA%ÈÕËZ§ 7*ÙJ¶Jü# äž1õäFx07x¨³Sõ?J=¬L3+MúU!޹®TÜ­º¥'š )€bŒÌ°ßu6³zãü ‡ƒL39T@B4w}þîûÏ×Ëo0Í©o,7³“6p¹ïÈôs ÿÛ/>úÙOn¯p2~rÙãÅKœ}pñé>žî[z…w—øá7Ïò¹Q.ÏÊlÕá¸O1_ÉÌ?ºþA÷ ¯WgÀŽñÓ áï°ü1ú1»‚nAäï­No?¼ ,°ÿ9î_£=ZÜîú×÷}|6¾$OÚv1êý/6Ir³Æ¾CI•O ø|ó㤟¾z•o?¿Ç.áÅgkÌÑ>ýö7?{^ò^Y¾”æ>÷Ïwù›ÕÌWC¿pëÖólÞ:‘Éî·ã°ÃÜ`†]uƒE@¼Ä{§àO´]ÊÉ£åó«WqlÆ7Þ_9h†æ¬±“Å'ù΂ÇÐ-—qÜ•»«½:Úv½ëV<šV(tÈ–‡lĈ€ !ÀÉPÔÉ4H5¹1MËo ¦üW½iÍ«R3ýïw«-Ð I@М1µrözäš!öØ("DB,VÄÌÜŽ"×\ƬÉ,×ÜÍZÏ$ÂŒb”Ýõ°'!wâÚ"–¡ŒÔÁ™‘`VPBÇý°7Œ‚À[4f«¥ws`s.Jîf>Âíh‰L®0S3e‚@ìÕíˆIJdzFNØR+H6P$ KIlêfªnW 0ìÓ£ö¡åÐÐQ¯B«Iµ )¬…d¨Â‰ÙÍŒ ™…(Ù8X#˜7è­ SNÉÆd`ᶉ­€‹•R˜§–\Ç¡H Jh8ÎÑÌ<¶&­RëÒRÔgâ WWclKŠ11ÔEx»¥E$‹Γ®Gõ*ŽbHÔwLNqWÜ7'×ybswr©Üž¯¿þ)&Úé—6‹Nµ½~x]Dx ȲQÄòdÙ-‚´EòMi,0±Ø„¶1„66˜|¶ØÜm™Ðƶ;¬XJI¼³Œ”(k@Œ±™5(0Íݪ31ñRЉrDÀGuE$"a‰Ü B#Ô±K\kÚDˆDB@·è CN³Vš¦¡2æœ,Á¢—bé–ÝÂ"Ù@М·ÝXÒ¦¿]ûÉùéÑîÙ“«×_¼þ§p3Wk»x´X ÖûíìþnøÅ'×N&ÒÌf¼ëãn×}ÎÉÜÀ©¾ZP]˜À*žþkøÇo&}²CU  R‚LCÃ]ˆÇ0Œê´^Î׳Õí7w7û-š -©›Ý]c!®ÏJ,£ C§¥5»-ýíö&çr"÷aÿ"§ÍU÷3M„fMÌ\vqì BªP##0‘gG‘©»¢Žâ €Õ¦«žÚ–~x«¹ê”>2k`5Êý0 Å6/æšXÏ÷  ( {6rNî/ûm8jÛMÊc~rþ”ïÎþâÏ>ú_þçÿ}dÎ[m>üËŸ~²»üÞ7οö³Ç¿|þÓ×½6öèÑ2í¯6KŸýó?úÁñ·ßû¸ùìþðùíÍùÿųæ÷?ûóO_æÏÏ¿ÿñøÏÇÛóáùýÕO¿°ËíþUzµß~y{óí?øîý‹?8ïaoÜǾlÃl±¹G_šÍn8œ£IÒmbºê_\n^]ß_ß{×ïØ3¸óRÅ; îV9×ÂÁ§$O5SÖY¹&uü žÆý'¨Õ=qìÃOãUàÏaµcd˜XHÕp^‡›¤p®{M«Í¯dlr›¾?9ŒÀÄÄÕï,Sá|%@=@YA‚©¯Ã`4€ùd¶óƒ¾õ kTJw #AH˜™|‚h×%ó„žéSDáí¦0û5 ë[rG âV…ˆ¦³?CÌ2–ÀÌx!ò1…€dB$nXº Èž~sSw~ˆS;¨ê|þЄT‘Ku22'&g"9ðÄÉmò?Y|܉¢{ÞNýšÍ Ùïr‰DSI¹Â.`7Ä1päX±HzÜçmó­£ãÕlYÒ˜@ñýÞ•ú_mß¹ý$]a±Gׇ¶´ùn÷Òoo,g;Nøg üÉwøƒoØí—Íëýv8Ââb y?öðñ˾†; ÇË>¡lîÃç÷¢»„|‰YŸ¢Â,@ ÷¹ éÑ žÓf› «=»´nÉrÞ—sáÄb^¨%_8áµCZHËͬm%Œi°«„tû,4QgÍ*v ÷×’¶cº¹N}ƒÑ¡ž‚yNŪès?&Ó=tO)9U'±&‡3LÎäeR'›ò}_ ù¯] ÿº—P¨B£šû˜}ÈP±T³kRE8xV¸xÑ¢n0hñQÙ80*)×íÀÅ%šqÉB̹˪t "…¸ ÐÀ"ˆáH `è-|E²–b‘L9™ƒÃ(Ã-ÀŸØXs@fær®¬'ñUB0r’š“‚JËâ eËnj£‘ eljjÍÌ5“È4¹yA\›—¦MŽ€Ý#8 $x p|Ð#%˜Ú„n+ÐA!΂ÀÞ ZÆ è L±p׈›‘2¬x&Q‰Ær¨#X…ÝMRö2ýjX`3„B[GõÁ³»e ÉÝ¡æ¦Ç€3×Dˆ…Z  hlâYêêË'ÙY@V›±Z݃•Tip‡U¶ú×Ñ?U·Ò!‹üV²ÈPQë"2/îndA ÂLLto=«6$ǘœòH-:anD8˜y©º¢{ÛÆ®£“ÓU†!kìÒoP‚{€´Ú¹XÊ=yîÓr™DP€g4"Aa´,A8Æ!¡‘âJÎ(Ab×ÄÅñ\šàβ§bšÍv×2ŽyȘ3rÑù|~r¶šG·÷H{bU A$çáêòµiÜÝîÅ0 `Üû=';[u]ʸ/ƒ²% ©„ŽÙÇa·Û&a_ n·ípIåëÚo‡£©¡H³µÂ ™Á¼!^ÆvÝÆãÀe¿ÒŸÏ«Ý0^nî4]l›Q‘´8^œ==›/Ú»aÓȬl /%íy£Ö7~ÝåÏs/­§1¡”dý`}ߤ ÔIŠ¢ž €N•Ÿä^÷>üô¯D»nVñªäp¶‡2 w!cÖ±ï%DÆb!°»•RÌ­ °¸³q×eõþrXñˆß~6û»öñîúñ»«“ùý ÏžyóWÿT7Ã÷üéÚf›~qy{/Í~ûþåÉûéøÇ4?k¿strÒ†“3º¸Ìaþéå—·»ϾIÿò¿û^úötûwQèñâçÛÅ‹M¹½‘×;9ôÞþðìÇwÃ'ûÛç ¢¥…Ó2ñåKNq¶<òûÍë{û¨\¼¿þîó¿øñ§÷ñÝÇÛp糋ùý7ZDZ͵u«dÍ\Tß:É€&?LîÎ>%\Ž×;6»~ Öë‰Mž3rr®05;t1Wnrý™)6Åf \a€éD…"T.y=û391M=|»¨.úò< lo@jT¦DÍ[Õ~~ç£~ÇUKS'ðT1dvØXªb.˛ܛ¹è«DÓ¥®a!¯eP$`›:!™Xdê°ˆ8 V‡V7v7‚C*Ük?#Õ ÜCµ,¨Ý2œ«æSoŒ©v‰jüZ‰àå0 q¨öŸ:iísŸ¸%z¸©êD+5“ðïrüÖ‹'ž·_Rˆˆ…ŒLÕ3 ÈÜ»êPè·ºœ§EwÛð§:nò9o¢_óÖrB¹½}­Ï‹¿ìw—!Ç-ÞWüóúüÉ·Ÿ¶ß9ÃqŽ(1mÂðé6½ÞØ »7+ÌØ^Übó]‹µáb ßÁ×àG¼}Ì~QBCå~Ö´¿ùù¾}©±¥gÍq8Ylér;ú¾àº ˜õŽÂâ¬kcÈ@jÃÀAÃRp,÷‹°ý²ÀVÐ9—Ñs<ÃzÄ'=LÃ~«»W£n˜Ÿ°r„ ®ìÄ…‰› |ÂìÁó¸#ÛèšÔ3 BeÌCHŒÑ{!o#E|¸±¸Xtm#¼X¼•2ˆ÷e¿-‘ ÇØ([q1#T²Ø4Y¶3’9»8Ò4=™ý ûWxäèMR¯*JÓÓÃ0”«¤fþ2ã>¹  5'Cp²Ãadn¦š‘ )ØH ÎFj!¼EA=õiáJXÂÄ3Š ã9H :bQ¶ð+ÈyhO».æÂÌÉkln0u€„ÖB¾Gm˜Lz<=xÝQÄ2™.“dSV§ºÙæïáT.%³)%÷*¿Œ X8:I©ÉŠØu&gv©ÔµÀ>GhÑ̨‹ÒÔ63…š·[Œ#Šœ¡¹X„4B-Qç´ŒÝ\–-l³±áy›º¼¿§Û-õ¹Q `sSWÿ€×.´*:s=€YQL ñL–ÁÉÉFŒ­3A 34˜“C8)[]“aªyEp õ˜\KÄA[½œÓ‹Îe’­˜Á­BPñõDôOV#¢‡z2¼éõ›-Ž’«3< 4,-/æ…Fˆ ±ˆ0ïJ“­ø˜ÜÌ4—d‰^JÎ)um"/—ËTƬi43Ä.†y´ŒÔg3K)¥<”‚¾OØzq%s"j£xÔ2âh¹f ÒE"˜g$³¬Öx(± iB˜…8šÑÎ6óõª·±ÇÁaÂ0ƒA=Ø|ÙŸ¯çÂß#ÆÅªY/çGí«—·©úí^{¬#è(ì¶E y°»»Ë£ Ìnâ°ÊŽŒ,÷šöJÎoÊ猪C|ñëÏÚ¿w+÷–Xit0û¡kÀ!ÄmàyÓ­ÛùQçe„D™u±kGèí8Ü—œ…ÝœT›™<::_=Z.O—J9o—‹=î‘÷Š~Ó¿Èé2éé,”çÍÅ TÅl{üЋSm¯R%†åúFµ·ç"™ß•«:%ؽ¾j¼¸ )C­˜'ÎËù¼$”TÊXK¬šçL|Ü·Ùß?þÆ…<ýôß}úE,þðçgÞÛþh¶xçütÿÅì£×ŸÙéûßú“x·õEoÖ†gßÏþ›gW³îUs·mF9óûñ6ßß,^¿÷ôô½§Í{ßY|Ø|¾ÙÞíšrºzÖ´CëŒÛÒln·ï¼¾,?ßÀ/Ÿ-»÷ÖŽÒ•08¶ýÎv–¯õóÿó‹ùe<æœó_üë>z½Ý­Žlýd³öÄÎa´,4rA1ÇЛžT7òz¾xËŽYW‡­M]Ÿ®Õ²ÅÌÎ`™Â< 9öÿª½í «#T BèÔEËdfrÔEoZ=Ï´L/øÚª2u1±ût°³>¼~·5“eoòoúަ ªƒîWsHµÜvª–¥©ºÐƒO33O!ihef0I•‰Üß*½¦ ¬÷ËÒÿj:>ioÔôf·EoAÿ.ŽŽ‘ W£}Ö_‡n~Åú™é@F}’õzè{5ÎgmIöÅåp ¹¬‹TÞüq‹÷<ÜAú1ÝHçäh¹—Ûç›ýX¢ì¡g8ÿñ:úÝÕ•½Ô.á8œè1íïÐn‡ù€‹¸ûNHχÙÑ“'¾xþüF_½2Zkî‡Ísx~„b(ƒáÞ‘Ì5ëX,Ï5ïhÖ‹*©p»X®ºöRîæs·ÈyoÝx¤?ŽØ÷Ø2ç}#zú‹˜+¢ÂDX”Û¦•&„ ­¯m\Ç=•=©6®`#MV ÁƱßÁûÆ.xìÄÇ«ÛÏ‹P@öˆÀˆpK)Å(I "!»qò ¸ éç€1qÅtð$»‚qHÇá׎C¿ÖN6;ëçž/ Ï7ðìNpu¨S!5¢H¤Î%Ô­•WçX‚«Â½PQ 6jÁ „#´34 Ø=l€í(1n„:’Eˆ§hV$ à(ź]7ƆàG2¿m€ ÑH©Á˜Ýœ¼…޹qÌ‘ pÒâVùÚÕêUŸÙõ!Ðyx‚L¯&Ciz*™À&Þ UE Ðr(Dg* lžÔ`ÎêD$D"Í!çhŽÐ-â|Ñtµ²ÒÝ ùͰ[”!€¶HŽ¢¥lV€PS…!v¡[ÍNOOä4Ú*mÓxµùjpxº—:„⪪Ü+ÃàJp°H`c?àv„¸¡xÒ®Z"Œ>,´´`tÝ€²R}ñsvŒ¦®.ÄËnÉr†•–‚Áy hmš&+SÜr²¦NBr©{?ÿz"úOíK¸M¯å¦í"†%e¤êQ‹­4¡Ð@CKèˆYÜ]UƒÔ=vö!õb4¤~,ã c±\JÖ2·ÍŒº0ÆÑG/I¡È­À7±(Òr›6„4È0kZ"‚˜ºæ¬)¥<O¾ ËÜç2–TJFf#$³…£îÑñù²•Ë/¿†a¾ˆ«Ug2  ‹íühÞ-[äÞ)w ÖG ibqì‡Á¦Òµm¿ßoËr1c&5Û÷Z6}nxu<›Ïçñ2m6Ãíý›ïw±dÀƒ¸˜ëáu€¶NËǯ-s¿ÍW ,ê®Yf!.BÓ’H6ôãjÞÊ|±KéußߎC‚{`öÛ]49>Z‡À÷ûÛnû\.fë´×4ËÞ—·ûçŽLãæuÛ™,âzÝ5QËy(Y‰À³z–¬ŠŸÕ\ ÁÌͧnl¢ ~ëˆöÖûõÁ4tàΰõ¦Y ³ÊÆhZÌæqu¼°¢yHûÍ8öêör{©}4?ûλhq÷óÝMèÏ›ÇíÏOáôüêò'ûÏ®CÎ/îŸßüõüÑêµßOùê“›ýè>¤8ÿrwG˜/wáhwâ+êõdv;Ûóõî\f‘ãåvxß=:¦ùbµ{tûúg7Ûáø•½{zü4<¦ô‹¿¾yµÇËOÿö³—··–âÑ8síþÍxùÑÍgßÞÞ9­r×ÂÛ<`´¼g…è.r‡}Õ©‹Cz*)­yT ÷¦¨ŒÿÊà 31³s%Lé¡9Çtÿªæ ©¸°Låo «Õ‰6y“ž¦ü4:ÔjãâWy4Àd ÊÁ®:µ¬³ IDAT"P½j„uü«TÊú%'ˆÕÊÄ*6iý€Õqn²ãO¯]öC#Ó¥šJ¿õýðCe-U½kb5Õi…ݫ㈙¤jŸVÁrÌ š–d€»ÑÁ_ç©ß™MIˆúÞpqx-´e¸`zìÄWà•¥]÷DPg³U²‚L× ì&éÜIëäü«¢·/Ë࢈AnEÕB±h±pиìàKʳ|ëeïaF]5ø¬{ÝܲÃ~¸Ï~ß³„ÅÙõó!r_AüV¼ò§?ß~÷îùÕÓ>.ç>Cñ´lp–NÏÍqÞ}k¾zÿ)àò©]s;oîOì…Þ]îxÖÙ1µOí÷–ûwíËn«9?{·•ðÞøbó꺷CÿÅ.—ä Ä œ,“%1ô6X. ät¶çnÅòFx/»2 `åY´››r÷eÙeh|·jÙÏãÑydÁÐãÅb"Kb¬Ã±ï´?³ø¤Y­ŽÚ†Ç€²»ÛÞÝmm„{Êùn°»½–R°›á¸VÄa <’cº–YÕͼF[8H­uVsA&r(©D\)2)@ªõÍûwGV2˜¿©„ž ƒLÿ¢8@—Œ×â´d9PX µ…tpT€ *|Ž ¹¨‘{Ë1‚çÀ)âcšñ¢S|²ƒÝCï¶0skŠ6 ó*4Ç[€`ê:³Ì æ„òˆºsïK"’CÓºç<ª&‡s [‡D®-k怒œj\É^ër¤*h©“@ «4L©}>@°C` ¢ â™D!†°³$Óä6"g¨[íÿavŠàÀ‰Ÿòé ÍÖÍrÛLîf¦d wÒ%ÁÞ1¸Â‹ DB!†ù|~v²zçéúý‹ð¨±õè²Ï»åfNwý~ÜŽaô!G€(i¬ ¬׊[°ú7PÐ6팻uX,xÅÒ^›XÂØçMn°O3"!%U¹ø "<»%ÏÉ4yÉÐ|(™T81%'&/æêf¢êeÂ0Õ‡qí‡ø:GôOx7ÿ–4ô–d„P+4Ô›fv4oŽ‚wjPe Mh]‡f$ÒlŬA²º{qc¯®ô£RÁ¶ßªE- „R*]‘îÂBv‰9â".ÕÙ¡’F´À²–1§2˜g¨mQæ )"Ò É‡œÅ~Üs éâœÕCl—óÅzfœúa3Œ›®‰|r ­åц›î#Ž»ùb~Œ ÙÓ}¹¿ÛŽ)xjøh)`9—a†Þ̈©G– ’;‰D_ËCÿ°ÍÞbOÉ V¸8Eâ`à¬nÕVMçM{ÛïîǾwCˆFÞÅö[ô^†.¥¤”hí²ÙínJÚ¸ˆ2z`S|nâJ{BÚ»k’jQê‘ê£NˆÜj‹ΜT"p( =¨“«Ë)¡‡éüW¡œ J3ŠAnšŠÒb6—õÉ\Zk¹‰ó ¬½¥4j²Ôhh“Ñlžc¼²çD1žã¸]gËcRdÊnÛöòˆŸÌžÌé·¸J/¾Ü¼ âËKîŽeI„2|K ›ðúÃÏ~ñoòÅû'§¿¿H:žìΞ>ýÎM~ôág?{=ðúÑÑÅÅQ¶íýç»__~NGç/¶å¶Ü~Þï|÷éO>y-˜=9z’|NùG»ñó"שËÏVËż›cnçh–ß4çЛ‰HDÜ+’›J‘¹)1“û¯ævÔó4K}÷²3étå•™‚:«B «È$E™‚¦°Pujó)±Ô¡¥âŸhj<˜™S "¸Q-–%{ТÈAZYÞp8Ùdåqƒ³»Ö.6'LÔÔ¸Z?HD§ª’ÍTy"ÍM²éô‹éׯWlB·á À ÎΤ¬Õï¬$µ3Öáì$ a#\É™RædÍ“‰U7<‡à»ÖB¤:¹ñ¡/>:øa"bSÿPý?â\%}gb¢·gWwP£«úé.órJõ *>HB6Ùý·ß:Õß‹=ÜìÄì°À ×ê¤dAIDŒŒh±lºÅr¤´Ý[SÓ¢A||´j7ûMÿ껄~®óÖ‡„‘2°Wì -¬¸ßÑ–¡aد­[=9nšAºùª…YyÒ—ý~7 ËÓÅ|nr}»ß¤°G)>æm×óåv‘¯åv#Ãf[¾ûíg'¿·¾ýÅõ.ËÍ@»E>ýæùvsÄÁÞŠÌÜcÁ=CŒÙ•;ÎQöltã¾ÁòY{ôÃsßòe3Üõ›îz¸ÖbõîòâûÏf-Ï_í>¼‰#¤@؉½V\Žì›NïæéžÆŽÉ,…hMcn¬4Ü_ß« æ`ƒÃ"Çr²jTœªOxò°RÊj0ƒŠiÎ¦ÎÆ¹)¹2Æš6’ö[Ÿ…[+b‚„Ï‹$¢ÛhÛ@Ç*`ëô™!‡‰¡‚¶în,¢ÂAL½¨ZÐጺ§³õ¹,–%ÀhtÝ‹]zz•ú×Ö÷È e o˜: ­{ÕOɵ t„|¢Íq–DD”€o•wà kh~ÛÎ4¦©¤ CMZ;üH”¡qÎnv@ÊP-8Sf›‰YÏÁH`ar™!«Õz+´Ü3s0§È¼DZ¬>2 nH"ËJ›Z\ÐjùÌb0`ÊÞÀf!y.–  *Œ1 ³H3›ÍNVϽ÷´{÷„qYöCÜ•<¬Æç ïî˜ …‘³ÃŒ\* >ŽÙØáB1ÄØtíŒæRâ M$Šî‘Þø]ٯˮC3 ÀˆÕ¼Ï¥jU³[qËžË`^ßEBTžGµÉ){1VròIB"ÐÔPÛ¾žˆþ©6Ì~ɳQ)Fî. Ž1,VËùz޹÷´_¬—ÞèlÙ®ËÆã–%ZŠå} B`U5³Lʉ!šªºA!ˆœÊX4¥½†Øê yÐh1„¦®àÙœ é j&æR˜’°qNÉ %k©›9‚DæàƒÅ„!‘B‡8·( L—×WwnÚMDŒ±mÛ0‹èºÙj¶Xuj¹ï7)§"–s ÞÎC»Zž*è~Û'¦Ù¼9?{F©á‘2§ÙÖ¶ÖXï³mÇÞ !ÝëЧqPSáz0ÔjÌždº¤¿s.ÒÿBnË%€›;Ž‘%‚#É<ȳãõlÖmœ7Ë£.BóPÌs‘®iŒò°ß–MV–ATò^_GhÃf ë4æ&…ÎÇR–‹R|LÞïLJfò|ä{kU„¦^ƒJyurcðÔŸ#‡ÖÆZÖ nS½Ì[–¯éÂD¤ «¯l's©¤ˆŠ5UÕâƒf¬V«ù¢ÍÜIšJ)ËYHqÿªí¤éœoéi<^qŒ»ÇÇÇ—Ãó›þõìézΖÇKÛݯËjVöûþzuòÅù;ïΚñEÖÝÐX8âY·K»{yý¯óÇ…üƒ™ÿþÉå‹ç?Ðïu?½øÙG¿øëŸ\oç]·Þvý/žÈü¿ÿán~ô%˜f.^–ñj×_§þ5ûöø‚ŽVÍ£áG/?»ÙÜþ͸ͧ-Ö‹X¾Ý¬ZîNG^ l—ÛÆ&‹òC§ßÄXæŽh*¹ªC΃âtjaf"Ô‰¨ºdèà]˜$‡)•S1qGÈÌȧŽú©lT›‰œˆUõ0—M¼ªªƒ˜1\ª'¤!1ehõ®ƒ( ­{ÀêE‡³›Â…&]™Å˜1µ¨fezÓf~ aVCÓ†åàš;¨^ojtø+j0kˆ=Rrf†³Qpòêô'aÔ¾öþÝn±ë±Ù^ Ç{K‚ŸÂ5ôûïŸ}ÿ¿êp–m6Øÿ|wÂæƒÕÅý‹Í½ gÏeµÛÒfc}iÁØnï_îvhÖr¼<¹y~sýøÉíâÝeäYXKœ£YîÂpyqN/ññëýõÉb{zÞ-Âiûw°}2”üi±~„Fµ]±²Ì÷Gq'Šl#a¾ÆÙwÖö/.î÷[¼ìvãXÒön?öŒÜââx?|Ðíwòü¦»ÅA¦F9¢ömÙÍmlÚë¸pqáÞI×p ±),÷°û™ìgݰj7½ÒÍÎrÉ…œËX†Í8ÞÃFt•AÅ,…AZ «+ŒªV[UÍ0þªCÝè+ö_½‰û寤„øÜt$Ú[IQf¹x9(@ÌDAÆ` šÉ™eêdbAë´D8 ÍE˜=«*H®{¶ÖG³ZÕÁqté •§æ7RÀµît¦àbåÂb‚{ÕÍÙ‹À=šÇf»•Í–c·%WUÜÅjÃTTsmÅöR`6ÅM!ÕoÌnSžš™›’r õE¤‡RˆºªÝ|_ý#«A‡‡~ÍΜnÎLfoI.jb1„$t1ÎB‘¬j»´g€5M*¥Üow׷׻봳¦å£r*¥8'I‡©d/m®'ì¶SðÆ;³B9íKÙäØD bæfîj–ÜÉ­˜7a3°»kÑ¢æÆBšÿ‡½wëµåÊîûþcŒ9gU­Ë¾û!Éf_Øjµ£–Yޱ‘ðƒyÉc€|’|—ÉSÀ %‚/IK–eHênwKì›<<<×}[kÕªª9ç#µöá­-»8iÜÄæ9$÷Z«ªæã?~¿8†eF Rš ÙE ëݶ¿öÁެOšÕ*uË(mâÛu×4©ìF·2ŸÄ¦±î^\múúòùÕ­åý;g'½M¯ž\>ùèñÙÛÑ¢%¢1@)ÊX°ë'ò$Aˆ,—Q³¡pqi„]Þ›³ñÉý×öóóïk@䇓-Ä›&ùP!ÉbÓFIÒpæ\‹L]h××—OC¢ºm¯Žû媊– ìqðaä øæ›-…!‘c¶ä1‘ø4ˉl¾s™9„œ˜]`lDdä6‚|J“Ÿß8ži žw`˜Ùì }ý‡qa‘ÞÌ|f›¼]Öš™æm$q‹nL$N"Ò‚fzž1 Nùd3)˜ÜŠ›AüðG ˼î옱Ós NÎä STÀ™DÝ€êPøI0ãü3JÑ›ŒÐ\KÈ\É€Äù°<` 1'§'öPÁD̦FBÄlp"Á\"Ì¥¢ƒÜ„%À…9ºÍ0½¹ŒšL€@¼ñyø?ŸHÙœ2 DÅQ€2—7³£Ö¬‚æDœÈ<¦mØ•ÈÕÌa`71}& Éä6óª?; "ÿ«ÜÚ”ÁIÌñ îœ àÄH+´÷äøözÝ…;Yâ¯àu“,…hSi‹€q‰G÷£ß8ÒgSÿá^.¯SJË$ã5åu‹úèøÖÑz<_¿û&þö›zôã.  ë”Jî^\º†|ï»g‘GdÅÄ›öxrjñkïÝKéæü“ŸžïÞÇêÁØ„³G5wR¼ºHïoýéP{ì´Ú曞›W–¸·©æ²MØ&§šñðÞíë²%ÆcìO¹7£kdCЭWÝizóu$ý•´úi?JÅÖ°ÌÝË¢¡&Ìò-!9™M3y²„öË[ mÛª)É8Ôq¿Ÿò4 Çš·¹œè‡ë26Óª¡@^ 6%O-%R¡˜·9 Š…BV‹S."”$äѸ¸ªiñª¨ŠZQ´Þ`@ï¦ØñWiFºumS©ƒ…êpfwdBTµˆKj–œ’$Nð¶Á¸s ¯”À-¤E\QZp³$ê%çÀ6±o1n€ ^©ˆ1‰(*ðÄîìì^@…e’€šlð½×‚jÐt#n;·–%x.ÈɰFd;¤‚|=ÌU]æ ÷ÀqcPµà%…cȱ§xhœèD4 <Xp¥ †³©@ &s*l®–-и$€Ø67Œæp-œE K D•g´«ƒ˜9·ÌË–W˰:‘¸¬}èsÝ Ó¦¡ÒÔ=3ÔÅ*Õ :hžçkÊ1ƒ[ 6Ðĺ¡1DvD§¤džIȘbŒ­µ m»ª“k®V`´"$A%3èÌ#ATJmgq"e¯¤ ļdËk5ÜíÆ40ŸvÂ/Õ ì—íDøÿÁÿ<½nº“ó좜bšU]s’až™{ƒcŒ—ÝòdÆ÷Ó~´ …—ËEŠË’1ôã8dUCAFQo,¶:Öh”éÞ»-L›ÍÕîzhíš%ïö‹ºåÙw[½ÞíÛ•NveHU¦1®ŸòtÌ´<=iÏZÝûéêäxÍåù°Ý{PI‹õ‘éåËW0ˆX ¬¹€NóÁģ6É¿¦ÃěՅ/5VÑFìÏ™l•ä]1eTR%„•¼6\Ô牽m‹wq×—«ñ*Þ'·–£oVí¶Ä©¯[iî¾|ºëÐuéÎù'O½}ªç=UˆÐ`ÍXJfCË9Ä|º\ZÉPTCÙîD¦Hˆb€ÍgP2ói*DDÂà›fÂÌnƆ¦”LQµZõ¹¯̬jó¿`‡“™ŒÝ‚©g×9‘Ä£†ý®Æ¤!N²ðåqóh}ùâü-»£§×ív —Þ¿:¿ý [Ü_| ý“‹Qhyv|çÞéÃý“ü᳟Ý^ûæ2OÛ2Ùø[ÿÙïÿ×W'÷Tóñ›þë¿÷»ÿì´õïýö|¹¿ü¨ä³[ïü½ÿæüŸÿÃïô?mVï><Ÿ¶?úøÉ'/Êz¥ò'¯Ý;«Ëæñ°-›ö­øÎož=úÞÙ‹i,ö/×ÿø¿ÿWß,q×Å_¿hÜyvùê-NööPÏîéJ†ãúaè†;ôìI™˜ÈȲ!fÈáU¬3§ß¨#w™yû5ÀîbÕÜ9Hé Ns)RàŪŽpoBKDZ­V3BŒ«¤¸››Ã#EPŠóá>;±;FµbVNNs®9O ± ZU«ÅÔº»Í¼BŠL‘È…¼ÔQØTUËóÀˆ¢’)ϺWbR™©™[ ˜Ï?—Ã%PbÕÈ17Ì#"F0êØf€½˜D¦ 4[ÍÝlÆ b3Ãf) %wáêfìUÜ„]àÁuŽÃ»X0åYs‡)·ŒFAªêžcãŽÑÑ›ð ª wá&Ä(:GÔ‰çÙ^ffØa(^Ko(…%p=8Œ\ýõž˜ƒ¹IMù/rWš'ÑÁà v L]j°í(åuר¿©·¿ÍaÁülß~8RÀÕßÀâðøŸN|ýncߎþ‹ÓëãO’?ùþs;¹ób3Töç—ý/ެíÆÍ)!.pô÷§÷W÷®öDZ)zçå˸¹@5`8íêˆývñª}ññÅŸŸc“ðÛÿ­< o_^Ã*þà÷^éÿs~||<¼¸úF·äÎ?Üó·/ÎÏíNíŽÓõ8v‹ÛASæ]Á.«UÛSlPN°[`§\¨Õ„}~þ<øéæ[ÿÑn‘þ¢¾º÷^ÿtÊwÑ?Ç~³­¼=}«{cc/÷Ÿ`A‚-ÆÆ´­v~Uw@vµäåiÇÝb,u3 {ól+Ž×¥—€³ã{¾(ÓªI<ßc²Ì —&¡á½¹Ô]MÙ™sc•¬ÅF­;Ef..VÁEÉG# d8ì€ð9–yãkž¯Á/œësØŠáJ˜ü‘Ÿhí®È*ú}ˆM­x ºÇÍÛÔÞ÷õ*€Ï©œ#?§þ)í&Ík‹”=@„ iöÂT$Å&5ãä5w¡®·¬:íFp ËW6XInñÄxMJy@¾,ØLzÁ^ÇÎh±LÌ<ú4^åkÄuBSʪ†Eiƒ1U0*¼:—YõmµQ0BG±’g3S§er)5îŽ([8šø8Ô óÝCEl«Ù îK»Ã,D½bfi $)¥ ˜^ËnÒý6··ââ4-[ç2Õý˜ë2\Ùø¢î®QFOÞ›BkcypÌõ¤+‹t­6aÈ:îb»¯»A_^ø°7Ë¥©”㾎Ì!°0ˆL¢{Ä\ÍÛœ–Q7$5æ}¶ª™¶…wMLDäœed$jWºØÖ©ÇPÝ*|„\8´çb- V V„e¡å˜?Zà(R²iºÔá"M=úĩbÁiÆ‚ˆÅANóÊ“¸5#úÿ?€ºùæP1Õׂ?]„8ŒÉÙ êdy,{„†ïßêËP´nû]™ré'ª72„YNš€à†:L¹L(Ž–³µ”$‡c É^]í÷^‹*]ל¬éø¸¨ÎV-%yÙ)–”ŒÀ72wwò:'Ü ¡j&Š$‚1™UÍey¼|prÿdÙÝ^®ÖmÚm¶ûÝE¯^žãÅ­ÕYÛyè·ýyÖEÞ [\/ÉÙ¨•N’ôûMØhKGŠ£z”f!ª0…sj"¼bšj˜Us#sfaÁþúWÔÿž«-@oª Tæöt·Æ8ÀÃöô G¸DGé»ßTÚžÜ=J·ùåþå'— …EM³–ý8æì#jÞª tGVhd;¥˜e¬fþüý.‡Åý®½8þÁ>|z}½'•‰Ç=»|¼Zë³»ôöòÖ7Wßø{ßîï=ýAÿ[µ;¾õÆ[ÿíƒÿêüï~ozU¶£¥r ½’D*ýæÑפec^ìØ3W55ž†”)—¤ên,Ä;Xg<¹y0ª` Pà ¥Ñê[•‰Ìi’ˆÝÄg!μ‡ÃLðY‰hþšADNЙÑM³ÐQÔÙY@óÚÈö픀¢Egܶ™9™ª‚`ª1’;ùÜ;šóc RÍܳ!šäL 6W M0…y5w'A@Ñ‘ˆ4³÷°³£ÂÔ]ÙM©ÎP\›+,d‡›“™¶ºglwpvÏð7—y=Jp°t~5„YÄ‚*e°BŒ’pœ'p‡•Q#¸Ò>ƒfpvÑ9H ì Lˆp)µ8æ.錟U¹ìJ„èÉňý ¯­U3xp àTˆ0³z¸‚ÜgÝ<æäáÄdÞpp#"qWDáuÑ;îø9ž·¿ÊâæM`ñ5+db´‚ &Æ•Á3¬nVéäÁ­öøÖæá1ʯÉíwïŽ/?xõ>âÙÔ~m9>ÜѲ^–——çûºË©ìvÅ@MÓ×Ë0á´mdÇ›÷óæNw_[¼!X=ûÙpþýgõ NNÏz÷Ñöýùò÷·CF=Æ{ëøºÅQ—Ê‹«!K½v#oBs!øÇ'GÙJÑÅD-¼Å~¸>ÏHm2xe§†#E( Ù@UÑìZBÃ)É:òäÃöÏ~ÿ<ݾ¸÷ŸÜ¹óÖi´ÚµúÖmüàgXî…“ÔûîÙFGm#òaî`õ]¤1¡ JŦGjÔ„iðšKÆúÝñT²æ‰Ê¤yž×eoÙÝK‘£VenyÄ:æ’Õ÷™÷èŠ,Ñ­ŽÚ“Å_L/*sæÊ¬£;¸¼~ÀÂ7$ÐCwž>—”ãqøóŸË 0МÚˆÕuçnTjðÑVœŽ¥¹çÍ›h޵3 U¡ý`åÚB‚Ld@Œf-qç1@˜Šî(kƒÛ2ÄQKe®pƒ4ÊN“+Š4°­93×jØø¸U÷T¼…ëýuX IDATJ  Ï®#«ZeÀm$4¤L&‚Àĉ¦èa‚ú¼5¤f^ƒ˜0p6 0¨R'& âˆà"Q6÷C]ØÝK%ͰÉm>å0Ìþ"Ãu¾?#ÌÈ@樰kß Œl^ŒJÙj©ßû…/1l0\” ̲´¶‹¡!K6ÅÚóT¤ì’n3ölU¦*›‘§jfUsuw ³Ì:æ ù>K\½N¨ Ÿ¬ZöÙF“œëµt-:‘¹—äÖkJµ»˜œ­²³8»²8éÌÝ& r\…õšîžØIò®òxçÒ2²ïu"%& =´DÁ©Â¢“á+ÖÜ/Õ”¾¸G4?TÌìf•Õ¹$oY,…¸ŽÓ>Ä´>jl(¼Ø8Õ¡Z‰‰S”65ÈnÙÝÍ…›¶å :•\½mRJbH‹uÛ5k«(×—€ç:’yŠMjÍC‹yUWœZ‹Qš˜B‚ÛèÇÝUQ̧ijÆ©ßJk!!8" Ldî«6ž­×wïÜ^7] ÊSÝ÷eèmQkÙn*3ZwÉN%¤1¶RFÝ]—~žœº°ØíË‚øå«Ý®š'ß»Ç]–‚‹i´:VÙ”ƒ˜9JùÂvýW_ÿN_Ê(¤ƒA¼RâymCGoá»ß¯=>èdûÁxþ£<^ÿðþ»ß e¢§#ɦ×ÉÕ3š;‰¥–êFlã8ŒM ®j¥”bóf–µ6̯[‡Êçæº8 ?E~ýÌýÂ77×ѧ‚¯×DéÃЖí°?î)«k¶úº[x÷­xï¬y¸ZúJÖכǻÝîjÅy©ÝiYÜ}êØ]¿¼Ò}àÛMwGë»1”£c&­oܾó;~ôÞ[é)¢—§Ï®žœÉº«ËçœMM÷lQü½ô­ï¼òÉ÷ÿâw7ù΃;ß=::¹Û,D¯^¦‹‹æÃoÿ滬~øªÒ‡Gñþ¦÷íå¥LåòÙõ…^¯—ÃÑbû¶Ýyx|½mÞ´ýéù…mÞl_ÞÿÄV»}Í$Ç&å8`x˜5us!Ê.7 v'23gµYBwqöß–g.™ÓŒòn›;ˆiø±øLt#'áÊEHˆxÖ‡Ù;}ÝT³ˆ¼Þ$™«eó 'f3"RWÂP¯î½Ev. ‚0ŒZnl„`Ù©¶smî3ÈàŸáܸ›Ïô5w7ŸÅsýÄdD s*æ¦ó²âlÊrÏ-¦Y®>—9®Ð 6ba°ð<" ¬³oÖí`Hru‡'G<€\ˆ#\˜pÏ&âü P€m&"ܬ@9ÔQ€ê6Á'„JäÄŸòF(ÀçžÃak‹_ß6ý€„ÙAÂé"ˆ°ð_‚O ü›N¸ÿE¾IR¨³ÕYa„º×êáZÜooØ­Å'“?}ñÖÝå£wN¯O÷oÞ; ß|5 Ûøé§“h’¿°xuYuêòEi •*·W|ÿö÷& 9î·GGŒë=¤{«†;çéúeÝ\á„Ìÿü'Äë‹~;º3„wß~ëýÝÇëûo]ùuéÀGÉs¤vÈÓ~Wt¯øÙøÊcø L×Ǹ<»FK’º-iÈb$×%ŽX¸X5š Í.VÚŒ(˜0•¾ÕIïœvOž ?þ‘÷o¾hNÚ[¥Y„“»Gå8î®&\_^ýñŸü‰~Pïì÷ßFA£„ì>h-Z4¾ô)ävÅ©M­4‡äe±Œ\P„‚ÔÈ l>­)V)JÍä®\Ý‹òáZ S6ŸÀ;´{=ñþ,JhR¬:Œ DN³/ìF¾ó¥UôøúfþÙöVÕJ³gäË‘ â.v”âšË6Oî<_^-|ÁÍ2t îZ,Zë¼”¼Ôi9ÉÒymÂgŠÂ ÆB%!*lWG5±E—ÉÏWæ“% c¨:Uäkß7 5°dGÒ^µ¸*Ìa(*…”<ÃAl  ͨYÊ P"PÔ äL#|DË'ƒÎq^ Ï€K1!fÆ™Œ#9±›’U¶Ì¡÷Ù…‘‰z`ïØ¬ª²1³Ì̓+@6W‚ÉQId`vAP˜M EÉjÅž•Õ³•yçuƒz…¼CQÓ h☠»:…a\nûÅÕ²u[a¢šÏ7—U§œKÞû‹]U!ÌâJ¬ÄL‘¥´Ax®ˆŠq&h1-ûÁÇ©86¨/thr“$EM±Š:UÓ«:nQ'ˆC@ˆ ŠZáw‚(Èa.θ½×½wÏouXÔiêêµøU˜ž}Qò³ ©;©}ºþJ3Êt¶|Uýr¶æçóÙá]# Do:œœt'gG.ewq^Æ¡êª[HaKäEâ Û—š§\Ô Ì Ęš£ÅÙ‚JÓÅÔ6p.Såä‹¶;Z®¶Ý¶iÛq;ìê®ö•™¦ÑÌbŒ!ò"¶mÛ6Mãîeʳ¼bÖŒ1XDŒ Ó0Qúa·:Y¬Ž3™$XH$ÁNVGAdw¹¹Ú¿˜¶½MZÆ2Ž#I”ІÀµÚfWJ»ÐÞ»uçäè´w哟>¿üdÏÆ!„ãÓ‘\÷»þEOmìµðf~|Ò-›Óáj³ÝöuÄЃ Q„ƒ¹ò—^䯾þ­™N„`6üAÌX­ð_þƒoýçÿéé{oñ£Û-žÿêþù?ú_.úé/^]“ž>>^¶ë«ýÖ>nVQÃ:µué‘9Pr²œ5e_Ò¤>Õ¢n4KW˜#GS}½wûúy Æ øü¯†-öEH£™½~оþ¾PP}îG¾a(ÏKQÌÖ¶åÇ¥Mq­S}Ì«¯¿±zÏþìOwž×§Çg¼\]Ó.'Z­ïð²·a=úíåÑùå‹îx±\ÉõÚ·Ûï|ûÛ÷[ÿ_on½·Ø×ÅÉrÑ MB®/†í‡Ö¶ºx§¤õš|å?¤ßø­ïÑópYC·>ó«í¥…r|7­ýŸåïs—ná¬jíJwçô'½1ùPÀy\‡Û¡ ‹ÒÂè+¶³ÁÃÔ~-„S0ìx¬ÔÖà…•HŒƒƒ`Óí˜æ" î^@(Àš ™¸Î©‘×3U:Ø ìПS3bv>´ä° ™¿çYj s×Ï6ìË7X‚ù/>‘÷™~æ‡v9¤W#tGÀqƒ‡‹å£ôàö>M¯†«Çxë7Oï¿yši²?ºï;¦ûïõÜÒx-O?Æõ+l¶f9êÈ]âë~ûF‡‡w×''!¼×®ßébëC¿J?xÁŸ\ÜÉ·cï<`ÐtõŠ®V·âÝwÒ¢`ß”¸¨]¨ Ô0 Ù*H-Tê,ÞBڽ̸N¡¶Řúk»¬Z&¿ J]áë|lÐI×hP·@AÒI›d=tg°žýE¹Ëwuá2lî­ö—[»<××ׯðãaÅÈ AɤÐ-ë±#öÓÂ{¶í°Å°âóÕ¡S¦Z×½ØÔ0Å ð:æe×Y) µcn„­~«=Áœ'ÐÈÕ§k?¿¸žèº7 r5Õ™gâ`†ØŠ""Øièsóã E‘ª„ZŸSó¼{Ô„ƒìˆnˆaj Ir "qž“Š šG³~ìiAÄ¡I$RJ«œ@ ßbÚY‘#*"!8Ya"m;8A30@y‡iO¾%ƒXqÕH "˜·Ô`$%+\'Ô$yŒH)÷\ö(ê€RÝ” 09Ñ̯›°ÄXªŽÅ¬Ge25J@ *ì;«[÷Þu‚Uhpž3wîT`^ÜUDáæ &sw„ájhríKi \¡#´‚÷ÐVa€±Y4<öu¢í¦}ÙEâîºFѾ‡~Ü ûín;î7Ó4hD+MWJ&8› °¡ã˜ÀDà …y‚N°Éò3ЕäDm f×’gÔ°xeU…%‚9‰Š+-¼½»wŽî~÷Ýî|©ÃÔL¯lÿ¢hÚ*´Ùó`ªõæ†3gbu«`ðW3¢_ŽM(ûÌ>®ß‹fpcƳ"¤ÀÁ©ñØ!uèTA®@±aµ>f˨Bj8QÑM÷u¨Fª^Ó¶yZ¡]®ŽW«åzQkÝïÇ2•àU[U‡MJÔZ‘Ë0£ÝSB •cÛµír¹dæ¾ïÇ<Q“ÌyúäÒ4¥ÖZ+†apØ¢‹¬Ãó‰k·HÒU‡Ín/7¯®û xÅ *Z·M—¬V‡ ^k³M»p)’äälyõj³¹Øu‰²ZïûbýT+Iis¦©¯„Ióoòä»-êËBþÌÌý 9ç¯GùGóõ^³_LHŒÕßýÕ·ßý¸üßøÆ“O¾N=½,_mŸoÆ:MÔ¦kNm´uөצ‹Eê÷»â©Ö¼Ý÷ÆáõSÐ$†ã4M¸¤Ü°üõ_ñ…ñ—çBŸOÐùg´_øÝ/ iÍ©(éì”y_#JX¥Åæ'{<ÊÔܦ´¬ì~»ç¿8hŽP¼CÎêõß̸Ã[ ï,—·sjôL9i>œ-ôìVÜã˜Tý¨œÞ¦ó;~uœƒiÿL·O0^ ïgò^ãŽìE ^·Ñ}ãxxh—q«RåtÕ?ÛÙOªž? pF×`;¡ÜZ¯éÕ˜Ï÷oß;m_Ỿ¦¯6õ͹ÓU)ÓD¥0Y #¤Å¢8ñ6sÃP0‹V›dBûª[Õ _ZI(k,o·Ë3n¬Â‚êó‹æýœ (5²X>yñ!PápE'•3ÖųéåÓ~E t ß9;9Í‹«]î1"#8IBˆMÒ®‘%´Õ—íØ7Z1UÓ›¡¨àH-(„"@ã~èm[q Æ„Юê).¨qãVCSx?H.„i„µ‘,UwSã /&‹Ï3J»!3Þè€?½-¶óõéÛ?Ï3‡“8G£Ö¬C"› ó&É„¨°‰à0C1Ï‚Òk¼Þ$D¢y*ëS†¸!(RBÛa]Vh[¬Gäò…oÊ“dL¸’™K„ÜAZáänV÷ð9kk^ÌmÔГµzND9—ÑÇãy@Q˜““{˜õ`ö¥œar0¯’ ¨¼V­Ù‘-s1õuç:ŠÜì ž5^`^Áu,›P@…ˆ°ÙÞ‹ #T‰jÀhu0­®s©Æî­¹”í«ë4TM 6UÛ/•±ßî{'Íf•U¨Îè@tN. Š-$€ˆ¨8 {0êQ@ö-göèÍ‚!Và RDà@&¤®Ùë¤Ò“+Ô‰5PeDz¬nSûFjßiév F]4Z‚öW‘µÚTå3½Q–¸?5#ú%HÊýÜC¹š2}úx‘€¥Yˆtnœ‡Ü_÷>÷%B‹¦M«Õ‚*éÞÍ,‘‹®vÎKTB-㤰}õ4,ŽW)-„ÒTj‹uë¸¹Ü ƒUGjÑ­‚™…l0´I–í"„cÙ8}ßÓØ¶mlR±âfbö”R­VÕÜŒ3îØÕêT@%À™B-CN$U\)Éce¢+Š‚$ÄÔ‚1”ñz¯Ù®T¦;'·CË¡ƒ ¶/›˜…‡&¶iu\vû~³¹|9Œýùn3í·ÙòÍ^ êµj8,[¶yùU1ôo?‘D¨7«nD 0¾÷k·¿ó«oÜ:yn^ ö±†ö»ßýûw¾‰´¬¶øý?üÉÿüsqpëÖâ¬Ikcך7v”¶Y½¼«¢šÏ“ b‚Q5…‚„oúÞ_œí¼>`½.‡^—@¯Ÿ£Ÿýõ/×EøË=TdN6£×æfä¼JDµžCBò £l_õ¶ÃhË»ØWĺCi‡KM×ír‹ —WE§|´hÎ׋WÏÎ1."uBÿäÀïÛÓ—O.®7/_å¿ów~ëîÛ·Ÿ=쌶<îl;–ýî/Æ?:?[Üòeüøêã?É{íx¸yÎô¿¿øÕwºãf¥ë¯Ÿ¼ýøGý?úßþÅÿõÏl{ܻǫÓ{·ÝîQ×]<²›£+¿¶„Òí–mÉöã Á0€Síh>ØÌû.sJÏgRƒ@â^È…àDN1&¸Â®njʬLˆÁ2‡Óæ¹Qar"sfäº0‘ÏzW83‹º‚ !¥¶!gŸ˜™0÷ /fêTŒÊM&€ÏÞz½JD|ð¨‚$yç`›³ÑÁ¾¡Us×¥nFìî®U¢šLÝ5Ø|xdž³bÆd‡ä‰{Р$t“'âyëªÙ¼üWwwŒª7ˆH%®LÅ1I¬ B2ëhyæýÎ%é,¦r"&ؼÅdÎÌäð:hþÍCº®Nôy˜œ}yFtƒžûEoAFŸßAbF0<¸Û¼ÉÝ7–§÷›ÐÒ>øv GÙé<[ºu|z9m_ ÛîaÊ·2Ðërõþ`/vÁ 6E‰}Ù/RésenÃêѽ¾}i>.ºÉ»‡ï½mßÿ¸>¹vÂí7€w‰ö>9öS^ºÔËý¢Køñøkúƒóáû½=GÝ• q”0:ÌÁÍT=… DhPĉ¬aD²1TµŠZ15˜Ž(>hî¼³êÞXië[\O€3D¶ú»o?xŠ'%ÛÚšÕNh³ÑgÛE%ž¬Zq|ûöw—åñ‡þñCl27gp#’Aã”sFM–½r lÍ--(膌Èè’0K ‰g˕Օaä•-)²»OŒ½ÕZ-°¯"K5¬e"ìsõAÕŠ›:²ÃÃóm†3ÞÜ—ç7öuÂù52ôç.ˆE5)³Kƒ( ‡ sΊLÞ[1°rôÇPQ Ö! ±$†´hfLîàSFÙ#Op'm¹M¡]R·°®Ñ ÷qƒíèýäjÈʦÂT! WiI—!·¬„êLÀ*òX9 SöÁæµxP+´VRurõySì󢻂Ë֊2zÍÈì>Tjà­rƒ`4Ë0gŽ,dÔ $ ΤV›µÏvQ¨Í]PuG#Lp¨*¨Â#,ˆœµd/Å‹¢Î‘Ý™SØÉ¹VËûaš³VÄHÝ"vˆ—èǼÛåRórD861hVw0ÄÕ@ šåš‡Á˜´NÊ(!RJ‹Ú»<•~3l¯{WÈÓ·›})+¬n5ëåZKµbQB’ó:–\§\ÆœóT'…:S53³)çRÔÌœâDîQÜuÌ ÁÌ)’PI¤jT¹å–WĪê¡ibÛ›ˆái·Ûå^·Òvs ©½}çUì.û«gû©öc1õ*"!D‘HFã~̃m7yغ*ÏlE>Fæ™;}–û¾¢’c@S£•”$ß{ÛÕn‡@f´e´[Ó­N‡MˆÂ±VÍ‘Úe{+†3 в‘–Z&óeß÷J2s‚»›ª»3ó<Ò2ß…A‡½‘×ë?ÎA¾PçÌ·úùQú…ÙÑ—ÇG_NÙ}ùb|íÎ`V$&ëåí©!ßn.sî}çø;ßýzÓÙÿð_?}z\èÕõõnßOh8áȧ·W§1ØãáC?É.×ø‹Ç¸üñGo7òÓ·Þ wêãŸ]ýß=2ž®Ð-·:]ûcØ×ÅËOÒ³'Ô¿ºØ^MWe·ÝMGrOÆ&?—ñrõøbºP^ÝkÈöÿüÕþñ?ûáŸ>‘åý7ßøZzóWßà ½>Ø~\Æ‹OÎO­9ÅqÕ¥ûú´mUHìW†ÃŒc56w73!°0±8;‘“+ëhª.. 7V”@îL$ç»–3f¼FäðêÕÌÈ…Ì0ÌœHˆÙ]ÜÜ݈XfêôÀ`4KsÙ DH˜˜Ý³0Uf…»±™9 ó‚¨‚˜xîB;sœoêD’ "!ˆ“é¼ÃJìŽêVÜ P\*Su&+2Ç÷xö{ð¼¡äNjdwv B!ä¬ÚÁ v°VrägUë åШŠ;QuöÃGŸªCÜ­šW‡:™× ‘3Dàˆç™9@êf옫œŠCÁ³Uî% q2q!.àŠ™HŽÈAì•‹“1Ñ Ü'óy´GDL<‡Iç¹-3ˆ±FIFæ_$ßM¢¤_¤(âÀf¢!:Î_L¦%®šesïÝÑ´Z"ܯó‡Ï>\<ëwmñί,Æ&7ݲ>ž¶|_"õ1 ¥Oënwu}L] @-yµHµkTdr꫼µºÛÓfÂþäþ‚ÞYàWbì?ê7˜žîÞó;¼ßÕ?¿Ü퇓Çë¿xæÃ7(Š©«õ¤ÉKâäµ)6èvE‡^Ç•‘ò®,³­*Z‡ö ù”Ê}¶˜îÕ}*/^z‚¶¢mrHÙ},êˆÝ0½Ü<Ï?y~ü/1=…F!`˜°Ù·âbš ƒˆRvqNÇýE]µdo VàQ5jÃ䨎5•©]3˜¥Žãz1/M1*5ë4žJœ*eªƒQeŸÈGÔ 6‰ƒ© Ü´yàL:¹ŽfÙjê|šÏwsW= íÓ÷÷u8îõÍüçö­ ΉPÍj…PhÑ  ÑV”zŸ„eOV¹ö´¹¨Û FHƒ¦õ\G&d25ãB”ƒ3¼ |LñÌ+¬hˆh‹^¬î¨±¼˜+W“âJšÖÑ/Cj™£{"#ÀÆ l¨æ¹“«:ŠóÔZ1[ïH«[uc‡À§0ws ìDÕ2zGèÄæ®aє耩 Ä1JVˆ&5…'…ƒŠ++\gÄŸ×eu „(,ÆÑ% ³) î¦7Í+g&æ~"ÇΨ!WgaÞ-E‹¹˜€…Ý´Âvf‡Y=Œš‰…Ø¥“²Õ`lv 1êÖhVÔ…åB9HÍ̲JtL¤^af¦nj}±mÅÕ”_Jî8 Õ^|ßPi¢…H±I&Å’5.0‰äðáüЬðËÐ…ÿùû¤7ÖDX£4MjW­Å‚‰r… h[ M$e´ó——çbõÿeïM~,K²3¿ïœcf÷Þ7¸{¸Ç˜CeVeU‘,NMHTK­ÝTo%¤•þ/-µÓJ -ÔjBƒM‡jV‘Åbeå>¾éÞkfç-ìydVf6' A6wáx þÞ‹{Íìœó}¿¯¸{µL„ 6TƒIiˆC¿èÒ2I_¦2îæííjä<¦Qpú°?{ô`Ñóa¶\Ý@ó˜o®¯½~¾ÙQ)e¿9Ð8ŽólGWúýA3u7“@‹Ô§>t)@j·J9Oyšl®‘cJCpR8¹X Ë^QÇýv³Ûæ2±ÆÃ•îF¾8¹DÝ÷Ûº™0— )g5Ô™ç)çɪÂÔ¡eÒ:7¬BˆB¸ùö¿1ýíîN'QJÞ@40m‰×ï¼.Χ‚Õ¹ ÏÂzYP7·Ÿ<<}àûƒÚüðü¢æÕf³xùr;òbˆ§y¿3ÑcÑ"…ÀZ«šA’¢ˆ´ùWwÄ/ú>:Έ>·}IJ÷¥?ÿ׉¼©Þý˜…Â+¡ìÆÛP>?³w~ýñ?ýo~õ×~ëüîðòô7O^í÷êSœÆþñéE: ºÜíõúÙúH·Ÿ½$ÉO¿-ÿüø/ËÅÝeÞþÉ/ÿÿüøçÿRÏüÕÛÏžü÷ÿÝeœîÂõÉÙz w>ù",ùþC~ÿ®>ûÑÝ·ÞøVÝÞæz\Z1º IDATèdaS½yþjŸüúÿÙå'ÔÿËýi?Z÷Ég/NË[¿ñÞ·>œobïOß½7‡“úò*N;ž^æ„¥KgéÁÍ­-å¬óÅj8Ýé>¬’ÃûXQ̬VƒjÆ4…(`‡8€W*NŠÆëv7wñèµù†ØàF÷Ø##7ªpW 1ȕɎȄûôOw3#v›ª»;^J\)¹I ù˜²ã€¢æyjL4?öXj±DÂÀî`5ÀÍ+„™0׬ȮՑݑêV@…¤’˜¸”:;::–ÛÞ²cý^^o2œÉÄ=¤žÍÝ›¯ÜZwôhŠ"xh©sÖæV0/ gbiPV͉š ÑjdFBì÷ö*¯Ú„a&Ä@5R÷ÚÊ!¹U´qTÍ¡)å ”ÝK“Æ…Ø™ØÉÛe½Ð|>jÐÓÖy`p#nàÿ+Xú;Žä íÉU"O„hèKÃBšKñt‚ïþ“óÕòä/?ûñûŽõþ£—;ß8úðp`[Æ‹æŸÚÕC2µC·8Õ[\Ýo¬±÷ˆºå·×/ËåëëÍOÿð#ùß?ã!†øð¤{罇Ÿ]ýäwoߨûíK·«½g\ýô³Ý."æ6†Û$û¡Ï%ŸN8o9l#ÝMõÒæÝ8åq<­c®ù6SÅÑ 8 ”èÝÒ‹ÜÍa*u yý3¬Wa™òþ÷žáô¿øöâ;gãåÎò'q}È/1í€’Ø è:­(š#bPwT÷1O“32ðèín“JŽ”ƒÔ$’Bbq¢›»íìËH!äqb²ußqÇû¼1£y<Ø|‚¸Kuš°HQ+ÏJpŒð¨F¦u»ˈÃ~š&Ô3 °8gwï7? c¿xW¼.ŠÚÚñÕÞVk¸(AÖ9µŠ<@%À \‘'èÖŠcÒÂåªn6ºŸ¡„´u¡ë(ÁÅȘˆ d‹&A½',H–艹ºuH˰HNZ *u„E”…È@Üsèˆ"ܸ^Õ²«›S *3­]àÂÄpsW¨»3ÌeÜšPPqÊ(“•y/ 3Ïj8¸$„Àˆ„£G)f¸f¯GŒEk\ø±"‚§žx°ÀƤ §ŽB uWGK>e'3¦`Ô‘ô“¨Íû0,Å áS­"JIR„ÈBÓÕê®%ocp'R‡2àHÎÕL*%F4°ON Š —•GRó exIýÖ³av5ÔâÕ­ìiÚî/ŸwXÄQ¬Lts#w»n7•±ö$…Ä[·ÊpŸA¤ µû ë£kùþFüªìä›ëß]Mä_ˆ‰$j"!«µÂ1b½NëÓÕÙƒõb½˜|žò¼Znƒ<”IÙuƒ]†MV!Ü÷}dÑ\Ê!cFž-†4„3bŠÌa¿Ýv‡Íöî°ÝÍ{ÂÐɺ—™Ê¾‚ezôè"„÷ãÐ÷‡»Ýn·»¹)F-sE¤ë:4ך[×Ç ÐuQóœ© i\ÆE×Çž¡uó8M1„e·U'ŠïÇãÐgŸû>Þín²MϾµê‡!k'{òøÍëWŸvËxþè4Ê~¿©yb’ÐuIŒ{#½»»»¾:ì7ÍLVXع”oM€*¡×§ü/N9üبýwûs¿î›±b³š·Ä2¨Ö$åÍgxpv™ç=êêB…h¶kJ¥Ìåñf³Ë³ÎSýè£çó(nÔEH´°›ç?üyŒñî0Gˆ‚©ª™•Rj­-Í“‰Žt8sõ úù è5qîþ³úœ ðšHÖÞTÎ…¾‚ptGŒá‹¾£û_…àææÙ  “ n}Oûñz:xLàGqý½7?Ð?äó€þixYö®¯fDøÆƒwž>^ÇÅ£<ø³ñ¿{öÿÛïÍç/Îì?]=x&çÿë‡×g»þ=ùôÑW>ÿñ?ûðÏÏWéâÑ“Þ-Œ‡Û?¾Ë¿Ô÷Áâå'‡-S:é–?úÙ§þð—Ï.¾·¸Þ~ò›O¾gûW?úù(Ý„Û[5¼Íë·zæ®[ß\oý…Ý}|ÇŸåë|锺Êô‰¦Õåö!àRÇ‹3ÏØi©dt<™+Ì,çI-»RSŒ‰HH’NÚù´ÛÏíQo$¸P054à5ɱËk(P=žmTAÂÄX)SW­-{”7Ë1$@ÚpB]ALXÐöc è¥Ë*ª¥zUç–$Á!˜¡•µýsÕIB ó½9!@DÕJ #ƒÙ@px1ªÄ ?ÐRš8tbêîjjð†õw «U®³“QÁÅ!"‰حΜº¡ë§ýlV'ëi;F¡HF5«ju#bs2H.ÍPDNL f"!GPRvW‡U°2 ƒTU}V«ÂÆ +ÙIa\¡ÍyDdBÔ5º»*D–c|]4¶Çíþ‘7…"ar†KK"¶R«VF /úÅäàÐlH_;éù[nŒmhÖk<º“¸÷ð…äÙùr6c‡~¥8ëàW*~ƒÞûÍ7¿Qö¯ÓþÉǼÂó?ºyãwÞÝ2¥O¹~Wð ÔÛo¯\œ­æq·Ηƒ¿šéjX<êëv]NnþìerÎf¯^lèi\ßíVo?«¯ÆÅêöÕû9¹,‹Ëëí>ãÕ5ô9âƒ-äüo=|.ç³…IIµ®³gƒÝ¢b­˜næ®#¼"%¬W”ÅSd_ûÞ²ÛÖØ¾K¡ž÷:Ó›¹Ó0û²~h7õÍAÞ]œ¼sð˜6˜€‡KîûÞ³^=ñ$‚'çj 9xIá„ bÄX汇 ' [w%ðÎt*µ¤Žr<ì‹m'LÐ1Ï›i•ú‡êÉe{ç›[”Œy†)V<¢¨gõ2q؛ޖyÞWÛƒ2ª¢Œ0[mHáÐ,.-Ǭ•= oCÄkVW·Ôõ^µTw«Å\ÌE¡…P™2Û 3²¯Ðˆ®çظ‰v-P´Hlƒ0ƒÈ9˜9Ì]{þ\¡µõ^dMqYyèXzé(†™ý²Â솼ƒ—un¼Š‹TIªT!3(ê>ZÝ3©tLD.^%u,°* T`.:·dn«,œÙê›PGÒUá\4š (šEøá”Ý)&­s™'ô!&I€‘úËÄ´ðânÕó2Šm÷—?ý™ú¾;ï×V=Cî¶öü%^\§ë<_RPDUq&‰j^fãfw·oòˆþþOÀ¿°ÜŸÏT„ FŒ¾§d¥ÌãL‡ ƒÎæ÷ª€q³çwWë5N¡;…ö%w»t6zŸBâoýò›ù_½šoó)-që·~¦“ïÿà;>çó7|ÿ·ß*«ÍÆ>Œýí䔟¾Ùû—ð½·/~ý?xCúð£¿øôy~ñÙ^¼óÖy¹œ/·§èûé­u÷Öð óŸzsU® ëw¿ÿÆï=rQ§vv–º»Ýb.N×ÝÙÐzÿZnxϧ×=ËNûsXÊ”§Ì5/¯}ÚÕ*Y‡Âäò_.œû1„ UêXò4ëTPj1¸›˜:‘Pt‚€rKr˜¹‰¹K;Öì.S3wR„Û|ˆH¢ ÇcP›<º9HI%GmQÕN•Î{Ü)»ÃHœ˜X¤Éò85r7XÙa$DLbU‰™‰ÌmgTs×õ9A¼1ÐÙUËàGÄya(™ȤFP#u5˜‘ƒ9 L>}Q=b¸ýµ¿Ý™ÝÜø^úÅ v€È݈‚K‹\òV±rpCdŠ)H' áê_YGþŽ ‚q3@", Áº³%WUwçú‹w°s\]ÜLw/ó^9€xÓu×Éw8üôã0Áš¤ò1#¢,š«&à³›Q~úÉîÍ•¾käîƒçWÞÜmM÷8ü\§þåÛï<\=ÍOûÇ»|o³n<ÉfCa|¼GŽødBØgÌVc—=Ís-ì‰i†KN³†¾÷®pÒ²"ï¼ë@ßæùý z1;Kq-è–XIWâÝOgpk¿¨'½\¬ûGûr1b‚ãlû»ýr»ˆƒa0D'1€ FÁiѼ@Ž¥u=`¼¨ÜönPåЯ$ ˆs*4*Æl£òÝö{O¿ŒnC|É7ªøDÒe¤Fä4C-®µ%Õ‰AÁàH‘ ¡@+UkyÜ#·‰Ž!†_æåø/¢ç¾"i¶¦Ͱ…È"dêV+—Ì\ °6K®#• k&E ÐÎ4Y%&p2Ô +nÙ´BUµx=èÔ—y`À¤õÒv¯l¿…N bŠtle·‘Qã;šW&u?:ø"ŠÎê(,$¬8uÎâ^Ü•i 9[Óó8g÷Cñ½»œ@(n (áø»LѨ“¸–nPŠJL& ƒ°dvôíô¨h+N›tîh’%xZ²,)œr:£´DH’˜dg¥zØCvZÊœÒìK§%â1€:¢N^f£=ltug6®.ji<ªûlÕaª* ì:{™Í&Ò –a@IÃÜw±«›v#cVnë=´ÁL+x@P ÔRvSy9ûÌ×Ó~8ð`¥!ÊaÂÍm¸ÚñÎPœ+¢’¸D´W º’·o*¢¹{²0ÝÇON"ºŽ»!ë<9Ú\¥¨WÓJT.>sµœ÷¨0Œc–’„` s!ºQ;9k±Ã~Ún'v /}¢yÕ’aˆ‚íÎãPjÖ2•ÃfÌž§ýÁf€0ú»®w£¬ ³jµ@""BÌÜ-ºnÑ-–])#qíz!¶\FW‹1‹ÓZ|îû´>Y¬ÖIBNO-ÕGWˆ|˜öýBÖ'`¶2ç<Žã8ß]Þ K;Y®×¾c è†(’º8˜Š™•9— «¸Èùë—ŽxúÊˆè €¿o®¯»” ÑJdg´¶ U [ì.1½¤sþÝ·°|ùG?Žoûâô„+]>ß½ød÷üùÍvÏ»]2Ï!„œ÷îM[Ùò!$!¤±ŽÊ j‘4Ǿ0·ô›þu  V3Y"…ÁÝÊ!|ž8tì54Šýëýõ^‰¯­˜ØÛJ wX¹¶Ý•€~ ذÙÀ±”ø°ïëN^éâââ£Óý ÍúU"Âf÷(?š?úüÏ.ùÅoý×ßMçóYØÍ¨)~º:{'OÎûÕR‚žðwßíkžž tR·e{·¹>»Žëôüêf//}Ý¿ñîw<þÍ7«íA»ëWÓév¾ÉÆN»åDê&0PÛ ÕØ Fˆ$»3#29ÔÕª¢æ g¨á˜Ë …ˆ(630Ð"Q³S`u… ÂÝ )Dh6j¼j§¦ö3ƒL55ØQärôÑ8DÄЪGÁ¹jM}Ç!º‰AÀäîa¦¥*“P[áUµq&œŽúÁ¶~á8Ïá–nLYÎê¹’JûK¡‚ŒL Æ^‰ÈœÍª›9Ì\Áb ¹;B´‰DkÆ=ôÎÍ™®á»Ûÿù˜ êF&ìDÆæˆŽŽ(…Ðq¢b‡×¼~ÿJ!ä€óß|H¯[9ÖmæÄ@÷lËÄ«?¹8RX>¿YŸ¯x¹[¼=ÜžY®.¯æý8øbõàbÆôñͧ¿;]^^o>€ʃ°+ ¡ŸÐM5›Ãä=ƈç3¯¯®ª¾$ð2Å«`õ)zƒ‚t…Ç·®áîé~ØÞÕºQ"¡õà8&ÃÁÁ;nëRoKVó»Ì³LJ Â+—s¯œºCŸö«¼_)¯½_øGÙ›qž‡°|tnQ溟âÔ½‹R$ç­² ýÌ}\ÎM8d`>`÷êfý*Èn^¤B="³£õtbè{XçÌ_Ìg;`ò-¦¥QæÀ•»í~¯ê¨ %¯>Mu»­»>Ü%ír¾›Ë,2.¡ià“³——WŹ(—l6i˜ër®Ñ°3x!åÖ!)z4ÃÛí&‡_uù1¬èk*¢Ö;+ÐÙJ&¡‡Äp/ns¦†CTƒOlòJ‰‚C‚:£¸z…»ÛDuô’­V¸+®[¡`»ÓÁË×ØÝ‘œ³§®&j¨ÐŠR0c±ruÏn­Ð28@2 ,).\:' Q†¸Xkþ Øg-$Ft„ÐÞ®B[:²:5Nº°$ÊxâƒÐ­bè3‰ÃªO¨óB^¡õgžÄ™Íùq‹sâ /ä cøà48¯%œ…~.BÜajK“%Âá€*p¢ÓÚùà Ë™0gl'h6É'B`E Â8¢ÿ j°©j¡ª¦Øì%Ã2ÛLVܲ·ñ ØA”ÙG¶±#+bw3µ:º£"ABPÏVëlÙhO‡Ë¯’¬Wc,û™32â$TL’S³c†5-põƵûæúûVI}©rTz*–«pv~–:ž¦ý4JQîdXS™Ë.ïZc{‘–%bgs6„ Œ“M6ÓZ™˜C`eVDÆ2-ÖîãXU]ˆD"¬Ô±îï‡ía{· .eŸ­ }èSèÍ :e­jVk­ZCÃ00£i<Í s”D}—†Ug–ç»í8fÎÓòäl½^',Vƒ 1S¤«ÑF¥˜í[Uí»¾Îå°)T}) m¯7Œ} ~rº<ÛÎŒ Eæ9—Ùö»yË<¡L÷P?f§7Éûý×㪊o*¡¯;‚|]OÎá³…¢êˆí¬[a{üÞÿ¾ÿ§¿TÞyöml–ùùá“?¹+¯ø{¿öÌc¸ÍÐU”b ×ÉÆzX­ÒÙàsÉ ÉSñŠ>uÛ:ë ¢† nÉ)µÖÏ5rG$!á+|í׊ßð‹Ä…–ßùµØ£Ï-}jμòQgÝß=¸óõêtÚí¶;M»ýg?ñ7éaè²Îüp»“n¥›ì¶ã˜_õ›0 O<¬Â‚)ªúT“ "ùôÕK9á'‹zþþ_Å¥.®ù·~ùáÓsÝmO ß}ë­ÿ¸þ«~´«ï§r²|r±|ö8}oãoÙgŸ|–'Y?ùÖ“‹ï×|p÷ü…½Ðgºøîòé]ÅæÕ«Wß{ï½ÝËñÃçW×ÛqW½Ê¨Mo?YŽ9o¼FÚ–Û›²ÜâŒ<«Ã«©"³€‚À]œÈá·ê¥8{6q¨B†e±t:+&Cáf–i°³×$9PË/‚• w÷ niEÆ iÖ„~LAu7‡“5w‘³;p`D꺨P' QB`ÀL• ªVh…ÛÑÚãä-ñÔD­æq209µ=5Å8¨B@(€Ì~D88Á„Ìaµ W3uÕ£Ôäp ‘`RãZ\Ýœ‰8H±‚BÂÌ\´ÖR=˜•ö9AHZu«1 $ŒHÎ R#GØ‹f"q¢V‰5ýݚ6v3Rh5Sˆ—>r&xiÉ—™ƒx-äâ†æj.în¨G0“™¬YX@NÞ¬O­®!i)+÷s;’Q‚,RLœ81Kãó㘆}OÛþr0ç××E_?×%ro8JN!¡Æ>÷ Évóìñú¤øºO»‹GLJ×Úq ÝÎd[Ç-ý<®«œ†îú0w=Œy«eRŸ ûû5ŨŠç¾èk¿¸áiÌ»·âÉ]D|(kKòr´è_n‚~ŒÓÓÅUá9ìg_„¸N«Ùçªc‰01Ò´™Ã§»8ó|»¥ht·ƒXdœ*ÖÞHp–é4^?¶'³œÙÉi|€jv§ f”‹¯œtžÆÝÕfÑç·/vWW}üè†sY}æWe¨›*Ã|»Ÿ‡áÚ»©º0{ðâ”ÙkdêSè¼Æz—µ,ïëõ~f p—úU—èîî}*(K(„œ‘3¬:G^ƒLdqázE®Á¦jF-²—¢ѪîgAîF8Æ•Œ^ÏX¤ðï08t˜BͬÂ.Ä.â̤º(q585"‰Ï¨pfB,-0M­ÎPÓY‰êÁóŒR¡Z)ÃF(0MÄbÕ±I÷^÷(ÆQ|è‰#Ø û›§úñ£á±Îýô žÉf)ç«?ý“ŸÖîWN»·q«Ï7vȇ.äÙ‡ON–ïžÏ)\=Q?ÙÜìïºOo6%oÍ&“i{˜±Ÿ·t‡ç]Ç©ÖÊm˜ZjÎJÖ$m®‡r…‡äÉ£pO”ŠsÆ?ædæNäŒûꕙ͵_mB a"P`0Á‰Ô™ÌÜÝ3É‘¦æî  À”y $01 ˜„=¨ke'E«,rvGKAj®";13Úž™‚!¨‘W8#wÜš*#œˆ03©6>!1,̬NN\­A°™(PðÊ lædªUµz‘Ôæ3 …91·ù5KŸˆâNâ¤ÄêìmXi ëhòd«»¤äð#ÈÀÜÌ*Èø—#46ãQ‰êDùÞÑݤ(gb6«ÐÐ:­)×ttÇ"?’ÅÎ…º¹ÛŸÐœ"Á ÞúZLþ c"ÿ›6e¾d¡Ä뚉ˆ ºIHk;{xò´;‰›jãÄŽüÀ­\>¿nÎÏo®v7úáÛßzøì[OÆWåÓßÿIȘhžµðZRø µ©À¤ëNχ«ëîò0vqè‰Zfî ·Øüè®ÿ.œàpÅžãÁR‡ó¸BHÒ¸9À½%•íX§Œ+XWÓÇ‚Z‘€UžCA7 ï{z¶ kYÏ”Ô'ÅkâéM= ¬ûp¥ÓÝUÇX]¤éûî^ÖóMJŸl‡OwË?ÀÍ ìFã¤1×n§´Å² W«•hd3{ʬ—R?:ûޤU¶ˆò¡óËŒcì0®Q Q0Ž™ re«,Ñ•ZÆmOJì&Þ:ñl¢,ÙåÞ•Z‹¥V×〈ü5|ÒÁ G£FÒkmØ—fD…ˆRÚÆRÕZ+B¨¦§ë¤ IDAT7¸ºW8±Ã­º%w. ™ÉM‘+hFÍðì6¡dx›ð0fdXulÝÅÁJ„!ôI#¨ +ûìº/”3LÜZΪ-È`'»„è" ͦ³çÙ5£öÊbFèYÖ4,iÙydÔ 9#è˜3mæð_ ăñÂyI2f÷ÌuT(´À'· 51 "9š$¦èB$$!ÃF/SC¼¶Œ[6ÝQÅlu‡rhqIðêŒÂñi:y'gqÀaj_E”K¹*¡ˆ‹€zæ…„¥ÊŠCLj¨øX©h­Ôè£ÈЛafeØ=’]D=ªx”¬˜ÖZ”¢BLÞbªî"¡G`¤¬ˆY”x¢4yÈàPp&¨¼áØ3£a‡¢©@¼å|SýƒèÍßw©ÈY!„®1²ˆ¸[­ÈyÊÛÛº.*±¦2çYÍî&•’“h*pr ŒÐI$r”zÈÈ{P»Ø%IÔ†”1Oe"ÂrÕ‰D'Z÷ÃÝaW¥ª˜ aH)*U!q£šÕ­T·Z«WuBHÉÌkÕiÊF•Øc×u]”ĪV³öCXŸ¯N±t'«pÔíö¶ÌõÁúa×ñT÷»ý5uñîn³Ù×»kÒЗIÙ2UÁ¤Ú»a½NVë¾ïƱô°/·7uw‡»Û<Ð «Ÿpÿ¦úõé{vÕ7÷á×4ìL‰Ý*LÁqŸœƒ'Ϋ¾Æ?ú^í?zºýw~åäßç'?Û¼ÿÁ§‡¿úàùõmÖéàã\§:oç]–>ô2[¶©0…“““dÜßÜîw´`¢Ïk!¾ƒ‘f²ûÿBHÅW‡EªúÅQ¹#úÚ7ûµ>¢@àvp'˜3AÈœ¹2yr³R;ÄEŽ~‰úñî3¬Ÿ„n=|ö—Ûõä)œL¥³ÃЗ\Ç’­ßôü ?µÅNNËùéúWoŠ>ÿËýË?|ž.÷7»«ùj~òæƒÕº¿ì·Ï×èl‹^ߌåÉÅù£Gu}ð›Ãyú.voïVo/ÖãùÉÝ©oõnwsñΣ>ûÑn7óÚ‡¼ Ynë'7ϳ¦às*ò0ž><]»‘Pp'#çö‘‚;™Ãü~,è ¦¾¯N~Ö0·,({ñR37mf‚+I îP†LÜP)tÞÜL`Ptg@P܈•ˆ(ÀŘ dæ®N swÇ‘ìá )ÌÔÜ™'fñÆd bp "g‰)u}·¶ªFëTWÕZ !ÅFͱê¬NÎ"Œ(,Â$d( /÷ǂڡ†“3qC›K qiÓ1´ð!cæFã¶£CýÞ•'j®Ä @!b8ñHV€ˆZæÔˆÁÎî¯M˜¯k•†PÑ)8GVñZµX³i*fÇpUþV„¦/v.ˆÚœA60‚K,< `xˆ÷~pqv#ʆMy¸î£<>s¿º½Å~ÞKé¾Týûè‰Û_›ßú¥· @ÁbäÌD•lÙWÇmŸõÍÕ“G6|çÑÚ‡íþñ/ýæ»ÓøCÿù¯?M¯Föë²ÇLóüéþÞ{ÿè­~úò÷ÿÇ÷_®ëŸü³Ë©^ÑårütóñøÃþÑö;o¾åa?ÌsZtXlf÷ÞY¬rüôêOýΣëw¦ƒïŠ€çž!íÊóÍî‡yÙ?`,>úéûawó^¿z†òð7~:OûÝÍf¬³„ÐÍ‹aîS7 jl1ÅõŸ.±èæ¤O‡¹Ö fDDâ`ä%²»ÁÜ ur¡\Ô©–Â}A8 Š0<„wµªfDnzÄ âáþ NVÜ´å«x Þ:¼ð³³‘CÈ™¹¬ [Kh6 BˆLƒ›i€ØÄˆá„ê!’{Û gØÁ¹™s¬åï6ë‹ÁÈÌÕJ."Âq®³»U¯ o´mm¯™À"ÅÈ íÍ¡M¥JQ°3 €¢nÜ%tÿz´ý¬F€ âÐâ_aÆ`§c;ì~b2jHFn®h„X&¦Æªu'0Õ¦4¹'›C˜ ±—c¶—KÓäÄ”@ *DÒJDf&†W´ñ,|Ù>~š<€Q¨nsÕɬâkB¾è˪§¿füÅo s05wS2 • çxð7ã‡Ós=½õ³©{#>Ä â²Ú¯nþô®…ø.Ægxõä’Ïõų³yõè Ü]â²é)D ×¾÷Sô•âtïéƒM÷o6ßñrölAãÌëÕ¶w¼C‡°Æ°äÓGË0ì>{éû êÑòa»¯ºˆÓSÜL`CŽÆV£š€×\.Ö³xa‚EÄ:O·Ó®F/À´—˜}9kœzÆz)Ã.ð_ÎüÉuw¸_`qònøpÞVÁ÷9IFÔ”½n+ ˆA’„-N¾4ôϪ1X ºˆù&äL^ Zpz‹~°Jê…–UF®; «Ô‘Ö”ó龜‘äþÖé^,£ÔÊ1µt³ùaÑ¡( ÔJqÍíéû\½ U7SÜ5Û¬„×›G\49ýc" KÇ! LÈÕ\FUgÌrEI¨M(Âð]÷t="*æ³kp*P¸ÃZôQ&œQTGa -È–ÄËÌÑ;¡@°‘•p˜ÂÄÒǘ)¸¹Ín3Pf0(’0…è)yè\@BœD«fõ «ŽâMBÈ‚îO‰b¢àÒåh¨EK-¦Ð‹°£ªf¹Š›Dv'WÍ ”a3ÔàdI;%mp7VgòêNfŠZQ±ÁÁDÊ(ÀV1Ã˱‡€Ô)/=,VÖc%2Ñ]õ(ƒÉF# è€T=º ¡(ffN®nFGëNÁqkp˜ÁÐýÿì½Y“%Ir¥wTÕÌݯß{cÍȽ6 »ÑMlƒ™!H!eþ%ŸùDrH7áÌC½UuuwUî™±ÝÅ3SU>جìj ÝùP.)!!!‘q7w7SÕs¾#Äp«0Ÿ``Ë j;uagó÷Œ #(K=É ÁmÂv:hÀ P Fî( ”|(Єœé»ŠèŸú0û7_å.VÅïÄÔI#9êÞ&¥ÆX Š4`y| ™iûà’Ë\TK…n0¹™ÎȤ€dÑVš¶ïX³ZÚ›‚`˜SN)¥’жÜ4!—ÝÕÍ0˜,JIîs3—@A J©sJõ@Npq ¬š‰¨ib·l¸K‰+–%Í%—¢9­h¸§in:9;[0Žo¯ÞÌ:m$ÆåñÉœ³„›F€ÂšMs^ÄuQõ¬Lq¹ìMéÝÛËÓ3Yôý»½8¬dW%ò h‡>«±±Ò;è—ýÁrëß•Cÿñ£ÌèR¨!?êùÁrõ$Þ{Ò>²ë°X†õÇ×ÿ‹Çx¼/éoíâSܬÊ·Ãdœ b'6g)ÎMÓ4%•›4ç2ïáÜ5¦flµôqÀ™kK ¥D :R;XæÕc‘Ù¡Qþ¡¨RŠ>$”øßןþ»}Dï=ád*ª¬L¥sÇíë+áã†þ`/ž~ò_ÿ·ÞFs·Úÿ5ýò§?ùÛÒ‚‹Ìݲ_òú쫇‹¬—'GŠÝâÝüÛÿáìž?8ÿl\½ÎåæÁ½'g¿Þ¿`£²ßAyNί–r³gÛæë_ì~¹þÕ6éÕ„ÇŸžúãþÝÉë¿yvysõ¢ì<={xò£>ùÑCy»õQÛnv¯~þâÕv‡¾çÕ¢=ê5OWW7¯^MGt(î¹i ³1æYH”F¥ÁlÎ%›%oÑ8‘kvs³Ù¼˜Oê„.’s ŽE ؉ÉÉ‚„ €¹‘U3DîZ¿jÅ 1™™Î%Æè@-¼ðþS€ßÁ¦º±w2"1›Yq˜ 37›YD3›ˆÙ™næf(„ƒ§ ˜5(UD†©SЇ‘¹©¹ÂÜ@B U‹¯‘UƆsµ¸3CS¢V‘Úž dÅ2Ìš& sG¢jÁáE9\«ìÅ8¸³TÛÅ3Sv“…;éÀÁ ÊNFp01³{p!S#oê@Æ-›gP!v“KÝ9¨Â6Mu‘XåHTÍ);ŒœÄ‰áUÛÌNŠZÑD=˜5âQêöjV]¨<Ú7•½‘Á!‡y½ýÇFNFÒÀ¬Z¹tŒ{‚šfuøÝËrR¯·oþûÿãÍ—·7 ÿAÿþßÍÿLù3+våÍj}|ïâA¹£KE^ïçÕÜkЏt4]\ð2¼Ù饻‡ûC¼8nÖ·W½o^âu:YëÉÇÇøá“ÓcÛüÛûà„t»¿ÚÂsóéêdŸö™£¶N³¤˜Ë‘Æ=¥œ É9es^faœ/š¢Ã­í@KÄSê®N—§g·Íå_M?§;ÃÅ\,––ãz·K˜Ï<€fÝ;®ëÇcV,ÏÅMðŠ± ] ¶’[n.(‚"pÂ2F7¿Æ1øÜpi)·Pнu¯ÌDvî×€#éh½øùöúJôfÀ$hº9·ìvò½£€ ˆ\4—9¹Õ¢œÅ…M²ßá$+̦¢ëÌ߇}0ü¿› þD" d¤cB” tÆ8b6$À NXIßyh9ô¡iI$h418ÃÍ`0®åB r"„j½YP×{]"¤õ7õØp4 ÌÚt‹Áˆ’º¨’«0„˜˜B°&ƒ¤¥eE§šÇj0= ÊÍ¡ÄæaØräöqJ>¶£rp7 ê'Ø€²£ÂD 4Ä…µ¸%+I1Ãæ®jÌ\`"sbâ,6¹Ž° yBfHÍ7­ ¼*LVŽæ2ÐT#±ƒ™I¸nW‰ÍUÖ@"B„sã\13Ô²—@…4{ÉÐŒRH•´¶ÁîÐZ!/Œ §j'Ìu ,Ò¸.rP/n7bÈ=WÆwM?""v3S@Üâª&ψHØ o(4¤Ýï•Ðú·øï}wü7ìû¸“V×èÉC“„àîF€³; Æ))L! k›fÙxãíqg=2«xÃ; ³®:\9êî‘âêÅëwÍQs¹ß%º°8ionÓ~Ú*4°6U=ÜM™Øû=1ÝÑgïXÍüÿ×SúCýÀ‡?ñ$iß{¿Íßùóo=¨ H 9yô(ìûiÜ屉ó²Ý=¼÷xßm.þìññ_|úÕí_Æ•Þê³×ñxêÓÓ?þøÕͯ߼}5g£6®V«ËëÔ­Nç™281Æéfή8JÉ™Ô`ŠiãX8[¯O®ï}¼>{m‹áöšNþ¸ÇcL7˜RϲºÝ G½]ÒÍÿòöí÷ÂÅŸÄ~ôéæ»ÿüâO/aÛ›±Øò«íÛ¯>¿}ý??ô§«{÷O?ÜÜbü<¯—¿úU~ñz—Ù“þè{ý4½»üy:¿\M÷ò3¿ù<<|øp“~uÿ£ÏZ´»¯nNl¹Ýû_Íý§3gÆÖÓæíV^¾8iµ‹y.?~ý|ñäøÞǧ< NbB¼Ú{‡c‡™Ž–34‘šjVud$´µ-2„À±„¨ÀͽP2ªŠ'’0ÏÅ‹ã@©óê}U¸Q1+VÜÍ¡¦äÌ¡i"“9jȫӣ,ÁX€*BØHC µi‚«»“‘@@aÎÆkÝ–]‹qƒ_ yñõÍÙI|²\­ïëxêoÖó(·åþšx¡_¼ä%𯀧—`o3ŒÃæÝú¢ìû« Š,& ˜ÇÀú«yy=¯;\wýð†º¼ê§ý~;öÞpAx‚ð=„?;›þðôªáîmê;iwòöV/ öNoš×Í÷6û ãzúÕÅ÷ï}”®mÿ󷯟 à8„¹_ös²àÐ/ÑaÛÆW ¼ãé¶ØÖ±÷ÍEðÖëžH¯ËžO3ç—´#èI³¸xÜ7Û~xµÝmö mWHC·æÕÅñ¾—wûÛ›™YŸÝv9ÝàTÄ"I×¶âm›²ÙPT ¸!Qb{Φ Y!7‡K-rø@3AÍ£/ûüf˜_'N`«d¼Ò!ôÈã$_ ‚Âgä"EȈ‚!*1¬åp»57½G7ËZ×­*Œ3ÀÕhÅf$Ã>y¡BÚà Ð:âUä% d®5=ÏMXi™»µ,—mÃfÛߤÝ5ò4f¥ áØH×j ¨`:—#ŽcI›Ñ¯&L 8¸Pži±›!+ˆ¡X¶4Ë~§ÛÝ´1ÔL( > ìáçÒ‹uFÌyp¸Eõ\ ù`g2cp iÎ h/ˆlÉlŸç‰ŒÈƒµ­,ZŽÑÂBË­±LP5rq° 7%X‚MLW–Õ† ²Qç7¾¿Å<Fb ¨3Qd w¶CRI*£§r‚eñÚ* rb©f36i‚¨ò<¸‚À„¶ñ3+šŽÔXƒÀ%˜ó^=x`†˜¡Ü!=H¦\aÐìNnJ¦ )èŒðkîŸìÐþ}[ú0¦8˜ ±Qƒn–G]ÆÈÌæÅ²MÓ¤S t]—ñ䢵Æ$†Ì¶{dõ4)6¥ÓcÓu­€Ì4ç´Ýåœ3™#g\^^ ÃÐ÷ýññzÙ6Ò-’¥›í´@(¬!´$ Tå!,`FIÚ-âÉÙjqÚmæœÒ4ƒ£Y.ŽO–ËxÁ\0Ýïc»îbåå"/‚ÔKÖY§e4Íc™ça˜ZéCHçy¿geLcQk7á(µ'Çê|»ß±,­î‡©N¨Ù‚ø¸ï»úý¸õ¸¼|Xø˜K0¬ Å%v Æe;Ûæºè»<è"v˶x¾ÞÝlwœÖ¥:jÇݘRf_žŸ\næÂHMÑ`Þ‹ƒXÒàwÒ¸»’OaôÕöpKT«‘ ¢ªx‚9ÙáC–Ú¯ÿn]ä{îö· ¡C‡Ò!J‡âÌ ª/CwÒ“†W7·sÙ\¾¼ÿ=ÞÅ7ûÅ`·:½·øÞÑýÏŽ—¯rÞu}wBG«¨×IÆ7ð®¼;/;:ºHÇ­I·§=0ŽÃævŸiù:}=ßveÃãRƒmV±kÙ/l:OsW^þzÿtõ Ü´¯ÿöÝ0ËýæãÓþÑ~ wïæËë[öâáùñ'a™M¿Žå6æ£Ó&·YÎûãu3§yûövU.>ú補¯õXÞn_t©%--hÁÝ~3¢ãb¦j¬NPŒŽ@b9ÂaªÀRDŽ …ÏšrÊCö¤ÐCÑa®Æ}8ݵ~°â~P™ÑûâD¥>ŒøæÕE |€ª!ŽAäžçÄnlä&Nl$TÛß}Œ á€ÉHGµh d¯Z rªC ƒc.9K¨ˆW ÌÜ ªÐdwcJ«¾‚çnšœ!‘ÁF®âf RÀ&1º»¨²¹833 š4«›Öå_ÄB`È%Š@¸z{ ^Um £b®n6&t.nBÁ8‹PEÒ#’wî=|Ah&8Q2Ú¹)˜áu¤E(t Ædî5óƒxo'wv0œkc¯^aì±þ/¶à #À[—eh–Í< ¥˜ª‚ÌJå•;Ú€=˜‹ôwº1%5VöØ/,†å6€¼ÁéÇ«6‡i‡1'i¼ÀýïcÜ[¶GË~š÷í´øËý|q›OŽÖºÝo/7—{pƒE.MéËuÂe¤¬ {—cÞÇôÓÛ]nvMŠ'3zÁ l°0ô§«ã%­¶hëx2–^|e|czµÛnlhŽŽ y‘¡oŠ´™šV:•Îc??þdñøûk|Do.æW§Óvùbrz´æf°¤Ø¢ÌPàêókm¯?þ/»·2åãå½åùù‹Õ»2¼Î¸z€ˆ2ùd¶È@ˆ`²³ ^7mhsŒªÑ±Ä¡Y¶Ë†“±®Â^Ë MÙ§ BqD›(ÝÐ|‹y€Nd5^‰žM™`(æ4“ÍTf/3rªT u…”¼2€D"t—{v@äÁƒTÃ%„9°Sµ¦4d怩úaÜ`ÂX@MõÄÙÈÙ);—*_fhÓ™×f:GVø'>~û:¯`uIDC×´mlšO–ëISÚïË4ÇB¢NÉKI›Û]*J…²[ro¬n¨íÑQ晄åþd«BœZòišU$§15je\ŠælªºZ­ÖkÞí¦qÆœ'> G˳£ÅQ3äéV'&œœÐzuB…‡Í bÐ"Q £¶ã“õù£Óþ¸ Ûg #øý{'‹¶!#ÊÊ Y-Šg'«Ó®Ò¶‹]ñru{³fÎFG'GÙ¶CJÉe½„IÔïÅÂ" \X15MÁ•2 ÈYcÓ즩9í§ehŸžOË0ƒ4Ç‘„mØÝ>ŽËÍpú -ûó«²[iÙ–®\•ëó¢ä9j;m½œ*ÿQw±è–§‡/N¨ Ì·[º}Vžçï6÷›íjjŸ´1.{û•“ç¿þâín>£ÆÁ‚ÿ싯54K¹Xùxê?MÊ:Þ[[^Ñzž¾¶Ë·´»àéÝås„ôuß´–Æfìò°¿¿ÆK[¿Üä¼›!c·½”y°ý6åX´Xt°¥|Eª ÎI>nä,ú¢Ù£Ic[ðݧsú,¦ª«a½öå ÷lõé»Å~·~•®†ÏÂX;fÛÅô¬Ã’’Ζ·ÃîÅææ €§)K™¤à(`å!¨"DŒB ÎSËÒ]ݳOƒA3쨗&p‰Å†}3NeÂ>¨p!‡Á%M}æ¼°7[µ9ô!ˆgÏË ´7VÒŒ’¡…‘ÎêEè=r™é0Þc(ÀBw%ŽƒÌÜà$ÁªCbª;ß ÊgC`GpHÍŸ7 ¸8ÝbµÅÀ᥋A ˜&3TH´ÃŒ 9¸– "¨‰>Õ¤/fªÊB€˜Ì\éFîB.Ì5OÖé8ÌTM)—DDMI8M3  >LY7-j aiµÊs¦YkÄ-3øÐÒ9$s¹±Pf€²xM I0h‚ŠL8³yVÑB‘†Fª3ù Êw&·Bõ vg0AmdV-ÈtHbu‚¹ r9´ù] ¯ sg7X!ÏNEÍ*”.€¯>fÛ?†K“öà ×fV14„nÓ³#,LïËÉ_<=þãSy([\ÑÙ_/r·[ìÿðÞ§oÆôhùäáÓîþêíGý®?.â'º]H#Þë„éõ|½É‰'X#ûF_+ž]áí‹áâ«&ÙÃ~»Hšå¨y÷UšÿÝÕ“ÝbKü|(?Ëù9$¡ïb.:ÏÆºé‰Nƒ†6âèºejeÕSâ¼,~üq«'Gèλr¯\Lé‘ûc]<êî­,¤q{ïö»§4&v K=¿X,?ëû?ž7?ØÝ<ÄÃ%Và /æ—o·¯n&uêšþ6ïw®‹}9Î8Üo—',acn1às*ª‹ ëg«ÅèáeÚÍ[=¡õ¾i­„¸Èó4{H€XJ6ó„Uºµõd…µ´.¦¦)7î‘£4œf(Î ó<Á¥øÝæ×Šj©çé]5ôÞÒ[]Cw±ÚN¿ ý-_Ù!Á8k2U b·ˆäRÈk€€ÃÕ]K33ãRÈ|x*°"„†—KYu҉ɄD"nD ŒA 7V“9©¹—b¥`ž±Ÿ1š–@*ÆQs]=¥Zß&J\(8ê^"%žÉv:Ï”Š«B³âi¶°wŽpó4kT/·6Œ˜ Ô3y)23X† ~Ð |í!#,ÆTqç–='xAQH9XQ€Hî7q¹C³ùd>X*b‰,£$Ò™ÌÜês†d6XÐß"m1Ðù ¨yr1(P¸B f(ó»LîÀµu|戢Wì†1X`.‡`oUÍʼnDÁ¨BH1OT («ÏÌÜ™Äkæ‚‘;51˜»ŠWÏhvKÐÙ§ÿ^>¢ïŽÌ#4R ô}wrz{I”f·××(SÚ®ŒdmÀ²•ý¨b "`òÀ O0%†nZ1Ë̳'&¦ˆ¦mmžÓ¤9´Ý‚QÎYá$qut4MÓ4¥·—W¥+žm—wÖãÞ'ç¾ÿ.7i»Ã^”Y…•§ä†$HØÍǼk ‹¶]µÇëžÉÇýVÈ[æy˜ß½{7ï‡éæ|§þä ï·ó>«eåônón›„D8³Îbdn‹®Ùì6˜ r»¿žß]î÷£Þî Öìnmå°Ã5òCðÛwV·ß§b3¸1³™ålH †Û–¸kc×Ű:êO¾¾üò¯þ·_{ƒÿâ_~tòèL/Ÿ=ÿüêÕ›© §÷»S¦Í³›¹I>÷–m7îYü8hï\’ºÂ‹BÿÎÏëcq7/zÿÄæ¬•,ÌwÕQ…"è¡«]"ŒûVÓñ}Qt÷(¿QØÕ)°³ãÂ§à“¯lQnƼÅí‹áÿ¬÷/7¿¸¼ž¦_?ûúó7Ã5XÑ wM{ùî–|p.9 ƒìå~Ú„ÒÎÝãÕÅ÷žþ¨[õ„f»³?ßüâÝ«ñ~s}–ŸJ—i„a\Iêîd8L vffµä4ªŽd)ç\éãšv®ú»ßÕFDAhá éBµwœ‡åÇ]ÆÙ—yñxuöÏϧèóùÙŽ'þd¹|¹?-òèÝ1ܯÿïWúåtš´¾X¿Þ–iº¼¾½N('„Ð/¿î ÏÛí»_¦ïÿûx¡¦ùôOŽö÷Z:ZtþêògÏþ¯q˜ž= GíÕäo´ìÑ-Ž›fMy@ ¾"Üoq¶ÄòøhÍÝéÉ;#t ¸Y¡{ÒœýÑiûýÕÅÃðbxþåÕîæ¯ö ÆY‹eFÜD#ì7y?릃}‚ñÏ›ðÏÄŸúÑ:}Ô®Ú›å×_mþæë›ŸlqÛÑ۽Ќµáq³xÒeJFö``(J ³¶ŠÇm?KÙ¯zfÅ\ÆBžïõÇs´\Œ%…pë¾f}y¹O«®¤F&×R˜-¢P<¤Ò8GGëhŠ^ ä.5`“ p¨Âõ‚ªKtMæºCÀŠçräþ¨1È“i4 @ VX€ƒ9ŒQ‰#036±RáòÜÕ™œÔj7…ÜSsDË5­ZnFää˜LòA\@f˜g£€¤^ Š"͘f$À Rwên¤j5I (ÐÌädÕUhÐì¹!1pr¶$ Ó!²Â ÑZWƒG’MDÎäŽì–Ý2ÌjF¼ûwÑ?* ‡üïFÃ@Òd@hЯúvÙQP+®ª(*Ò4ïwÈÅz²Ëã“©ÝdP¡Fí’sd„Ýn¯x¨ç5›¶mT ±î/ÍK.…ØE$gÍ6¨jÛ6ÇÇÇ‹ÅâúúzÈéõ›M @óÇñìѹ5þæÍ«/_üj§àl!YRÎ`wËXLŒÅÉšŽ>ënØ <¶ÁŒ·Ûí6ï†aØïÞ¾z×÷=9«qÓ.#çìA3v·ÛÝ”–Mï„’už³¤”q—Ò8b/¡Œ–Š»¶­´—·–ö@^ÐÕ·ðÝñû͈jÕñ[? r‹–›–8¸8q¸ãk»ù|«úe¸g÷æ—¯Ó›ŸÛÙú¬iš¦YÄåÉ.Ϧ¢ÖL¡yñâ7ìÝÌ‚P…`TUMß¶ôÑ·|Mï{‡\ûˆÌÚéCûÓÝFŠS'g¯Œ×Š¢ßšJ¾/¤%ÎÊ –jMsR Ǹߛµ1žôXå=}ùÓ—ò¿·Ç?ê~ôéÞ>¿~ûËaû:"í1æM#ö lÔ`…1Ìà¤9–£ˆÛi{äÝõõ>tIEvDë§Ç~üàoÞ~=¤¼™ÃùÔßÛSÃéxÚ\µô´÷¾ôØåÍ;»I¼Ïã‹ùåùÓée*¯ÚÍOôÅñ¿N7¿–éõÃø‡úàü>ç«…LqÝœ7ën5QÿúíþåÕ›¾ýò_þÉåG÷ÿÅQ ã챡š&P'±ž‹ŸÇlÅ N A KÒ]4™eõìT,ÏÅf%¹À”ôjý²Ú¥CuÒFv?¼±ë¬æ j³ !3rg¹C“;LÍSE±ÃŒ…$’ˆEr1å5HšèE…)‚]¹"5ˆØ^žËLÆÎÎ"$¹‰ÂN˜ç‰ø½ÛJeX“IlÔ‹ƒ#j ´2‚ s€ÍE̘HHaç:ª~#'7«4ì*k¯-òJÍ3«$ØÃ ›‰I‹j¶Œˆ¹†3šA3GgÃÕ5X («{ÝfwƒM DœYœ@ c˜Aø®O‡Òð@\£Yí`]‡q½êŒÍß«S½¨ÌtÇclšÀò‚0PZ†<ì€R…Háw/ŠØá ˆ{œŸµ«?ìN?’éf3ì’]ñÑ4.Òo?¿ÉX$Ox²·ÿçÿ“FìöóO~º??Ç4áê»›|=5c¼ßQ>Š‹© 3M»½µ°Yq9ãùsüÑO54±mý Ýë®ÛWt~þý¦{);„½°«.B&ÖNø™€€†qÌÈA·K”œç=uXô´Z¶Í*¤ž·££±ÙûÉâÑG̓Íí¢}ËôZñ²\ß¼Ù~u•Fèt?ÙS”§Msnùõ>Úœå¯~róÓ×øUB+¬qof¬‚ ÄÕ¬Hš‡ìÛ{ð$ì  †×›K*½jé¸YÏjËäi—²‰“ fÀ‚ÄØRã4n*ÀQ 2»í’QÊ‘c$­ÂŠe8·%3EåÁЍN ËwíŽ ]ÐÁ@ô­ûü?@Å€µŠÛ/8FmOš•»“Òaþk♞ƒO‰1‘*L­¡ˆá¤-t¼Xb¨,inmìªßÍP\¡B¬dÅ¡©@+ðÂVÌ™5»¦R†’»Õ0®Sª²S3dE!¦”PfK“•„¢\{-N`ƒ%Ï0wä‰`À3²ƒ˜]Ü*¬lHçCÛï0‡É€ÂêÜ™æî ¨èB5™Þ„MÉŒ½M”µhPQÇä¶G CÑ™ÒlYI‹X½Ÿ;’&w† ˆÁuúäÂà ôõJ¿¨Õ ƒ¿é‹3,„EŒàPv°Õ5Á],uÉ HàL¤FC©Tà \ ’Ü&ÌPÌ «ò`qöš0}hQÝ‘EùNÉ[o{îðšþÝŒèÿ[ȳ«tXŸ¬ÖgGq÷ó8æ©° "3xåh _æ5®ŠR›•*ëDØo‡ŒbÉcÛ‘SÓ4-‡XDGjêB[Jò4»»v"Ó’RCÝH‡Mó„Y°\ãèü<.ú7×—_>ûêåeªå|$Dj#ï¢7d$ˆûi73»°M!L››noožB*W—×¢ l·W›DNÍ¢x·ÛêþÖæ½{B…+\@úÝÉõŸT,©ê7c"“¾=f gê™—ðÖJ¶<äÝfٹדí/Ë_ïÜ® GùM_ʳ·Ø '©;_­’^Ïñ*vCÿçÿðMÞÿ¢¼ynå6" $ BßÜ}«"ºãbÛûÒˆ« ÄôM-Uí› —¿¿ùX Ño>Ö·W_cX4ˆAJ½_Vo')úØöºX”æã{÷òtýâ—úù÷‹æ1ÆË¿Õ+ܘ/ñéýóõ*n,¸Ó¼¹I9$&@®J|£sûúæâ~¿§÷Οξ [þ~4²1`¡Ûfý¬ùDW÷«Çñ¾]•v*×·_L}y!›Í=;ýçvû[úåÛ_í¿èŸ¬sXýlûæåË|Sòæd\|zoZw“Ò0ß¼ÒۯʋëݻٮRÙ΄/^~ý‹×öëûÛðFKǒ܉˜Chˆo! SNžg‡â–9ä™Ë,:ç<³Ú >eÞ'Òât«¼Ì ^gzìDUö‚C8¡†A+¨¢ÏŃ#( `w‚Aœº–K$­ŠHÂ.;˜ÌKǪ̀Q(õ¡ˆèææ¥Æê(Šy‚õªš»E©)p5N͹6©@€y©óÆ\33@!pŒ 3ç¹h*DRµÊ,"ÒUé„bÙQÙ닸‘Ø2‡š³àânÄ0ªìÙZÁר7¯rŸâ¥”R‡kð ÎŽb £jÜœD¦eg@ލAŒØœ”¡"B@Íqw3s«]ò@,‡:ŒkÑÝÅbùP£ð*[3⚯Y§&N#¶Ø2Iµb®V"b0i•ؼßÝA>·;`5=%÷#}¶>y”ºöêæø€1qyCž½pô\ß–_ÿ›«ý,B{ø'g|²;—:ì3æû«ÓÝ¿§ùx÷êåËÍô—ûò ”£=v„+Ç×øä V'åèfüŸúçÏ ŸÌGÄ»GI.æ~= ÏdŽKí“MìU]àsØli»_°ugGXÇKY•}úúùõórMóUÿ/–·¼ß·js8Þ6gïVǯ–«—sùò'Ë-Ž#š{èÏ]ŽÚû›˜_Û»o_}Ž7#v-ަ~eÁòæŒñqCÐ//ˆh¿GÉî9ZfˆT(6ÄDåÅœ-mó’ãƒÐŸ5 :î¯x|î·Û…ÑUT@â ‰Ÿ> †òÆó6§½™1"$»e2F)@i8“˜{Ž…2GGCœÉ‚jpWd;L‡¬ª¿ü ª4·oåÅùLùN®dN°€¶o} §Í2 2’”Z:an†81‡ªåÙ=¡$x@̰¢îÌp ,ýÿËÞ›ýH’$i~Ÿˆ¨š™Ÿ‘‘wÖÙÕÕGuOwƒs,—‚³Àî ‚|âÀ¿ù@†˜å`–;}mßÕ]UYyÆíîv¨ªˆðA=²²ª+{Y5Õ3ó°ñ@:nnnj*"ß÷ûZF’Á\¼ðä”H« *BË‹;d"`/:Øta}oS¡½uÏÉ Pä(ÁƒªMTŠj '­Ap¯äÍR¥À×ò6H$ffV¨¹›ˆ˜˜V4¾Ôì3wGM\©â>÷fJFM[3l/<4cͬ;-ÁRÎ&Z V’`l§6B'/YI×ZI13À´¶ÀTª`bGp àªúûbûX3 d™ÉÝØjƒ¦B±)Bð#]Õ$àÚÒ"Vì;7¨”p#%#0$BUd*@`vkœjðQ­« ¡ÎÛk°W¨&c’õŸ+¢¤ŸŠöOçE‚3ÌæíÑ·ÌrNZ¸ 8nb˜M"€Š¡ïÇ”RÖÌ­Å6Hmõ©™—®™kRõš9»–œ\S"6¥š¡–JN913ƒBW¨MÓ˜¶Û-€aŠ¢Á‹¶[Í]éììêò|„"D=¶±ë⬡†!³xYh–‹UèʼnMÄ“‡ÏKIf†[wÂz½N%ç<®ËãÅ.ç³ñb'É=ÌKšXáMoSÏfy,G‡í¢YšÐÅf3Mi&³”äÙ£óaŠãà(ßgBöŸ+¢@Eô™âä6íÄ)Ä0—æ€Ã¡%gXšvH©ËK”.îvcb ¢ î2®ÒÝoÏî~ýAÚä³=½ßÜøÎÑwo­_ûÉÓGý“?¾z˜%#ŠrKÉ¡ï§Ûô²FîUgň/~Ó?±ÚBDÔ?Ýbô—Ÿyо¸ ¯_÷ýªù#‹M-¸ÄV‹YnåÊÞþÆ×VñìÆª;½ÿððµõüÁòì×WtÏýù¶/çg›IÛ-C‰–w³¥·Íèél[>˜Î¬›6Å©D §ýÉÏú÷qüÁCwZ4y¸º½89>ܤÙí;7ï•^wƒ3fy„(BIÁ‰ÙÜ(ªçÀóv>™F‡ÇÈ BS2Èá½z ž²M„¤ÈFÄABɹº§Ý®Zû~M1(93 ª'GàD0"±»» œI(q.Dˆ, 3Ä3GS ”£)™íSn APÇM…4ˆ[`R"«Ö4Vs$h¹„E„…™SuvXñçJí·kðš«»£À LÞÄÐ5Ìl0˜SM‰w‡ lUü) ŠCÔšX €%pÐZpJð¨DLqã{–í{•ææn@ Sqwµ¬6¹+ƒÀÙ(ÅÁæÎÎ\Á -; r`aÔffƒ¸;3 ÃÝÝjôw‰¡¹¾{|Ïy¢ »P§BµÒª›§ ©a²âJ^´”œ‘³*¬@AYaUÍæV+ÏÏÕ.¡’ÈtÌòÔ1ÞlÛ¶Ï;}žOá·±Zm?MgyÂÑw„o|ç}¼}ïÎÁÿç÷Ÿ÷‡øøìì›s/âÊÃ]À6ž¦m/iÕâûG‡Ý©®.·§ê§ŠÓ ¿8ÅôØÞض÷Jwæ8UÜiwË¥µ-ºh49j&§ˆ«M}VfM¡¡0X":eÝ!Ìq»·^¿s!IûùÅ©~Õzú× IDATüáÕãÍÆï@&|ý›ë ¡š{u‘ÏýÉŸö?ýøÝ[(ÒÆ7!_S?ÎÎBÍÑÅÝ«Ÿ?ýwãÓ_âÑ N.@zzˆöpxo6ÿæj}»”fs6,›Ð©´îÁùH Aa­sIyÚz?í–qb'ÑoÝ»Åq*4N®06(ü|è}ÒÞòÎÒÖ±sä‹Hã 'U÷Lªe1DëÄ-‘ "\^À?üú¢Wõ‡ƒ³_²^›àÊN IËa›¹t“Mìb ©Ivr/ Bƒ‰©kF™`J‚'N®“{KTHÀStgƒ»JÉRšµ¨iu>*rF!8#]b*äÉž¶>ô˜FªT&‚S©€¸ V*fÍLaZ½¹VÁš¯|U3r6'f—Æc¤(,`R‡ª‡;µaV'º,b&'óì¦DÑ*S’3lpVVj `î0ÒD¾±Ñɸˆ@I°äVŠ:2`Ìædp'¯¹põJ©# E7!©1ëÁ©1 N;%7ìá•Îq"€½*ö#k"80GfQP$"â=Š~'¤2x¥Zª[£ #§¢©¸Ì³¸*j?'F‚Pp§h^“¹ÉîìØ§l£UÉÍÁŽð2ëðåÁ¥EõW½ }2¼ÿ¤‹ô…OC_¼øÇÜ~Eßß{7£—þd@Õ‰ö’š#a׎[g:%QAÃqÞ„®%¢ µ fó•$l/6ärÐͳ;Z-/û«ÝÕîøÖá°»ÐpaìJ#C³Ùl.Ï OX/›&tã4Œ»`6#±¤Ëõ’™·»þâ¢0°\ó¬]ÎÄDùüÉåÕîj›vH@A+Dàˆ&íÒ²]–A›Ð¶G»x»é½›ÝZº–ËË%‡iêAŒåZèìì"Ä8[u[Û¥N/†Ë«´=¼s·•nwrFš§aØ]ŽíœÖ‡YìèâÙ¸Œ”¼¨wóùA·:’³Í={~fcBQeàP Duñ)åûÝ¿Šï§™ãÒçû3p‚‰¥¯ˆ#Ú×/g‡3sÑÚÕíƒù*`?d,ƒÒ<ŸvOÓ³‰¥7Óæj;>µùÙò­ô_ý÷ß:üÓ7†€ËÇ›”ÎNÿú£NãÅùå¯?ýxóh­À™]$°——ϳrê_ÔEŸ^>!ÑÕ†·ºUV¶“p]”ëjûâoyÙÓðò¼èZÙõɧ­Taˆ r(AGOŸ¼~xstœëù/OòÚƒõý?ûÆÝ{7ï^=øÕÙoÎwç‹fûñÅåb†qj›e']ãÖÊ0ùfRÉmñ ”‡Qÿ>}Øé•=þÍwÊì‚»É/OïÍÖé²ÿ‹ï¾óÍÛwnRÀ ?ÿ݇3]¦öµûïþöðd¼K¯¥‹»§wš¹~(vaÉ0M“õÙÎæaFãÉûB"³õüÃßüúɯžÿí¿ÝËnµ(‡\’c}ô¶mZ>ZËr–}ò]sÉ næä6u&e“† DË–’a@Ø%²DÈ Š©¤a¤ª—sƒï¸Sð¦‘R²A ÀD­„.2ï[ €z’ªÊ2iÕSU¾ …‹™©Öÿº1܉ŠC¡ÂBJ,¡&·¤ÎÊÁKJS?T†\!R°1!sÙfXMB!M:ø 1P"ld$$À®ðbYÈ#º(!†À@n‰HrÎS.‘ÀÉ…%0OÓÄÌM¥ëÝ‹«ßJ¨*KŒÌd“º³¨ÂÂðuv¹YƽùÆ‘ÌQ4¡#è/F©ur7SÊæÞͺœ²æljL`V—Ääp.“ƒ9“pÍV"auƒ3‹SéÕðLWó O{"˜£Ú"›fÊ£–®‰ºª…Æ)´ë0m ¦¡™Ýmä>MFx¹2ùƒí˜Ïl?êÞ—Á47À½u\QÞäŸÇò›m÷Îêäøüé=û6·±¼=ÝŒ7ÒÏÎßûÅ ÿ™Ó/34`Þb9àȧ?‰ñ{Gë׳ٰ¡<È2@|,Câè«E䃸Yئ-»µm;»J~®í¥àp›ü|¢9ú8›óÇ‹d½ 49.¿É/"_ð¸_Íy~áêï%´~Æ8TÿŽýé‰jcq¨¡]ÚŽÓ¶ŸjÀÒNÓ0ŸÏÛõ¢›²o§>ežWVN{Õ4];j›‰<…‘+ˆ‰*Pªù3Ÿù>'ƒ?ç!(œ2në(@`‚ÃŽJßÌšví7oÞ~ï/¿~ð]ê¸é¦u¤9pgÜ®lWhw>¶''r’ˆ6„eÇs ËU£ëærºò¦¬//¦§s]xÙÌiøþ7ü·ÿÍ[ï½õÆz¾<}RþÿíwOþã³ÛóÛ'—çç‹­¶ÜXø‘l·ùÑ“Sß †’ZÝMy„j$u—ÏŸ—Ô—ß<þpÛ…§O^¥«+ìRow! çÉR}Þ¨»ØqÛ‚Õ’­ »”ЈYÕbÓ¬ÉmPô„,^ˆTÜŠ+HÍ‹šqb'&÷ÚÚsr9ŠsrBu)˜8BMÔgRªòtå…ÎÄ!°S Dx ±&ÄH)‰3¹‘GµF¥KqwEq(‘‚ìl+L#‰8ÒT&/u›.û]3Œ\˜&¦âÚÝõŠtšˆ¨a;»³›¸‰»gcçÀ„P']u¨*Âîžs.–ÄBåtŸµ/æUµp JÔ6u'I`*%;L=»g €J¥à#D MŽ073 IŠšª*U°‹Ä€@ƒ"D/Î&À)¸ÎNì`#¶ +‡gP©ÙÆÕIUiÙ&3)àvâL€“ƒò©.Aü¥ëKá/¨š#€¹¥æ(ªO9Á•ùÔÒÁÎçX½‡ßn‡Ð â X73]ܼyüÃÿ|ý-ܽ{çø­¸ß>ÿ‡ÙVˆ×•RÆV8»/ËånÈŒMÃ,íÑœ5++ÚS‰€™X jÊ®Œ $ƤÎ<1'¦fVFŒä½ÚÕ#ĵ÷”`>rRKɧbÙÜio‡ã JS+ÅY0…*ýfwW'äŠ1sÀ¼ÚJ^—¨NÉYˆá$Ô‚I+´Îàè,â5#¨‘Ðd4VXÕ¯u7oÀ n:„†"‘S &MÊ£¹eR5˰zÀCÉízwJfReðuš_‡×G€á®Ÿ°"*ê ó ¶æ*1¾û’» “`Ü  Þã*ëÜÙá0w‚( ƒjDÌûí‡ã%3pMÜSŽÈû1wß©‘±eV  êÌÈܦš2,™fP%n;;‹!8 5X¡á=œÔý‹WD¯Úá}‰ßÿTV)½¨‹>õn×­ë¯ò¸_è÷ÿá‘ÑgÛùõ‰XÃû¸£Ùb&­ S¿ÝmŒ½‹3‰Ì,³Õ’!%én*iÒŽe±˜/1+š rÏÛάg¥†ÐPÛÆ64!¶bAÀ2ŒÉÆœ-ƒ8`bqÖš*ÃK.Z\ÕEb»Mnê©OF£ ®R"š.„2vÊcî¯ÆFäàp½<謙ڃu‘qè{Ë–“rlb7[t³ùª´]7¥]ÛHÛæ(Â6Ë«;miT¢Ìh6ôý8hãÀܲE¤[7–-/ËîùåÙÆP’î¶3êóØÎ%΀\Š^uªR´\Çtúç>wÿè×è ½þÏ­"z¹/û¢§8‹C3â348÷ȳÕ[ÄÚÞš/Àßç{ÏONÿý¿ €7Þ¹Yüâ´íÖWcwð7ºñµxr¯ÔONÏOdÌÁ#x‘0e„,1„lŸŸ¢[oüÏtLˆÈM‰ªHÉŒÈaÄ ªJƒ;‘‰£frúõèŇý>u"2°’˜sFg˜1 £¤iäÇ7׳]~³³y·ŠñæÑ¡‘Ÿ^=ñnxó;7nw¡y|rþ¼7-“ha'cA%6üt{Õ‡“î~¸õÖÁâV8ÿqÑ·—·Þ<:úöÎwÿ‚—Çaq£{“ðä¢ô›þ,>{øÔèf{a±»<ïOc3“õbJ)[ Zju—ÌŽ†ùÅó˰žŸL´+3;hÇ+ïw›Îäho¾s||„p£[< SÓÔ}LQFóâEÍà.™rðÉ1:Fò‘@…¼0kšç‚” ÁëSGjø"[ýà©jˆ<’s-€È†bfµåÉ !PUžq+Ô‰’‹7>µÊT˜™„DjR¨5nÁ¨¨#©rÀ‹£˜×ìX,!Šƒ²i.¹¦—UèNZL„X"áäp°3Å}>’2ˆÔ¡-ZÌàx‰B‰êإɹxJ(fä‘ãÞðùÂç•Õ¦fªÌÑMÝ jp"vh‚9j94¤Q€0‹±i 1^܈,D.y+Mº–ÙÕ]½83XÒ Ældûv9ïY$ ®U‹‚@dN8L÷Þ‡ýÖdŸÒ[JÚç+ïXÍÔÒ¼Y´óYÎ?W(GûBȾp=T—g7²lãåÕå¬ÅPðîÛX½ƒãæ~Œ`™*}gâÓ®>~ô«çþWÿú­£å­ò£áƒþ¼¸½¹<ãôü£‹ína êдø‹÷Çß^ÜÊE»p5Ä¢i¿MýÉß<=¿ÿ˵úÁ{ë_ÞŸÓÂ7GÏï³Ëÿx1dl'o/v« 2–›E´pž‚¨)ÌádžŠžù©AßX¦áö÷ –|‚Ùÿþ°½s s›Î7Û'ˆgˆ-¢ ¿|¶míø ÎyËárvõóf÷Óðø§ixØ}ìqƒéF‹Kü+nþŒgo^ô}“ F,£clÀKHA&¤íç–Ú¹º,Zm¯4ÍÓ°¥<º'÷‚Iĺ066!MìSC½û.éH (‡Î[#ס˜¸•iò°X$pav‘âè‹K¡8gp6ÍÈ 9A¦0×±ZξŒ ©çáV˪Éó€¼Ó‰A‰ ({1+ÄÒˆÉà€‰8³OfÐCûà£Y¢D¶›<\cË%8ÂÖ¶¥äyò”ˤ ÊTË‚“ºÜÈ e”$¶g¢€÷Ðû÷$89(#d7r+(‚Rà5RÉYÝÝÜ Õ?ÁdJHæ™Qˆ¢“‚jÓ€½B3Y JÔöb¥n6—X¢^1á/¨JÚßþ)ÁÿþéË÷«;ϨÏ?Q î_½v \„à9¥°nÖv³ÀÑMÓ¤1W£œBÓ­º¶Z’æbeLº5…•â%OcC!" –J¡4å]* NÉÄÀ@1M˜DLY|>í"øh‘'ßí6Wƒ›-v;Wƒˆ¨*`€£ziÿ§W¨ÏþØ×ýUËû«Žû¹•ýÓaÃÍÌÌ+¶ô¥scS‹‹Y‹Q†çÃñÁó[ ƒŽ[§ÍtuºÛîÒEóFV¸{qçÖí§ër™¦,M^t[Ͼ½ZO’4Òú4ãd³Ç–P🮈^EV‹wƒ©Á«!_€Hd{†¹‘™šÁö*ÁÏ@·_y½ˆ2‡âbÖP\É¡$BÚ5˜%Ü9<´q¼(ç———³“ÑÊ“ç›iÜùˆ¥Ý|gÝÞ;ÆÇíÏôNÜÈ9»'uÆý»‡ë»òÎ}ûOþòÝ]Þ]þ¯ìÃéµ»þ§ÿñ¿;z·Eó“‹ÝÏÕçO§ÐÏûîõåry‹Ÿ”£æ õËò˱?✷Ï~}>›ËûŒ@íbqÜ®:êSyÖ!ÿÐß:*úc,„Òz9[­ì[oÝ|ûÍ·ðöÃ,ÊU·Ùž°°¸X{„pã¥>:š)IA ¹ä}Ö79‘‘Õì>WWìSoÉ™`pªJ2gGpDáH^S†Ø•ŠU ‡í ÖP\­Pvgv°Ò …Ô\sÍvn¬Æ‚Jˆ,BâB\œ 0÷læîÅ ,ÎA@ÕE†0"×DûªñSuò<ç›7UÏp"aò*,§²w(’z)®•©S+Ô­7{tµÕ|y»“ºYqw4ÄJn­5±ƒ` ¦J6ps‡š‘2 ¼*è™P#Rë ®éB $Á-¨³¹–ä*Ê£0\“b³u¢½‹xÿ…'ÀÊŒt¤ g2x®n¢O£=nŽÜ"¨î¤nfštÕÎx44Ö Ä®™¼ôÉ|è…ûËp5g Í€ 87œÍñ?]½ýoî|‹ðÚ”»®[$ÏÃÈc¾‘š|VÞýž,ßYÓÆ©üêwO^ÿ“E»Z=Ç”úGƒbÑ`µBìfíýæî7–¿þë‹G—–Ëé•ao†f›CüMúày¸ø÷ÿ‡Ãßþyü»éù|Ù~ûß¼>ý"]=ÇP0>żÖébÜrÓu1Ž©·qš1´]š|DN fwpãÛ݃·o¥–"…ÕÀþ‹³ÓŸœ]ýùw——‚éþu!¸x¾=}M.~ÕÏH–'yøõxòwxú÷éùCÝnu‹Üß|#†oI|Óq0$ö„bÈ(ƒ``˜£Y FÍôeØ¥¡ÏÂíb±^jÊ;N½eeiV‹ÀÑsÙ¥qn¡(<  1“¹'Bã¢a ж1B ”ž-÷)9T„¦¤År‚&o2,¡dX†*Ta3¨ïDVq5»ìK<|¨JøÛz:˜[k¬êf˜ÌG¡õ—èƒyFVx†µ`6M^6Vv®;·ž|rshŸajÑSÌÈ#¶Æì©øDŒn9’‘[ÕŒºÃÜ…ˆÔÃuŸ¼bÍjý\§J¹~ª² R @êàA¡mlJ*¬ ÉÊ-Œ€`S­']MM ŠBàY©5Bˆ  VG1CQÇ„ÁÁsË< $PF²‘P#0SCÜxP'x¬ÞbrÑPªÝ°1ïé{ë(Ü€P]Fff0)Ùžéu-r N";d?˜‰“±i€Õ7T{‘à°.veR#¯±Ò.prMAj¶C*QµQF¢kÖƒÀÌûH¢½_XB-¬ÁÄ0¤uzñêŠèU½ó>_½VÕÿÿÿÿ¥‘¿lt.¥¼Ü¨~Q}UÇý¢¿ÿU͈ªóázF”ÍB˜Ï»Ivì…Ð,fËõ‚bØæ!§iê·}'UD5±aÉ‘C‰:Y¡€Ð Y6k.ìÅÓ’Y&æÇËÖ-ˆ¸Ñö|³½TD· m˜‡©³qT6t]„ó4¦Vj ÓœÜÝH NÞI»I«Íêha]ÚøÊÇÍ1[#®ì¤}Ne(Ûi{C׫ٺ9È9”q3›ÉÑqwpoÍG²Õíd:io¥Gˆ€¸ÌCˆÌÓ4íú~6_¢žS³ŠbvßlÇ]?ö=ƱTb€WgVíLî¹±Dÿ4×ýU?¯:.Ñ?¯Ð¤:M1sfw+¤ià¶·´ÒîÖÁñÁzùäâ´•¹Ä±ßäœo=x{7ÒÉnÓ­xñ<,>oš„9åÝrídºÏ ±þ q–<’°(Sç/ò‡*ÌÏdªº«WóúkMY1̹Âèœ]Í ^ξx‡?@’PBŽPU€g`Ù] ³f}ðol—g|òhs>^L[¥§lËñhe³Ý¦í}±X¾¹\/v)I‰Qшgj{,(n„ø{·¾ó{wŽãÏß?í a6{ëµÛãð®¦>ü§‡ôZ¸³þË¿|mùýwÖo^lŸO‰ÿòbÜ>ÛµFcÿ<- „t4¶¡ ‡]wè¶Ö\Rÿ1,¡¯ßÑÅÇÏs™Öï}íÍoÍßøöŒóC¹pRl³éI\ƒ:²š‘ QŒQQ·ÄÉ)«ÉãI…”L­îç‰H@V!³žåˆ*W'f‚p n#7 2@ä5'„ÀÄ03cS¥@^<¨b+0Gb.ÊR˜5€Ø­)Æ$‹enÈÁRŒ‹“ºg˜³3-9;b!0© €J¢&¸“êPj jäDuŠ¡ö­Ü`"8˜‚„JÎ… g"aÉZ+ !†Ã\Í<tbVÌ„^Hʘ(Š›3939±YÓ¹¹q7๠Ü*Ä  n-ÁÄTÄ£@u*(Á@%¡ÒÆ60I*n!FG°š†TCC@ìU¸óªSœÈØAŒA×½Yx„’ ‰Ù¸Ôˆ]UóI‡it6ªBFuЦ·ÿ¥V;' ­ä^=aûñ-ýÕëÝ¿<ÈÇ—)ì\LœEG>ã6>×÷^û.nÏ?:ýrÿúÝûúÞÂgñýþâ*£¸—½›‡Ù±ÇÃðä>žzÅó+Ä<¼q¢vž‚cþ1ø_´ñö·†üˇÛóÃux«çåwB¹Yv+ðq‹x攇ÜMOO¬ßàö ³Ð•ɰÂMÌ¿{œ¿wø]¦N_ïn½»àá¿~.'ͼ´"|.cOÓo€Ó+L:•Í€ãåòÎØ¼ÿìñÆáIÒ ]o?ðð5mn“›,„yÉ€€¶[ôŠYVˈØÃ3E$s4dzvgÈÉ ¤B£†LR4ÁBÓ”Xœä\l"Vn|ÞÄ9wiRŒÓån„“Hˆ‘HY&¤>êÍS…§Z=‚u.ÄûÑP]„‰œ¾œw–/\3…•<™qríÀÉÝ&躤áÒ{&ŒžwÀÂC«j)g¹'ÝÂÂ8iKž›J8CP”‚©`(ÈëXZnŠ0*P…Rµ»ˆ@@Zà.{ü) (€Ä™Í¨Ó¡ç‘tˆÁ¢yP°!ŠÏ™£šÏÂL9¹Â Fj¦°Ä0¬ © »x‚„ŠG#9‹q³[ &Û‡9¨ L@Kë29Š3·q·-åÚ½‘HÁê(vƒˆ©«•bê°•Ê• ªîääpAÄÌìDfÈlÅ °»4r@‘8Öx%ãàÄÎLœÔɽzk^Á5`@cH5»ÎÀœ €×læ{C°;È)8(PÃN fg¡ BµŸãaOæÛÇx°Ã‰’›_fFw¨#d IDATô¥Àÿ©!Ñç2 >GÐòûžç—pÇûïÙåkÝŒ=Sš¦Y.—G«™ÌŒá 7³Y;›Ï'”~ôi×ã4 ‰A‹Ù̽h²Qû²› K Efm'mîµëº²³i†4&yŽùAÓÏlÚ&4¡µlê%ëÖ»©w#'„ˆ'«"~b7s×Ú¶ Ä `nšÍ(ÏbçK¥ÜX¶3ÙÙ&ÙÈç³;â¦@Tâ2ꔦqšIVGMw0ëÔrŸ´˜òÙÉéîjcIt*\2l7%-‹n1 ]lLÓe¿[ôYàEK;êÂÂýÔ¹ßõ6LU—ª€¾üqïGŽþOsÝ¿èûüs›ýþ]if¦A½Qo·;Yo­Ü[,næogs—q~ôôììt}ô¬¿”öòþÏÿÃå¯õÇvM:yÿÙóÿøÆe{§»õZ¸ßnŸT®N-G7à0*@ŇOÅU¡p6úž¬ÍàDª1]ÉH‘#¹i6 êÅÈùEcå3˜Ï~þ¬„â¨Ò±Ê,ÆåÅpOæ®Ý8å-Ú¿ÿÉã2;7X´Ž‡F),£!–‰yÊEɬAÑ0Qd†bæŽÇW§o·ÇcÞþôÇ¿ýñÏÞïZyó[o¿÷§_?xPp¼™ÍeáàËñ*K·é.¿ývS§Ÿ_¥m¾ÛÄ·îÝ¿ ýŽÃÒ6fýDÙ¸¡2S¾ì¯ÊÆîÆ£ÓìíföæxódJÁí20…ƒ£pïÝõúMÿøòé›_t8ŽkšÎ¯–AH‹— HÈœ46Œ–ÕÆÉûlóDІŒ`d¹ÆW9ÕG¥³ïkO&v@˜ÀÔHˆ‘"+3#P™²3W®sOA` 5RD‘‹™’²vÞR(DÆÂjAc6&ò‚#™gxÍ8ò‚:ŒN(p lŸ·C ¸€‰C­íˆP)äJgpˆû½3Bàú‡éd×w¬ÃÌ]Ë~XÍÌL1²:¹™…iq4­Ô%ÔHíà(zm{#vw"¹‘13ŠÉ2 Õ‰³B^̲PSˆT6€‘¥EœG"¦6„R¤(+2AäPš2ÜAæ(†BPpy ©îcªÈ°¢„f¯¶±Ü\óæüRÍ ¡Nüˆ¨2ö ÷k½Ü¾KøÅ×Ze`H£ *òØàà]´ï­Ÿ.Τ¹:¥)†mžÛØÌ©ûáß}ôƒ¿8îùlšÎ×k:¹üíÍûŸ<é"–‚Å<.0Ÿ¦áìôù6swqððâòámœÝAøÈGW‡wÿ^Cïì&~Їg¸ú¿žÞÿ«oýë_oðë³s{÷­?÷éÅöâÍç‹çÐGcúÓ”¬w¤‚¡˜Ü’ˆa!”·žyºÔÞ=äHXøÐAæ^e–³QÏËäg†èˆ©ñËÀqžÎèéGO?x„³£H`»eþn¾¿ìÞh»øP†Y× ’¨E<ù22¡ %0Ï s.ÛT$9»n(ÍæÍÒÊtv1NS ކpUJÑnTó ÅÉ +AÃ>Å—,RTTtrXXšÐä`Å(C2ÈÔ2Ú_ñO2­šˆö‹ðµ¨Ã¿`ADTe/®êYÝGOKu6·É5;oxØúÄv9ÍÈ{•Ö)˜;t‚([ÖÉ1Vë:i¡¢F©\Gr$"óдÜÄ,2p ´³™L­zs@$Ì.¼ïôP¯Tf¥¸wo@±P$nC³žYƒ‚ibt&³PÌU)ìWFw@Ý‹C©†í§·¼÷byÕ^Œ,UgŽ“šJ€ôä $™ª3;P¼g2Ø9 ¹€hAsÈœÛ ÁÙ§’“gwk1ĉ­J6•SÇ`rªç){‡ˆ AÝI¬âa-B"¤¡ öú)1{;à "ã ÈY•0[.€‘¹0H$ŸŒ6 'ºÆ Pp "¡²ï@Á©iêÌž+œÕèUç©£¨ð‚/ã#ò/äPÿÃ>¢—;¶{-æ§ùÔ/61_ü¸_Íy~U3"33«Ÿ«±{6›­V7ÃX®¦¡ŸŠjÊÓ®ï5¥a·†Ñ’5ÔF Jª¹¤âÛ‹ó«ÞæèxDÓŠƒwÓΧ+íUG5+Ê5Ä$²E¢¶Š‹”ÛÐ.£Žvµ½ê1,šål1×äiÌ"¡i:˜ÂÔ¡DFÌIÝɼ¤LqvóÖÅbÆ÷¾%+!ÐÉ¿êž;tŽ,صÞÛX˜„ñYf…#0ÃE8rÓtY$jNf`XD0+@1/{Âãï­lŸ 8÷áó©ñi‰@…Ñl¾¼wü6ÊjÀ´køƒÇ'ÍaäâýVÎÒfò“Û«ÕRâ0åËÉo¦a‡n•–¼*°@Ö÷!ײַßjïEF*«å¿çÍ“c\™•Fæ §[ÎóEÏö7?ý›÷ä§ÎóÒßók·¿ýÆïÊåUY}ü«ŸM½•©´Â3*­Mç«v}÷4~Óo}w}¼Ú„ÝÄ7oÝ:õíÕq¡ÓùÁÇËn7µööí¶yYÐk3+Ò¢;¥  ¥Ì^Ì‹R2È'Ö)‰™¶bPÝûê .¸©èó*¥'bq"C!Š$"1R#õª›LÜê0†¢¢YƒtJý¾JqóbÚuÜp$D î¢Dâ]ì’¥-¹æÒ»*Œ……b€3KUàª+ŠkCÐiÕáîªÊˆ„#C¹ÔmŸ_O*IX@ ³”C’ Kìêp·¢MBu!uWÕÚ¯S)Õl®¦ÎæTPÓ8È­òåÈ]ˆ+¤‰" ªPUE*p5Êîh¨%Dâ`‚R  1nš–Hœ‚‡VÝŸ¥±aE†‚«mÀ©æG•:rf3Vb#11f a2'Tê8’2!D"¨;¼p5ïQFÊ>"x¬€}®cˆ¾°DÙÈ*‹\Q¡Ö n¾;OeˆçmoÑ|¡À•¢í0å³ß|tþk•×Û‹[ÑËËÛÿô§¿ûÎûîÏ¿ñêÝMw¹ûèßøš-Ï#ùó;zÑÑUO}xpÿx—žC·%6’‚öÀÕ'ßßMÎ|åâU·®®žþÇgÝŸcêÈÍ`§¹ŸÎï6q×·šÕ¼\^œÄóòé¶|çæ“÷wßùÝᣱÙaõÈñ(áÁ¤Î¤…Û!’{G´¶ÜР€šæèh™·•;•õ€ÁçZ‹AÖè&|ÓTOšj•½Í÷”zäŠa¤#´ Qp58Åi1õ,²DG6é«ÕŠ”zŠ“’X‘)‘C¨ DâZƒV&%òq}e?V üS¹å^0*ÃÍÀ¥B{ps3+Ðj´ò¼¥L,Ò¹wÐÖ<ãÉ(Ãó¬Œ1)Pà`Qx¨)pNL-8Tââ&„„PP*£z†Yr#ß—±s jq >N0B…3Œ'GæVC”t4™K˜Ž×Á} žÑ×¢ZÇzl܈*ܘ ì&Õ "0ƒ±8 'çŽ,‰Å܃‡@*¨ VXÌ,:¨Ð÷PõJFDq¿¦8œ3Qähª.`gqf0W3c¸»@Æmˆ•³1#¼ä«0² 'çIxüG8PXØ\UhDpP€ɘíìkx$j8¨H U…Й:ù@gÆnõÀ@2Ö9Hp NðÊÄ%ŠÈl,ÊvèPÆO3ý¤\ÄO>iñßòóÿ:kî'¹ŒDøKý¿ÿPïóËkº†C9÷á¨7>%Ô\‰Y"sGž·óÓ6´Õ·¹ë6]?l6 AvtÇÚõ]¯.j&¶ËžN±me@jqt´l&‹ã*éÎò: “£yŒR~óÍoþwïâÜ&WéôÝGoõ«ÿð[˜ fíÓû«W)üÁoýÉíD™OÞ^<|ïk¯] §x!“ä±ÔT"rDÇ„ýµOŒý¥¨í/Ãè‡ m WÀ{K 7So眚¶i¬äšw¡TS÷¾˜•ZÁ^ýè1<‡kçG¿C!'‡ÚXû‰LȃsÒàÊo>x0“ôÃ>ÚŠéWfwâ¤ëÒíך6XÖXïëýýsåVJàZÙRÂ$HkTÔMH‹ØóMÿ??½8}óÕùÙÉ‘~{}Û­Ê’§2F© ›µÞ®(ÔÉõóáßýÛßùè{×Á™—ÍìTdæÝå¶ ý?ù¹_Z}øy÷ì2y ¤‹æütytŒ¯Êüz²{¾Zlš‹w^»Ú<ÍG›³w\¦ÖÞ?~ý­‹ã7¶¨»õ 4‹UR”yÌ7#®œ `7rw+¬Ù•L{X1(‘C܉)ˆ\ ¯bXÔÝØ9¸Æ‚T•$" ” ŒP ¦€“(b1ÔâÍDì0(©!Æ^…‰\U»Â{xoÌ!îæÙkEU §x貌Î~fgwsw(îf0wy¬#46æe’@Y½% ¸Ã¨Š)i"…i8n T׬f ‰›B­ŽOPd»“™AÉ / £:êh3b!n(Æ`œMµj?hŸò¨¦j+1D!(¼hV­`¦4kB` ˜›3¤`­›Uð(V‹âÀ•ÅÁpçS% ydD`c=Ü߯?f"ªœÀ4‹Ó¹LZkVb=<0ÃÑþÓù£ÀÎæ:Ÿëd€N€YÂk^# ítB‰JEˆçxºzö®_›ãxÖÄwß,ùÃûÝö•Çè®ñðA›ãÜÜ×^úœkÐ^ïó'ŸÜ>úÚE‹†Rî¯.»zÖçÙùp\f—w=”_=E¿Ççÿ:ãýo¿þõðƒÏêÃ'øùwׯûû¦Òù‘O›£ÇmZ èå\ä{ÛÛ?zÚR8Ʀ§Šº½Ç'ߺ*·ëz*ûºßÞAnAÞ¡›Þù,ÍŽO6‹£UæÛÞŸ¿àOh*ÍÕó›~pùüc\~‚Fq6ÅQÆã„÷&x2 ³@’-ªÒ¢‘mÞe³ U¯ïTÓny¼à³–ú2miÖÇ44©îÅ´ï2f¸/=íú©mfmšÝÝ­Ö÷Ž)âÎT`Eœ9T¦!׬cˆMòR´j!²žK·©¦²@Ø5"OÈ‘ ³©+HF‡Âøär(Æ*Ìñ‰ö%/ /K·WP×ê¾' NTÍ–¡Õdo¥÷"˜Dã±RRPUrƒÃáP…• ‡Và"…§\2¨(ÂT"(”aµá$#9‚ˆ™QrN‰›a'Öâ5Sypq i¤mb;mÚ¦@¸è UQÌ­6R› Ì æ03 l ¤ÑžGgKn1!¶. +u`XbJ"d¬xƒ—’àÅÝܨ5`««FG"ò`=sT°ûȤ':¸øtˆG HÝóØŒ«/æ<šªEXMfnƈѬí|š‹thK{m¯ë»º]!–‹Kš)ú~ȹZ#"„Y-¤ê0¬»H¼í}»^ß^÷ä˜4LóÞÄP}»éìq1ieÒoûýͺ}3§ç<—åé<¤6Üêðù~Ød¦2‰“8l'4m£lC?€1‡éƒù–Ww·W¹l›‰œž/—GSav›·wÚD»õ~ÚNÏÏ\­öÃî~R/–ÓyÛØ6w¦M;SRáý uØi!°ç¡óÎŽNÏ™¥î†–8tÅh2—‰&ͱî‹g;8‘ÍÌ_^ˆ_8MG4&Ü¿”iý?)æÛßUÖ=~Ó˘²óaë?áïë¯ü›¹g‹bjœ ¼#²\1Mð äCë^KúÝÅ«~»»êÿ£÷ðìóål˜½ñè¼)“-—øZ|ï—Þy°\¬?YÏïÎçÖ^”‡7ë»[Ý )@šÐõ|@MŽº.Ò!Df˜»™µ1…&yV¥ïX}¹ ¯Äo½öîÉ£7ÈmuóôòýoëúnõÉÓóɃT e£rk¶Gµ@8°s®µh• Näd4š…\a0Gv@ †)·MŒaÓîððôøíŃËõ}{ŠÔMwÍ©H'§Íé¤ã£EO—Èn+^6'W/îíÓJ7@¿÷Uƒ‰yÔAjÒz²ýhX¿r'ò¯¿^·rõú¿þ/ÿæ×Þ~òÿÕ»Ó·/~°úËa1õÑ7?ýVþƒÿý÷Ï.SJ'C¤»WW“üÉúÓöìô¢;•»ÇWÇ_Ÿ|åÑlj³z7ŸM7ó·¦óS{ëªo=‚d,ö³üØ¿uõýù«G§éû?øèíwÝÝÞÏÛÉ2„ýe¹¼B;”eBìp‘æ}Ow¸ŽÔë„áM|öfèf³IÓ^(NŸ2]wýÕÝòަOåî¯?È›^b{‡cÇá(ãMà½Ió¤mšÜåZr#Vê:ì0o!­Ší tÁy²x­[t>íNb×^çvå<…Å|E÷qLRûøôzW:ÌíëS›ç’Ëf˜œ¥ÝTn¬_­S( ‡2‰ëºßªî Úž£)˜$Ñ&ªMRžG-0TïLM]«j5s¯¨ZÄä¤ý¢‹õoµÌýõ<…1e &N1kï¥%²Š¶:°¹ghJ–¸zÇ3x—Ãâ””Ýá"î‡L̈¡`.L!7@*Ö8¸Cê12f^R@!3‡³AšObHc&.Ô" BD„ˆ‰Ô÷°Rk ìÅóÑl6ŸÍEÈyÏ2ÚJÕ¼sP;ÃÁ+j¼GÇÈäJaÔ€l0Ï0=ÅÑ)-Ïp²À|‚T´ÝîÊ]Wwš‹”œ¹-S/NVàp ZRÛë@R#’›‹{‰´ÑÜœ F¢dÎcµcT\̃Y¢€ëÐ@DbvZ›¯à™W¸;jq3¸@lôE³b‘@*T 3áŸáXH.ò‘ôž4qJ1 ª›ÚÛoДÝVÆÏHÕ&N£bbanƒ3bHmL\$dbSBÌÇæj»š©z øÙë8¡þÒÇĖt6Bl\]Œ[÷iá1gìg‰¹‚¦if ˜Öš‘wõdÞæ*,xofèU‰z‡‹Dò®Ö¾–½²!ƱéÈ«U×1âZ=.Z¼ZÉ÷CYõ Lšåb6}0Áij %fj¹l¯ ŽITuÐFš…ÉÉ¢=NE»ZƒªØP‡¾g PªaUQu7lPRÆ(1µÒˆ1S“šÀ­Ö¢b<0öº½Ûm7«Æä¶+™ ËÅt19b}WwÛ¢e¢= {­ÃËðá®Æãò¥~â?¶¢øÏèEÓþW„£/¯9 —/~¬fcÑ7.â¡á£…þÂkááùú׿öÕïÿé÷õz3=ooòe×Þ’<'Ž—Û ïíºë“Ô^g ÓTL‹ôp‡^¹N„›SœÆùî{eëýýýzwßÅ_,[…ìv,+#È­9ˆÀ̇ 8‡ª»„Zշ䘶8y°ü…_{òK¿~úäââ8ƈauûñ÷ï?üÁG¿÷ûÍ^õÙÆ Ýþ–f(Õâ®e,—³ÑÍ ‘1 §1Kß§<ÔÍn{Ôû+Ëóo<|ólyV©¼{C'rXgûÚÑžÙ+D½*w,‘û»^/±äдó&´VÑéлf˜j¨/ê”põñöó>yu‘Ê Ã☞„ëWÿü·o_Û5ïüêo\Ëð;¿ýÝïþöÝúiú&ZÜzs·j}˜"mƒ^•ãþhRb¿Ù~zù|ú8¼úËÞüÆÃå»Í>[Lw”Û7ŸµŸ´»ßÿÔ;×]óáe½LgÍùéòô©Còsp!rMÕgƒ¬1|wõù¿ûèâ7¿òÞ2ôøàrõ¿¸ýCÌ>À…a‰¸…û­¶ç|\êpsW®l5T>á+[$äIuâý°}øäh›òƒçùi‚“ÿzúÚï6å¼þÖìþ亮|Ç|x_§¯âÏÿÕ·é_~ã—ßù§asGØŸžŸýååóÚJÛGG“þ½åŠ×—ãô³!<±eBa:Ÿ.Ž›96}¬åaÚÅ} ËÃäþ~òi)Ýn?épÕuY|êµ7œ¯1^Kx\G>f×È›ˆ«˜6‚á¬{ÖÎÉ(ºq¿íïo»¼Œ˜iœOUÍ@9µËÇç«éuPç)Ž6°QÒÁœàƒ:k¢IM3mXa¾¿ïªu¦ ±ÄŬ£’›»ç<ì2u(Ýb–vVÛ–b1°¬z=Ðz€1³>F?5?åÆ*€¨˜8 d`ªäÊÈEÍ=‚«k56@|ä_ëøêÝ£Q›áàÑíö²±Ãܨ|ˆX ØÀF#$ÄÉ9@€B§ ‚k<È1  ˆ®ž¡Np2¢$óXÀ¥ª©V­•b[ÏB¶µ @kÚìzß H@™»hì ™",Oyv!ÇGt<­­Rß{¯9£‚ ¦ðÊVæ1À|Ì:&K‰œ’©;´¶‚”À-$DÝ€ñïŒl佺³yëÖÀ'I„w¯N®€¹;ùØÿ3 ÎîÕܪˆ+ìðŒ›\Ì @d‡E.Ä8)Gå(Â`uÛÛ Fo‹ \_R\̳!cÉš2;sgÈÜAzh¡†‰9Œ~6ýC`Í 8°G˜álÌ«º² ™¦v¹uŽÒu]é¬Ûí´ú´žŸ.fµÛg¯>:,ÍL(°Y©¥h%¦ÊC IDATAQ-e×ˆ0›ÍDÆâ@u«†±èÃó®ÃС³î>;Lgˆ’fÍâdyÒÙ~è7¬<³Úz¼” × Ö›étÖžŸ-N&ëýu%SfVx¤›i< dÔï C Éœ†’“ðühÙˆŒÌücÓ$ ؘnrßLæg§ºM¿î†’$+IóÙ|š¦}Vßœ{Ûï†Ý¶ ÌIfÿ²Þ¸Ÿ½^ ¼?&ÙÚè™s6 `ä¢*WMsÌ_ÃÉ{õWÿéôøïó»ÿ×[ô¿}»»¼ËW‹4;_íÃnÍë£3äþù£Éž=ôø‹ß{m2+:¶½ÞïÖ›Ïöûûuß_ÿEÕ¿òø«˜¬uóôæ>/ÞÕY¤Ñõ8VYÁ™Æ÷Y‰Œ¡%˜a`¸¨´@pô¯uþ ¿þÚ?û§ö "D~ÝÎìš“Íû/6Ÿ~ ëÜ6&ØÆew57"ˆºÆëQnEGaaƒšwiÓ´‰‹““éÙñÍns×í6¹ï¹TafvåÁ*ØîƒÖ<Ð"¤{÷ÎÄ8†Z-gÛךIƒÅîjŸ”ÿBÊå¶{ôæ6êlÿ— >Ö‡¯ËîE§^ö«ëÊýþñ'﯊žÅÉl™Dwq»¹XMÞÝŸ5Ë}·Î«{kµŸ×»á³¯NçïÍOžÔÜn£<]¯î’/ÒÅ“&í¾g›M¿îÂí·žMNæ§fu#qrpÒ§¦ÎÚZÌQÔÔL²+6jIˆ…˜Ø_:K @¡ì!Ä9Ž•wŽ¢@-T&‹£ÓÖÁ†ÀÓÙLC­)hLh'Q°³šNCbö¬µju… 6çâ À1‘Y!"ç\w…‰3SP"b \ÈŒ"G PeÓÑÚN0&b"bòñY;¶ êv î.tØä¦ Z]wqAï$  ©•¸˜J…P¼ŠSRPsÌÝ™94 3Uó`ãÙ™‘Œˆ,f6=T‹3ˆÙƒp€g"ò±]’\ÅÌÝȉPÇvY†UjΖXBHªêÐ4‹d*yF­ê5›I±n§"Š1ŠG¡$ÚŒ@r¸òALãAÄ¡vè!7¼Ì %¯`QÉ6š•y<ǘ 0Xíöû}pÀÈ_.ÿÚZçï)ƳÐ.Œ Rkf;Øwìé¿únzþ¤}$³ºßru÷>úO w°3l÷‡“~®ï>ÔºKßÝéSêâ²o…å(­û×7Ÿ™â„ód–j‘FCØU•ßB{ûwßy–ÎÞ/Þ?¹øî=¯<Í(\lÈïцø‡ÿºÜÏ®ýÆÛüùŽfåø½Wï,®í%èÉL~éìùk«O¿ó´ý0Ÿ÷ºšaºãø.Ž5/šý¾1ßwÇ{o/»É³½¾¿ß~4\_b׃c]2ᵄw OBû¨iŽ‹kLÖM¼¶ÔEÎÅ < wì(ÜJ{B̦Ûîne«2ØT¦sŽGÖ 8w–7œ¶Ï–ÍÖ‰æŽÎ÷ªwCi'“¡¾U@£i¦KñMlFžÝ¬gÄ`Òº¨ú UUU±QpF,žJÏ=3‘ÒB¨†Bª#ê0‡’û_Iu~ÉQ™€CPiÀ"²jP  ‡>ð¸œv ˜/u)ÆYhl¨=ÙêpƒD ì#OÑŒ˜ÆÊFtÙ¸4rc@ ,€ÄŒ+ ‡ˆ”(6h%A¨^M¥‰CÌ*@h<°Â«™ÕjZ †˜)¹YÒNyÉ1(Qiñ¬Uà‚ V3D(EžNš§I‰ƒå.UgójZ”ÈFß!&odÄ´hkܹÁ¾(vÔ»*¹GP™P“XñX{t`‰ˆ#P'3r‡¸L‰Øtè…e2›ÄÀîº!ÍRlšÎ†ÝvèÕ"ÂÒ„vÚð¼,ÚÙÃóónµ†Å»ûýžJíJ²´ím¿+û=J>Œÿ£~ðŸŸôw\Wô×u#úÒ®?‡p,b¸*ùHºD C`\”A3Ì.ð‹¿Ù~ó— üé/þê›otn¯ÖGt¶ßîn&?Ô¸oâìhÏ—t{“'«’·ýþÁö* —Û»çû;z`«²] ϯžßg‹¯½öÆÛ˜ïn>ÈÝúF„d-gCv2&à®cáÉX^ȉ(„Ü#-qöÎä­_^¼ùÍ:?_9º²_´Ó ìÛÓðèë“W>®›Ä7} ½¿Û† &W£ÃaÏÍ‹B;ØÙÇü+;’„ZKéëd’ÎO>LS(?ßÝ~õìÆ»U(C㕜„Ù„JÉŒ …*yïÌ„ rïŠVíEÔ=—*îDjÔNgMlîﯺ÷Q†^ß½ßÅ«ði,çÓvõçW¿ÿ'ï?­÷÷ÔF<,<Ý9‚°xï¸Í;\Õz³Ýw˜¤23;¶>•å×9|-ÄÅNËçófßoosPYäõnû—×<ÿ~Þß ÷Û³Ã&——OÎÊ+˜X;ñ²QsH5R2œm$ 8¬æ\ó·û: ¢DÄTÙUF¦5 "”Èyìû3ëXâ$¨VeE”f>‹Ó´Ûè:Ÿ–Zª@tQ¦„J¥ £(T´À«»l_Ô¸¦@.‚jŠ[ É›sµ`*îÌÂXˆÄIÉ„I˜äeÃ/¿|À³CȈÆÅ!ÈÈÝ€r0‹Á´ÄÆ\)<*)؉Ð0Ÿ‰ø¶ðŸ•««ÔeººÏ´ÃéG`SÓ¿óo7oŸ”Ÿ;:I:¹û¶}üÑݾ%~åhöóëç›Ïžéí—|6•0©]Ó\¿XéÝv¶Àã_YÌ_}õæ¾øà/^ÿ8.ö7çZf Óij¼‚ËìveÑWOÿÍç7zý8êzVã÷·é›ä‚öâ«ÛÙ¼y0ŸïÙ]]Õ¶Ù6óI~8+ç'ûÙ¬«»ÝvûO÷v«å3힟bƒmE!D 9^mðdN?oÓ½Íú¡Ó\úTöÔÞÍB-¹l0-AW±«j\m*tBÞô}ÿ¼`CztÌ“‡‚ÝÛ–7õq=9ŠÜ·¬“ “Ò©•Þöë<„ ³TÏûœÈŽà °Õù"Õ\®µx-–)(Ô›:Á&ð/¡d¡}F®¬± Z;XqT˜AmJÉ@æncò—yl}‘i †l˜ ™"(8’dYm@.€Â@¦ä0 nBvÀ(Ru'ráÐ$/|°ÃŒ=¨`€™Æ¾žZµ¯6TôŠf°º·Íº®6¶í°/ÈLˆÇä‘*·Ô¶Ô4ÒÎy֠Ѣ«ï« Õà£@Ô’4’„qJQ{¸Ç:4‹ÜÆYÌ—g?ÿdõþüöÓý›oÿ.·ú¬ÔÉÓï}ˆ¼¶®¾qz> a}¹æùÑÍŽŸo+‹"WwÏ®n°Û áÅÖ›}]í6“vJMöëÃÖí%Ê‹ˆØ} Ú8½lná…ºñÄgqùÞ“'ÿìâÑ׋‰v÷!tŽº|_N.=yë¿\ßNíÓnRÃŽžW/ZT*"„lÜàºÿ˜p Á‰ÔPˤÑn×ûû»Ýe·ªSÁ¬áÆÁêjì„*±GTT2##¨5°Œ ¬"9¨Uã¹r\“𳓗jZ8ˆŒœ›¿!!ò÷èŸùqˆˆs)UëXòØÎç³…•Y?£‹îˆ7CÙmgÞ¶s³Eßœárüï{}öiÚø©ì¿‡Ò»ßÓöl²ù¨øÊðúëxÛ'âzÝmïYW)O‡¶i­Ò]}qªqÕ/¨ÞÏ#ä(òŽ(§²–>Ùx:›þð¦>ò):Çî·“?ÞêÏͶSßNÛÙñf1?}ÏN½4ûnw³ö\'Ûž6Ïö·T¶7÷«Oï¬óí½ë=ø i…v1x»8It1¬ŒÉ¯OO²ÌÊ…â4nBîšRæ´?M7g²%„=¦^i#zäÝJýn°Rç.ӆޔ– ò5¯—½®¯·ØY4Ý]·o.d9g{…5í5½p»Ý‡f¾JÍý„£¢F_!p¥£QC>À÷h€¹$ŽímßåH¹a¯B¡*uÕ÷Öï·EY«[eW3G5/#z™½£åýo»"~\*ü"[p´ÔL¼uHp‚š€Š¢º«¡’×q0ƒ‰)xŒ.‘ã‰5Œk5­ÆB € S'¸QÙ+/+eÉM`;L[ŽØ]é&-{=€¿…Gòµ›¹0Á# Æœ¡fµZši<™Ï_;9{k²h÷Ìš’ì°ßTh¦ˆOv;îo:ñd•­T®F²;+Xh¬Tƒ8 9ƒ˜H‡Ü¤ bNv³½ë@Í mˆ×y'Ói¡2ª)©;°§ÙMLØS)JÎæÁxjÝôV˜°E‹n^€­ï-l}) iÊ­9½ÿâó£åôÍ0»˜Ìflmuk«Çï.—§í¼™žMN|vùá³µm—Î6‚uµ•™ƒûŠ¡7NÜ6§•™šÓ¾ÊU·»¼ï§ËéÏ}ý\¼ñ ?>yººÛò¦f:*éæ.?hÑœÊô‚æsÍRɺÂÎÖj#±¹õ}^˜'ª¥ÎF¨x´"¦Ø©8²V+ A›l1SÙ©ª»YYÕ«»ì‹Ú^a @¾Hšýý=¢he2¥¶xPP1¹ Tx…»:ÃJ†ñ"Ž ±¡˜<p¢4ç@¤p#uPïª6¨å ¡2™0ŽC! <"¨áÀ“Ñ­¥tXü?ì½Ù®mYrž÷GÄh末ÙÍ鲫Ê$‹dJ")Ȱ Û|Á?‚_ÄÏâWðøÊ6`]P4a‰‚(‹¬.³2ót»[ÍlÆዹOU«²¡ƒ×Å>À>û,¬³ö\sDóÿÿgnv8!Äîå©O]C¼)´ ‘Á˜›™š›¹{,:´YA54usVÎÆÂ”ÝQ)¬omÔé~y(>¡ñ„ÓÉN'œ+UÀg¯¥¥KzEÊC6a—-¥ØÎíÜsž9V%†÷ˆCH™C$NëΘ ¦ú®‰u6‹¥DCg}FÈ&É‹Í Êv#•ú¸ßQ8ÜDàÇx,<‚šVÉÏ*ÿaØJ€%2›­¡Þå«™­º¸.^‹¯xÜÇV ÔAÒú˃*|‚ºVuFjˆyÀ¹ª7…V++çð;¢ßxåJn¤Ô0 9ËC²ÐBÆi>¾zõyèdZNÞ´-Þf2%q0Õª•KäÈ&‚¡µVѼi4DĘ˜@HADŒŒ$0àlÍÄC’5¼‹ +U¨–¶0³³m÷@;f' Ô ©€C"ääDY@~>}ÔæJÛÝå~»1èÃxž§‰ÈË4ë¸ì·[W$A yYÕƒ„RcâÒ¤¶é0Ÿ;/Å•6Õe:k©´4Ÿ´N@ÅúôâÙÐíí¼´Ù—RgÓÖtž¼¬Ñ7Qu_­ øÇщÈ!€ØZ>‘®“/v¤``" È<}oýöþÅUMx¹àN辿¾Ü]í>ý÷¯þ×ÿåÏ~ïãþú‰·«»¿ÀU÷>:Ýo§×Óëòåç7‰>ÕÝ·7•N£.gƒl1J·ì¶ƒ_¤êõx¿ˆNƒ£¦Vµ©7%Gbð:MPâÄwû,TXµ†’ž>[úÍìv<ÙïAgT†ÐfÂà /oo§Ò&b/µd bˆ6D"P€¡Â¤îâ"1sqt)7Fóv¿Œ£Z×|#ÃÀb‹–YµZÍF±¹5ÝDˆIj‘ZÒ–¡°`ejK ªki§ê•bamº{ÒU_6ÛÙdô. ïãIqºí²hÚÑE Ïžäç|ØÿÉÿðÁþý-Kgs8¼œ~ðý›Þ|~Y'KoDZ\\—!ŸžVø!²]>ŸM¯>ûâí«{Ùö×ï?­K÷GÅ]¹çĬñ¶ó‡ÅE±Z‘W3«‘«°8³1 þHÔa!!1ˆ;»Bye_„ÀjUÀ•bv!䌜ÒEÜì»ÝÕ ýN—…&óÌñºÏWÝ@½Îࣗcµ³êl¨Ër½ÁaÒÄÞ=æÄ$*Z®3ª{QCÓC`r‚­ f†Dko­ÊrqnÄDHeõQ¯ùR²úꜘÀfn³P $Ä‚¸…®DÄ.v]G ÍJu…3Ê#PDšWV d»W’ÇU‰»™˜ ˆ•äÌdàõAÁÙc”]ÅIØÄÝÉ N(­¡:<œ˜¢›¸š;$0h¥ ²3A8ôÛ-WU©f³Õ‚æ¬Jnãi¢‹lÄ7îCÌÙdzòZL*äB 7Qg€œaŽd«|Ê©”Y‰ÚZ@:k³‘¹€V®âêÙø/žTý¸)b0Y$˜·T}¾-úziW±t‰K{U_ 6þd›w/vxpž/k“mË~ªF›íÜïw<ì|vŸÎÛ¡\}„«‹ ‘øy³éÓUØÏ:cËñž°ßáP_în¿õO7_¼~»û³”ñ4Vÿ´Ó»ç8¾Á{’v9ŸDpáÁÚÃeÀë„s…Ø2ŸŸ"Þ,xX€ÎõR¼‡ò_Ј¡kxÂø0å¤"iè9ð‘Q‡p*­”YK[ÄÃ8"¾ˆqÓžµ îÏ:í:Ûà 3yNŒ`^—Xµ`ÁE‡aÛ7â"<™4¿Ÿï7Û3 ­ ¥.³o3–SM£\´p2G™ó¢)ÀzÌPfhn~lS=æMŽƒpQSk°&³³6öÖª¡¸V"#&–u¼õ ïlDú J©•Áð•q +àH!eëQ¸:’H fTYOu¡A ÷)H!yì¸ëzê‚Ç`L«?ÅØWâ4‹‘I¨îÝו–@äDPQ`Žî£ƒ'B¤‰ÁlDæænìn¶ê¾IÑ 5 tâd´âÌr”Ž¢jfqå…0·¶3mLª(c9H²–lÅÙ¹Tðâ,&ªéˆÑ›Ÿ<¼`™lœhQopƒhB8c>ÙœÛ)›{óR|YUm¬É 䀹¹:3 X™YWƒ& ztÙlù¢ó!ª™‘׊æ. 3v"'‚¬²9{t’èãÞ„¼®TدâD켪©Þ©v0¸:TÖÜs’FÖ\«·†¶ªÝÙ!q¸¯·G4ÌHöœ2-Z„ k¹m0­æfhƒ‚øwDE'ÌœŒ”8d¢ˆ‹g;’æ¬æåþáN& sʳ;ƒ<…®K¾˜µeYI)E›™¹š6T¯Z¬¸ —”s!˜óJàµY•Ÿîdºú×Ì“d‰‰H+´63Õ)IF%›°“ ¬)Y³stWf!õRkY/ÖÈØm7O¯/K™çóaÑL›Z¤°Ûì/†mÓ²ÝnÝu)šû”w›>&šÊù¼4=ŸÂqý|<µ©t!Dð\´,  ò&nö6Æz8Î6U+óR*Z[ï¡ëÉ\Œ”y§TÿÇǯ±Ãtd jäïÖM„”²7nÎîmõì7x~¹oÏ^¿÷Æ_nxøòáÕù›ñwþÓÿùFn/ž}¸{8žøeyú͇øüéÇ ¡þÙÿörº ›C¹ËÞmöã+Ò¡¦-i>äJä'r+2h\‰ôHáæ•qïpp[Ó9E$:“™ÕÕ΋i±{½ûìõ§ß¦ž] Ï÷ã ¾í;«ßWä IDATñê{ç—ßù÷ôö‡l'Çä­Eâ ™[µVa…%r{t¾<šJÖŒˆrJ1°“ˆSÐÚÎZ–rž_´$Ú²,Z«ÕÙêŒý`¦EC1ªŽæˆê®£µ7ʆj+µ¡FwcP«Õ„Íy<·¥oÞÈtw‹Éw½xÿƒMXÂÉkØÿ‹o>l¾Ø~¼MÇ;œfÖ×.´DÓU¸ÜYÿö‹Óî^ÿÛ›åÿ Ç¥ÕpùI±g9<ï)]² ôåÍ«‡ùðÙëÛ@×wËYƒU›¬ÍÃ.¶êJÖD‚¯H*ØZDtAkuYf]*!t9Ç G7·y }8†»ÃÑ”ó°Ý Ke‹›~û$PºŸä¼,elj]7\nãEײm>ؘr=Éxæ{è£moÂvõûàKͶ],Óٹڢˤ®@&rˆ!X`ƒ3ÈIŠNkÜ5" Õ”B¼–n ‡1 i¥8¹¹ÃÄÌyǪnrNý¦ü0?”ó„©@R >Rj®µU(Å)HKF=…ƒ%so‹s&™Âcúèú€³BypƒCcnÍÌÍIi> Eº!‘‰Jk¾TÉFï(jªªÍTmÎ*Vª‘)œÉŒ@`§(³GodŽe^eDÙA®îDâD¼ œ•œ™\¢æÁIàlÆÊ.,DÅ`n1±HÈ1YP1~ §úM" ž*ú·8~Vm+Ú"NÑ ™Ñæ•k£¶ h·“\/uêRB>½n7?¼Y¤¯Z>þÿd÷®/TkºiÒWM‚L­i;À®GWìË»rŸ^oßûæø²ÝÇøY8|Ùî¼ ¸»Án@—e§Ó2ðJܦc;–ãñA­-U§eÞô›v®v,¢Èp4Õ>#%\]?_Çûãíi5œµÝæã}iGð#ž—ÍL8þâ^È ÿ ÖGÌ?•‹°þi3[1Ðï>‰?¯ºÆþÔ…º&\}õóòÕÉ»ï|åò&P5ÍW4ëðF¸…¹ªÊnx¾¿øƒOþåG;Ÿ§/6±‹šŸ¾úöþˆûþÍwÇŸþÿöÿž|p;ߟçÛüìã'|µÔ³½oŸM_âù·og7Û óÛ£–‡E¡¡”¹(_ö)ìÈQLÍHØ–æ†ÙÄT—V›*k×aq HÜôB|?ß¼½þä¯ÿì¿9^|ñ¯ãÓßüýKf¼ý¡¿úîwï¿û×øÎŸö<±¼jÝÑ9XáÒLÜEŒ«Z©x«¦Fë{h‹Â+¾ñüÉT¦íåþö|¸=ž?}»îþî6Cg6Z¥avÑÐBBÛí~~­›®ßï®ß¾¾;Ns ‹1:¯áfóŒH}Òq¢qÆŒ3YH1 üùt>>èÓ÷ž†¥¾·ß¥å<¿þòâŸ~Üvé ¹?„zèŽC·¹¿©ô­Ùt:éžìŸàÒÓay¿q(üïþôË{»~ÿ[/~ï[ïw/–ôòåÛ¿úÞ@ùÕ«W‡Su›ã|€¸‰uL‰ë8Æncµ¶R‰Äš]?¹:ž]Ê!FÓêÉ„%·VC—Ü­j Œ$hÌ«ƒÌ«5Gº´}²½zSb=—#JÚ‹n›ËÈyîzé.úx=È­w°™›Ñ]ùr€×Q+G®°Sc¢¸•ÕÛµ…ckÐeÍ ·q.Þ$äžrjÅÝLb`SJ˜‚5ÌS-UýÑŒ¨ÖŠA(æ’U›¦3˜9„®‹”P´Î§9v1æHDKY–±„>²S[Õ`Ä6.í¼ 1T²JVUÏG8ÚU×õqž«1$€¦º y3 Bb,¥´6-SC9tæ†Z`Ž”6›á4b"*ZUkUupà$†ªµa.!v\­h˜—Z:‰©Oµj›«5onÖlèBîÓœ|BAr1pæV°‰Ô'oµ4XD˜›9Sª^º«í¬Û«á<Ÿ‰¨ï‡¶7‰]nçrº?bQŽ0+ÇV7RJu=Öú럿ô³ü ÎŽˆ‹©Å#òKøÿ{¸aB÷»]z_Zò£w÷ŸÞ=;Óu ñ¶¶Ãóðùt8‰m¬È{ýÍiúôŸ>¹~;\l?ÅQ_MýâÆí<þ«È¿ÞÜûŒ?~Ö•ó|˜ŸáÅöÙ+œÒ7ö×Ý¥y›ÞËß¶Å>É—¯\>-ç{=ÝË„ÔÁ3ö»ÝÅæiÿp ­Ý³žhÐX— !¯MÖˆ hç¸d\[ý¸ Ÿ ÝSªW8< ÞÃySâYbb’8Ïe.SÄæE©ìv¡¤ÖÞ.—8¦B͆Ëýùåäw÷›Úõ}¦ëí½Ü – X¦Û8Ž×ϯ,%¨¿‰µ(nï/öƒ†Úí»÷%Ç×w—¾ø<“<é^½žæï~I€^Ëé¤;Ç ¡ršœ 1¥¢{;•›²ÝÇývÇûá°÷›pÿvy˜ÎÈŒª´F- 05ok*òOuº¿|Oø•ÃÑ×ZË €W—~׈P¡A2…@EÙYX’ÅVÈVûIÓ@DZAb }/ÕÆˆëL}(È‘bQR7³æUŒb ‹7tœ{‘-#µÆmq(;›YõÆnq…"»¸¨%ð&„s¤fLƲ˜Ô*zŽÎY2÷±Ëæô¶<´ú@P…8ˆq´2F±gŸÈ'X`­ŒÅf'7rõÚ äÄ^«©F8Ȫ V]|Õ†ûɧ‡ùaÀë u™“åv®£ÂVë»A«;‚€fU(œXÙÌ|Ùì°O‘ºŽ‡Î7ÂÂÆZKsÔ,@…+ˆU„\DÔÝÌßýFÝ͈(HX+æµZs&0‘SE0›¯ß*€€‰áx¬¶)PP®nODÍÙ!Ü)Pƒ7ru †ŠNâ$Ìb`wBó38 10Ký‚¬9ùšŠó×T~þÂqѯÞG}ÝëùÍä0}Çõó+oUýq ú“vYb ê qá2ï.·¼è=Æ`kϯÞ÷éï=SÜÖó…aäÌPz\’`*3H(çmŸc˜s…ßµÓÇúþÆ«§A`G¾¨Û¾í¶œ^•z^Êáô2|˜ì½ò6ßv½ïž¦þàÉ_ýÅÍÞ|wöíÅåEˆºX›€ 9²ÄÉ5UaÔ¹¨KÇ9ÅNœ$Âj+s­Sy¶¿®N¸,%}ñ`'9}qzãÎŽ»§øø¾ñöþt¾Áæ;î±ßÏDýpWZ—›¹Õ2x{¯_t9RÝw»”‘¦|÷ý£A'l< œÚtʪO¢ !ß²Yc/=§ÓXX=+z掩g\°]iû$Ç36°d&` ÀF±WeYtÙöqhšq¼–ªH‡»nw™󴌎}”Mž[[|‘yéQ²±ÇÔCžbÞƒ3ˆçèc"Ò™^åÖ?yõòÍòÈá6æ6.§±:ª£#l/³>ߟuQ-¨ £vŽt€¹S.±oŠPÁÇjôàµñb@Ø£U´³IƒW ÁÚ:ŠÿÉ!nyï¿þØò1bA jamfÌP÷ŠfÂæÜO1ˆ½±`µ^ñ«¿11Àî«§…¡Íj E"ÓGCQ®Ð@œ)uàÎ=û ¥kMQWm4¼©9ŒBÈ‚äÉ#49ØÙ=°Ç€ ÎÔÜÙ¡$$™%AÌeSSÅ0¢.ЂÅÈEd°.7&&¨{ƒWǺ¡U"#w÷eç5lZU×à•WøÈO2>a\ eÆÔ#\’Ej®Ò«LûIìä&þ(*qs2g‡­áoâ$@0b'!IYš‘#8!XCá¾:ËüÿákÁóÈc,¡››ÁÀä1Úë/ýQÆ"^U$ %&ŠÆÀš¬ür¯Qëâ``UÅóc~’GØš{b€Ö ?Á×ûˆÌþÞõH?»úUvJ?`ó÷Û}ÝCUÿÎ:‹ˆœÄ•—æ0ÀBó ¡Cî¢/õ4«7cÞ¸“­‚C2R€1l±BœsÖš-ÜJ)fÙÒZ5m“ÏFÎuif&*穆„)„°ÙôÁ¸Ôì!ÊR먧É&ÊÔÅ$MêØ‚jkFÎZZÚâÅDB¿íó&…$ZŠIXuÓ§i<Üï—e²yN¨Ú´Î¥àt¸zÚív}–¤10_¦y™JÎ9å$1å.ö› é(r…ÎÞM¥y¸?,c©H’¶ã‚‡ÃlÇõÎI?o´†×Ûÿ/×íßG/ôcÉ寵Ã$"ÿégøê¨õû§˜CÈ9Èd.îÕS¯66ëìÈÇ>ÍœÒÃ]ê à–.ë5ù´¼ý‹7ÿ©]’¿ç×xñ²ûòµ¿ÚÝ\^¤k½ÝßÝp×&¶óx8Ýy¿ÃéЀ’Õsá’Ô·®Û….Óå†ûÒÚÌA‰f-§zÆUi.VPIXCX„a›_{¨ŸŠsÂIæ—§íh›ÉÛåÖÂwÿcš?»°;>Þ¾|«C·½~²Xñi*ó¬¥,ˆ“PÞuÔEOAI—ZUUpö@WÛ(4Ú2-ã÷?ýáÃË7D® ¢¶ˆ‡Ø`KEÓØeô½u9»¤™¹”Oò³«Ë±?»½9¡ `TBI¨(…Cc¶ÞfAR·ë÷BªMy.t€Ÿ¢S4Î~–ö¹bÌÇeæ¶ýì/_^Nùòú{w¯ÇSÁTr+ý rÅó…²{»Lxxûé}ƒ\Ò y®.¦ÙÞ|޹ ¾XõªMAè,@ ‚62À v .u–D¥©™µVÖ£KQÌMk#0Q g" ŒjUìÝ´‰Ý.`ÀÙÆþr_mÑw¡µÍ1«³ât:YôÀÝiÈ䦴9¡ÆÌ´ú˜ÈØÕ*ÔØÀŽŽA )p ŠŒmFXä DæŠfÆ0$5!Rƒ6Uv䀸ØŠ75TrFÄ£žfæÕà s´êÚÔE"VU†tCމ¦ã²ÌÊàœÉjÑ#1Á\Õñ¯Ì€ðj àÆdR%²tQrÚ¦nªóR !%"ñ©Õ±`pLºÚ­™ˆ Îîdm±sb‡+¼JìXÖ¹S"4×¹Ø\ܱÔY¥‹Á6¡¡"QÞtTœƒ[ƒ63+Ö`ËO7JÕfõÁƒ×YݵT'm¨Í{écîÜ—2ϼAi}Àë~¿‘M½ób˜Nªyf¹M†1àLÐÍé£?üèûN1¦›ïÌÂuöª(oFIJÝë |f¸™1D|ñ‰¤îX¸²? ßæÎs ˆ_ÖË..79-N:9.ÈûÅÍ‹èß<ä˳}‘—¥ëŸðÅóaï³µË.Ä'ú+™b|Ù^L›Ý_ÿEêöÛ„| Zó÷9ß©Êl›ÙöN—)]äØz´›Èpg¸ÀY!7†óSÀ(ÕûüäâÙvG-÷÷uÔ¦e³§ý¶k×ÃñŠÞNSJt®sÞNÛ.‹H¾t;í¾Ù§óî !Žªt¹é}¾ÜmÚq9-ËbÏwÜØ^o‘SÎoÛ­Û±dl1X;"ß!;V½Á J c'çYOÐe¡ZÛUÄ”#o¹*‚Wü˜Êj!?3×üuUïþ.Ö½ÖBev€‘±ƒ2‚°’ÕNbįV" p†›7ÕV½DŠD"Lòª¸&ø¸+™82™’0"寯"$;³D$˜Ô l1P@ ËD‰=1’St@rö^ Áƒ8;™ªøà½MŒ\èts>Ï“«·çÒnïLJY'­`ÆR¦Îz”“òW¾þü^h}4ý‡Ñýø²úñõë€ù/v®‘wYL?ÿúÿ± õçüÕJ¥'1 ã:o.È}jÆ^(A×½âb¹Ì»nbDE­x£xwéÅBóíùoþäþWü‡é/¾ý7ãþüÏÿ6Œ¸üÝúñ7.žýöÕ“ï½Ù< iku.ËÔw¸Úí¦û£WçZÔµ‹; g¹ŸuæòûnÓm†Úìþ|~y·‘Ü—ùèuÈB ßH;Gßìw»©OÇ/p»¼®éÞÛïwõííòÙ`¼y}ÿª¯º ›mwñêôš¸%H×mRï™9DâÈ êÂZ`jJ®pW³bõGŸŸ·»6®:.óýÝmñ[ß|vûpÛÜaFî¤f¥ró^R?ì(ŽFÞh[.‡ýõU?}þÖm0+À]j±s褡‹a^ª£Iê…E—Ó<—H K?Ÿ”òdèã<œ¾s>Hõ–›q:ØñµÎtk‡·ãR´X6bØ û«¾ßÊ$cN‘ŒÐc5б°½>ÞJhÝ)¥rðj…E¤œR(qѱ™BXÐÅØI³¦m1U¸ÈIV(@ƒw‡Š™k]”É™ÁvïºptcçzÞ9Ya;¯gqÀ\á :GO`œc%¶MƒªTØ Ù²25CsªŽªªM­Ä I mHJƒ™ƒ†]çµi7ÒÖóFr,€kQ Ĉ’säèuÖR뤶ԦÊ$Á£À\ëJ#Z%«¦n0ñª.Á” ÷ÃF<.:gïttLkÌÜÔ,ºìv*êFeiµ¨ÇHH§ P"Î1d’,m¸ìllm,ÊÆÉ¤äІ¬ _cztM/ÂUDE$DU‡™Ç Ö@.ÌÈÌQÈÜ2{ÄRªÆ€NZçè€c—sŽ>)È©8j4]½Û Ò6T‹ŠžÃ…Ì‹:ŽË™LÈsàDAZ±Å+„•¡ndŠ S7…+?Úå3sJr#85G«-’9$!ÊtKþîŸß\øøçó矟ó8¶vqÓ£Ðo@î`Kœ%­§±Œ-éÐMó„Ïÿòå{Oßÿà½RO©‘;Í­MËò{ýf8¦ým£Ò^¥v¤Q'ï‘르 ëåp~/|‹n½Üx¹ÔšC}ªÛÒ–Z€Ý·9* <ž‘Ì{­;–$`SçÚħìg_€"ºŠðòÛ÷Ù"^ÝÚI—üB^|òA"k¯úÏ¿ó£V’Sl5·y(OiÛzÌŽsAdz¦ 9Å‹/zÞÇf§Å«AgOýzÛ½Q½ìvãr ųžP³c¿+Œå~)óŒ£Bh³c®¦k.|!e\IÕ£z‘fP轚çg¶Â¢Ñk@4]p§•£êö•ÚqµÔ›ÿú£CÁÑê$VºÆà™#E?¦¾QCÕ}Ý]®鿀êj²ƒ Yàu¡øºŽ07% é‰×&ŠÍ“E#b JÑ-ÂÇÀᨥ3š ΘKj¡3ÏŽd蔂eAŠ^Kw˜Â£õƒîº6°çNJ—ƬÞtñcõ…¼5ˆ#4׿‹YqT˜5Ìîè‘{êL„ždÍ _Q~ 915"¡5ÛÍæ¤B 3#f§GA¾SÜ¡k"¿»+ÈàÍÍÈ.h³—IçÈ3#D„é~¤ÓÓÂK±ºö$Á©Òš¯í 5¨§wÝÑjÏÂz…¸¹ºV­€Vz¼\˜ÞñV¬®ƒHÈ»©@lÚ*˜a—Gh•ÃÉ ò˜!á ‰(; @° ¼VM_Û…ðóUjÕô7Xþêk¢¯{=dþ›}%¿âÎaíY×p_ÈBÉ»!Jï! ÄV1Î3ÎÖZë».HªsóÖ¶i@d4gÉÒÅn5&ÕZݽªo·›˜»6Ô ›çm¨6 Ñ¢ ÊšK1JŽ]Ÿ»Z°7ÓVfm%ån“7q“'kÞ{Øî%Iß÷Áeº½úRoÊfnÔ¤ãþ‚-¹ãŠ/Þ& Ôƒ_în^M§Y‹„f¦óX[ÓV6úM¸ºÜÕº´:o7×9]/Ë2MSk抶`¦¨Y„» ½H îVMÇ©LÇv>ÓÃØÎ…k 穞Îw­Ýê#øëÂö«_¿¦Ÿ Bÿ0:"æŸ]ýjªÿsÝW/é¯òã~´zÇÁ„¼ÞŸËXC7 íš§±ž¾W>ûÓó'òÏ»Í Ç›/¾ûr{èãeÒ÷ÝÅg¿÷'Ïöÿc÷ä¼yñæúûßûon˹~ë~çó7ã÷>ýÑ›/Î!PΙ´Þ¿=>ëvÎÁÉÈæHKbº Ý5¶W—ý“x¹ÛlrL)uÌ|( ðß9{{[¦/·Wã騥 ¹ÈŒ‹OþÙ¿øïÿ§ýÿ‡÷Ÿ¿ûòpbÿvÎ7ß½ÅáxrúoþÍ¿üì¯å‹¿úb7<%M×¼Ýt~9 ûƒ7­¥éÒ¬ŽîÇ¥Öe$k‰© a=UBGK-:šG¹ººÂn3ß<ô]Š'!Bu§f g¥>Ä«nãÔ Ç‚µ IDATgõó‘ï@çjÓçõËsGä cѦ+¡N}š<÷Â]žG)u™æ…UÒNV11ß¶Óý›)¾þëÝ·¶õjz¹L§ùòÙ³WŸùö¼Øî²¦ÓM[ꎿ¼û²iM†Ë_ç},éPÎÓá|ùüj·ë»\OÇ8d†Ï…~ë[m»ð$?¹ÿ|ì_¤†jU‰sÁ ÏH%,XHˆk nÈÇ{x…Uø:3%ñÄAÔ]r /Î$dAªæ¬ˆ„Á±—|â•,±Î÷Ÿd9NÎc«ÔÖž†Ž@%ö.8™%å©J!_“ûlhMµ5/Ä¡˜¨† «{#–¥Œ®f ¸PìsÎ)%f”yq3-^ÉŒDbˆ!f‰e.,ÌžÙ ¬Í¡ˆU€æàM´JîD=2«(CVùb]%´ÊÕÕÍa3s¡Ív3µÂ`(ÃàM«šÕ‚œ@†ÞPÞ&ÉÔ¸+%1‰v›"A‹Vm¶ä&A8 ‘Úy1rNˆ„bN1†æµµJì!†:Ÿ-f8Hd#ÑHM&l"2& Éf—†3NäU9€2›Š¯bźˆ­ä'¹Þ­)àÍB%ÕFD1„MßtQGu«núHϦGò¯hAþe£J€Ñ%º5dǶâþo>Çg»½:œžÜ>ýç¸7Üp{;¡jKœ;¤ ¶u¦/@ÚJkÝkï;‰Ï6Þá¶NŸáÅ9\äg¨Óþõ,›}ØúéÕ—¿…Ë·ßþòîû6|ËóÝYÞŽ]¶y°Åm|ÚôÌ©Tñ£v<Ÿ¦O0] w/òáxn¶Àßg¤Ð&rYæóyD?øö"@`…Ál ºº ò|Ñù<º[ßÕ퇻´Ï§·¯oîñ—åå)æß16mÏÑø7Ëùó‡óái¯ûk~Â?:×Ç·Ðz. %æ´IúöLû]•R©¶s›ªÆÃòV.Dö.„P5Tu]ç·•=˜X %ƒˆ90ßgà*¤$ɇì6›]ÓµN™µ]4‹uëœÛßFÉ›RI*ÑyW¨„Ê-Oî˜`¦*ÆÌ.’"‹™c»¾z§ë“eÛã(Y bþòñIÝVmWßÜÜä2»qÇqô>:â«è3”4ƒ„™ýnØ'aŸ¹˜9QŒc{S ¦N&™ŠŒ::d+¯q‚½µþÝ8ÓþŸýzûóö•jî#œŸé#zÍ‘½NCùEïÀׄö`&Ûæç*c‚"£ª÷ëÃÏ»·(«vKûg¯šÓj6—Óg¿Wÿ(ŒÍ_úïi5=ygõÙ‹ôî½w?Êíøþï~ðÁÑ®î¶CsÑ Si="œoªä$z×…ú„Úßyç;Øäãþ0n7“’™åFåÑÃ.G¿®s„êve’À%ÆÞ]]\<ýðÛßþ×õÇã´½Xw˶>kãó¡|z·ùèéÅñŸÿþŸ?>ÿW‡?èú‡qâ§Ö4QKIúC)¢æÕ¹ìªQ.ÃQÌœc#3KbízµöÂdf)¥`$š··w&}ÌóZû°àú4.¦#u}àiÃãPƒ‡P¶§r—P&è$Ó3„BUp{ ˜¦i0—&ÃÀ‡*ÖµoÉ»Áòí6›Ò>ûìruò±.m[‡#q·¼½{õü˜C‹»œ÷¥¯«ØµrÌÈ hF<äîÆúÝðßyò§š¿Ìßßü`ºû—__†AÔc±ªœ«6eID`Ø»†¸uÕEëœ;9ÓOõ¤ÃåðÅO¾ø‹Or‡ôݳqÔ›ÝÝñVÅ€¦ôpwØ_Löp½麧qWo÷,Ö.l3Z‘3”§aº·”µÅ¢A\E;D§K ¶g¸*€rCq]á%‡óº~·áŠd#SšÌøº›Ü‰_Ÿ_Üýx‡íþ§þã¥7&” êV¸\k)ilÚ¢§Íðð8ÝnNr78»)ù´Íü²-¡§«g/“׫‡¨;Y ”^ʵ¢zo_}ëQiæï]°€Fp6rÜ;wPnJDì$Ö«˜2—j@2Y1²jBÉ„ÌPtv+ãM 2½-úEçõÏÔR½ýK#˜y’q³²¤¬ ¨QçéÞ) ¡€!DA2;ÈƒŠ™wðI+fïˆQðìŒHɵQ 4F!€‚À3Á (VÃUTµX²o5V=ò6÷}ÞôžR-Ská;´ – VV•Ã}a¬€T=SÕ`]kWS§”+jŠ—¥»¾“Ðb¹—8aUXFžÅfŽX¤0‹ù>d¨æ7ÙH˜ ¬ÀD b gÆ3ÚqÄÞÈ1Ïê`V¹ïE%ˆmæ‹Ê}]©~u1çÄ£ªQAE'†SÈÈy#7O†ÂB¦ 8ceº·)Ïš>Ýc{k›iíž`•¹´P™„ 0UdX!¨šÚ½åˆØ˜ßÚyì-YŽÍs+™Ü;Ò^óHtÏMáï]5÷‹~¡jî×|ž¿E¬Í/xž_O5§ªo·k‡Ú¶K·¾¬©•ºŽ`’s}I&zÜé8ö*‚p³¦9ª.1ÊjfElLÓqÈ%£®vSÊD¦>Öaµ^œœ¬\íêR†¾ß§¬$¨˜‹ä~Tç‰Ìyìa·S*Ó0 ´Œçåy×p¦þùõ—ýµÔæfo@•÷\0UoWuö”F%¸Ú»* "Q¡9ÕÁ_œ¬˱ŸJѺ®}tÅå$cðXtUÎysws}}]²­Vëªj‚óѳäIs”åXŽƒXgoëfY¥ã¨dY,;Ó4OÎ9ó ,Ê@¢×ýçoÿªsòwÊaþý[‰~fÝ*~¥jîWœo¯¦ù—o8"¼nÄ»Wƒa ¡9c¨Ñ‘ÂÄ7§a±²³Åáüî§rYÚåú[«§¿ýÌ~´k÷ÿè÷žf\Ýö¯ÎΚDõ‡Oüëýþñ¿é?þîÿõñöaõduñË“/e«{+hNZѽnæà<·u»h./CÛ~ss}-cŠêOÚ“ÅÉ2ozªb;ÉJÏå¶ %›2>ìy;E­`MÉdó×[¤î$t«ÆM‹¨MuÐâ)OÿÁÃøî¡4i삙ѹ:ä:„¾ìá%‡œ5«ˆƒá׋&«S-¬¦#B¨ÍqLT9™`TŒÈO0…UËkՆܒÐÚ@}o{è8ì+l {•IË Ò‹Kå›ón˜ VÐ’%¢†à Š”ó0è¡È¯`†cM% .’ó¤L™@±rDÎù~Ü©YŠ(JF°Ct$)YrÉ}v¦¤sù¨¹@ÌÞŠÎ&a%×MˆË:œ’5$!N íÍ*ç©r€'b!gQÉ¢BsQ¤$.scíý9¼ p-qÍæ­¸$T@eÒ ÕÁÆÚåºn¹¢Ð1r¢:äáHM Žüœ¯-Ñ”K2±"E&h©¨k».¶57±:"v®fò'Ñ#–ÐYGW(»`ŲÈdYY½ƒSr>ÕÞ]VnÏ—1îƒNar Be‹(\ÅÎ),CƒãªmtT.à¹ék÷'ûŠÇÿµ0iÅê‰YyŠª£\,ÎÊjÿÉîÅ?×®œýƒ~û³ê³íul–ß¼øîgÿüÛï¿:íg§Çœ›‰ëó“ðIÖCHš¼eï¶í#ù‡†é€ö‡[l©yöåáÜ^B»ÓÆÞ;Â^??hΛW»ñ:‚—¯ºU¬±µgÕÒ.^ìNÇÞoKRTKðY[šêJÑ3šàÏs7lFÞ Œd…¾BzÇ—w|JµÕæ¨jmÎûöé¢,øîn¸íóó“+—›àí>b»À_ÙÕ;žm©Þ}:>¼À7?zïig?½y~sìiyåÇíÝp¸.È QtaN^¦~Ê>†r±Ì”¶Ãv¸Âa¸îpý”ª³v;ˆZyBeÉ6rÜ® ¹4–ýP\¬*^fR{PФd‡qNN(œŠa4IY’`z‰ %U÷úèþJàA¿îYù气Ȁ›¹"°­B]&A6-b¦à !á`P!fb1\¡òf.“ÏT* Çì"ù¯{P4«Œ[sPÁ7¾.…˜³˜Ï$ÑùšêVM½¢®K¬·Ó~34}ºƒôù¶à°¤eG§VN ä<ˆŠr&m¢,‚5ІI¢ç†ÚŠ›ˆÊ“é„,žˆH̳5‘˜€Ìô1Þü[ãÌŠ86Ç*dYDlÞ»ï;Ÿ |¼±'x5‚Ì™>dp g³#î5;ä`j`°*JÆ&V²Ðäˆ2Ò io‡„i¤LlŽØ«ó¯g¶søõì£|£—}¥a1ÏXPÎÓa6#˜(Θ E­³XaË&rß÷ú&$‰6g{¿ùï]³è&03±{1Þ}Y’þÒ¬¹¯‡>Åô—ÜG_<î/? PüújÉ÷."`ŽÿÀJo´Có‹Ì¸ÀoWÐÌ!ƒ@ò5 KɾƓ÷¤þš½×}ý]“õí=|ö±Ü?ßG¦86Ž®:OÑàE9›Q!¢à dØ)18Y]Ò ý‹ãøg¹èÁ>>ûöc»8?_}ã߬¿õov7C'Íwmñ}4Ãʵ?î_ðžb`ÈŸ¿,¯žßýôŸ^í<<ê*‹ÝÜwOBöEź6¤v™ww?yþp]­+ßÕuð>±ö›a»;hîÖ™cnêè&ÒâŽsdŒNû}êI¦}_‹’ÜNU\7ÑYà® "’*úЯwwá¬úà÷Þ[÷Ô/cÙ³Êõon¦e½¢¨CÚ[FÕVg玬D(JÁ1CËa"ûF÷(bÕœ4:HúìÙóé-•êWWÃ>«GmO[WçÝjÚmˆ#°D\v± †éfÛ¯–ë\W5tÝ9®õðr“'u·jýÞà£ó53g”q{œ(P[›%6.šÅF­5×uD¼\Í–ú¢“6±m×Ëc/® ¹¸bY4Ì´¦¡ÀΉMEi™Zdï´®©ª\¤ L]œ¢ Üì‚óU`-dž‰DQ´L˜&›<Àì 11d¢”"ÂÈÃ8¸Pfå¹²Í(9Ï”+ˆÀ.Pd󚥤šQÊTÆ©0©‹\GCw»²™3#]ÍU'Ó˜s #’MÊ":år© óL✺2ˆ¢@ùòƒúM¢Æ’Eæ0[ó q DÉ\Šfƒ°'g>¤~<ŽºZµm+òë°Ÿ¥Œ˜Šãª­–µk$•qÊž9«@ÐÊS"Ï>p …™³s ˜¤@†“З+×t1úþ€"­«c¬r„Æâ8wœçà˜Â˜)\òuæÄaàZݘMÊ„\|àPyµýN«`VÄLÔƒ¢Î*²·­žzËIÿ7߳؈Q±z5òä©öõe¬üøÏþèaÇ«‡Õ“o=¼>/gøìîÓ÷~ìüû½ŸÝ"WGš–»ÝFvÃùðô\®ònÌ«sž¦›ì(Ÿ´È#^þóÏ*ú œ>Bû1ß}üέ}Xl?}ùü“¾ªûÔâá;X´è!ƒvÓYñ§·étgÛ¹.9<ò WU5-¸­Á.çÑ‹XàããÍ»^Þ )ší0\`j?½C®£Éh!tͤùîn8ïðœ-ÒEsä¼q[~XŒÕ²Y¯«*7‡b÷T­åb©›œo§q@†¤, :¹_núeäõb¹ªÏhüp³¹²qÄùI©¹‰ÇaxõÜJ¦TXëXµÔUˆ»»ƒwñöúVeÿðáãBr{³áªÒº*iµwrdRöÅ/êÖE7åaÌ#98µ©äž*Ÿ<¡QT`Ès^¤Õžc°ýxC¨á*´ ß6«»íqÊãóéÅþ%±oÅO®äܵ±;ñU(%µ¼Ûí)Ò¢Y4îRÉË–gn:À$·õæÔùëý6tþÕõuŸ‡ VÙ9‡"˜´$‘ÞÕJȧ<(wÇÔoö#%4¤]söуw>ß÷CÒ”§|HŸ¼—ª¾9îûfŽõcb(9HÈH¿Á~í”éß§¶Ö_¨Ò¤×]et_[vo@t$°×eg³—ÊlÞX~våαÿo¸Mz‹R… `9(M@2ÀfUJD‡¢8ºqµ^ÞÔåûO¿‡ÛÓ¡ýo~ÿ¿ªÏ÷Ï¿øüË~rõ9è;®G»IèÖÏÇ_¢¬šÿþüÞ?~ô_Þüè0þh¿Ü%ªøùí_¬ßyøøÄ_ —ý¸'àrQøøüé;Ýå÷ÓQžÿåôâß=ovþÁúÜWãvw¼ usl»´@Í!dñÙ²–fýèfsóî‘ÏW—å`íè¾sÜ.Í„öîËþ}ÿ´»eÞWœŸM·›o?¾ÜnŸÿäÓ‹oëÛ¿ù­ÿàû·Ïvµ÷olÒ=;n¼ö{¯Ï67£*à.Ö«E?}~S/[ì¦RŸ¡O§»rhÝeÛ<ªÓt~À¦ÃðÜ®›ïõõþ |I‡öN'«ül›}ªG«oçàS„öaíPØ%«ê¾«Â®Œz”ªr^ÌhZ_\öÉ=Yžì·/]3ä´==]êØxyv‘ÓÑÊ@S*×·‡I¦‰ ß?Ñ|xr~QÑ.ÉÍ»»[ôŸ~þàé“6”õÊÇc³O[œU¾ãªêï¾q}Ú XdéŠëª}د»u>ê¸Ï¦ŠÆ¨v£‡VÙ­:qä‹×衟†»ÉWYJÞÓ8°(ú±BZqv…$[Òý—ƒwCJ¯ªØ˜·c9.WË.Çã~§}ï«ÎG?‰BbˆØIY9¸F‹…vm"}`"é'1‹>Q€pžÔ,gÊh€±J¡ÂΜ7OjÁ!DÄŽFdË#,£®›®ãH‡Ã®T*ƒbm – ¥Š§UNÔ^´§2ôS’‚˜«öìd´‚&¢ç2PpmÝu¶0¹\-wèò¾ÜíÆ ‘ª«\UªS”Q°KbºðÍ"híwûTàMr9¦,)ÔÒ-ÙOã@¥§CÖÉ{4M•¹dÀ§Ž‹uÛDÖqœv†Ä•+a45MQ_/h 5ܤ|쇾w‡¢pŽBåœwÖ»œµ·ÊoäFù0mÑŽ»;„{ª¢ód¢B0•ÖƒW:±îR[ô Ù¢H3ý Hî'Ù¸WÀýꄤûM×p ½³‰Jî,,ÛåM´?¹Ú”¿ÿ?ñ´øó’§'Õù´úÎã±|ùwÝaŠª§iYM#¢‡“›áª%ujO\¡eé øèüèoò¿‰'ßj_}{õg'ý‹q÷dOÇ??<®°|o%'´áòüêøb—WøÂwºGÃO¿¼|‡ÏÇÁc¿‚ûN›.ÒîåÕ>íu…têŸKÚï䬠½};§Ósß-KÓÓpÐü"Áñ—'HS"§g'®ýhu¸¨n\úþ ¿ûñú"´ñòìóW¯¶w×Mðï~çéîÙ³2lëúý'Õá§SšÆ»Hó œvžÛ¤î³’÷f•ãöÝ2–MÞ|ÿy» \¤ò1È4ñ½I.NR³¢áÎ6pÍVáwß»mœérÀÕ¡í6ÂϾè¨ º„˜ËZKAQÊåÌE1Á²Xm„1ˆïsI‚"oõàÙ,“ÓŸU1½5ÓßtbÈÌæ5!·ujX;€@Þ™â»Á» ±‚uî¡Ç~",ˆ¶jÈÈ©¨Í±žç)²6Ì­Fa‰’9aÒ*S¹2çÍ…X{URµ±íˆ+ æÆã”RgÉ…ÊUØ6¢ t+\Ôù"â‘ï»ca1)ÎÔ™RÀ’â@ŽKÕ~O¯´Ðe:ê˜Å™øpDlPµÖFrjÙ"H¾öÞ9¶"R!DVål(@vØaÌ\&LÉ’Ø3{2aó‘¨"Á¤¤f 8)‘cÎÌQh‚€,!szÃ,‚#v¼CE 6bãy»•2Á&Ô”LÈGv "1¨xƒXŒØˆˆ‰Ø›–A³@Ùe‚©™‰ ›™’©Am†E@ÅáõuH ÆNʶ IDATæàû*°ËâÌÁ±2£b(ñÜÀñ·)o™}Q÷Ÿf{C3;ãÉEÔ ¬Nb·lšnY5ñä´;Ž›lcU…ý~ÂWÏ6ÞàÕÒ}¿,Ø‘CÈYf¿3¹È;ríCI½£X†^—Ì:‚Ï ˜CøÞ°Co†¯Á1›CQæMxF™÷¾/ff"föÞ«ªefæÉ']U¹PS¬œR‰5U‹À T½©•RPÔŠi11ëê…÷áûý®¿ÛnRJyq¹X¿{R4õ¯†©Od±Ž¡[uËvɆäw“2”R}ï+ö!qÕ"ÖËj{UƤgm¬ÛÈLÇá0ÉêË“årqRU•^er½QhxÁì1N±¹î­¤ºÚ¬\¹X9’óÕíóËó¥ç1c¸Xœ=}üE‡~èµïË”K6Tu”ˆ«ýt½¾b á´éžßÿoÿËü'ÿõ‡•žï Ât~xþÉø _~1¸}õOÿÉÿäwüçéq‡Ó®•6P\‚ꜪQ5Ùµ1™ÞHÓÅ÷ºÛ2·é¤ötÜæAzÐt»ÝÐÖßÕqs‰vêÐ"Vî‡Û]®ÏÞÃÊŽÙð“óÐn÷Û'9iDl<‡õÉ¢s cµ°›|œªôl/êW›m°¾X\œ/¯nnêe|rñø´æß>ÿäðenmqÒžµý^×\ð% P ê3ù˜­7ªšD¶ú~Í›í ¶úüýîôaàv:ÊM5Ç—wç¡9}tþ²lŽ‹½;ÁYVíò¸×ñå_–09Gí(nœä˜²éHDƒ(¨p¢,¢QàÊÉãå–Þz4¶è,é>V§TB…:z§ÁÓ4ö–°äeèÈÇʧ~zna¿<ë¿U¨¿ùÍÿðÃû›ÍfüÉ«ýpqcåa8Þ¼¸óž¼sD¢·´ô~¼÷Å9MlÎ Ø˜Š£Äj8°9&DÀȳwž¨1ó¦–†dvàR68(4èI*EŽFE¢JL ˆ*SÈ©ˆL’-Ë Hˆp +¨8tµ¶†Îq<ÉùæÔŠ fìÀ¢¢B ƒLcF¨Ì‘3§ÌfÙæI1{°Ó9wWÅʤ“º ¡À‹ª˜,M³iÊF§èm,Sž /lJIXsÎÈ&bLŽ9H!Ü‘ :1Î%ŒÚO!RæÁ\b2+¥ô…Tô`&õæ™&w;pZמuý¾GI˜ò”§Ò»á¨˜àŠLE H´\&à=ê1f†yS+DJHaX0²å|Ô\¢x™0öƒô2'LJ *L®˜jjVäëXu!´<%ÓQ%4„i„w$ ؼsŽ(hv£±i­h|€Õ`*óKúæ¬å¯. ü7]pÀ0—Ö7¡ÆÝ—y¢><¥F7zûGûOÆŸT¿1>lâÖ̧øó/èzj ×±T ­+ •ã ´“æl꽸EåÚFj#V¹/¦ÓWøèìÐí‹ kyþrQдP&MÊÆ,8€žÿès~:ÚIwö*ÝÞ)buì=’«Â äš²ƒ48®`KËaB ~ÅÔ6æ@’]FYÅÔa”©%¡@qåÆz¸ÁÖ=‚v‰Ù«»ŽH+™dà48ÑWE&—ªÇ”>ø˜Ìœ e5˜UáÀSNBe £èàêeU-VTßâDv„âôÜùåB⨷ŸLãò ï-쬞0‰–:À×p‚ºÂT0:dFv*.AE”á$ZÄ È2‘’iP3ƒØÄs!¬'Çâü²Q¸CÍðD<Ü£úܧNR!›-rRYã‚• %Ξ"GTœHÈcsVØ \©Y8Ó±È@ &¨|¨<ª’¹©*Rb±® Q)›q›–\JR£äXëàœ„Z]6b±ò8g;3=7r†œ ³c1ƒ'¸Ìfc¹Üp,›_¶+6š™)œó&žߢ]rÓ…¶B0+¬–1°Õ‘BjjkŽWŽ<)¢LHÆaäìÀÁ†b*JL:‡b3Áf®‰3úWÿüã|íW3e(霆éÀÎ#§ÆD¯‡ØÔ3ä¸7”™AŒÙîA×,ä×9AÄ3µA÷a¼5¾Oï"#Ve6S5S+: ã`˜îî³æàïz³Š‘(>'3G¤6›q_ÿu„_ý¬Ãþ:²y+¬OšGOOΖY¨éê‹ËõXª©ô.p¬÷ª¼Z­4Ѹ—ãn8ÞõÃqÈI¤¤”‘­”yv&S@qLc P €ÇŒ4…MFüæOl~'I™îÕG?w;4¹§oï³¾õ5Lz3“ 9}u¾šKÖ,(²‚ðWUUwþàd±èà4åq¿ß™¦4¸öý!Ùƒ T†¬E‡‹³sç\]×C?ã("Í¢[®Ví:†m_ö·»)&?qe¡^®®Ô¢¥1‰‡Á‚s”BS­ÎÖëõú®:BáÛbS$%Wcéᇺ Ñç\Œ”ÁÌY&%X1‚Úƒ³¶ä³•¡Öç12I¿€1„2å°µHrÛÛñ/&êÅ£ËÇ}Ú¦aì7J*N©È˜¦ýñ¸?îz‘XÕÎSC¾ñ«F½îÇ´=>ÙW·֡ÝÓí«ÝͦS6¾7ò½¶éï†jÿFzk†úÆ24çóÏ}Þoóˆè—&…ÐL±³ñë­@Mç´R5ƒ´”‚¦¦v¾u?xõSLå?º÷ûÓ]ÿäOÿÙ³w盿ý[»›»ŸühûoÿÍ‹:¸‡=vŸn[D‡Î×P²¦Û+ Ü\¬â*,V~aúÝn:>'æIÎãzÖ‡Û²ûôúz·¹)C$ÿÁãGC_DQŒw:%$ø2¶Ú~s=¤ãá65‚¡//ûmS×¾kh³i²¬}÷|sórqìo6-'®jyU¿ØÐ‡4ì9mî¦ýiÛGáSù̦ÕúìIM݉vv>b9.Þñz[º¥ŒŒü”„àè¸ @G‡ÊBW5ÜÕGÐ]9ÖËÐŽ;S•ü™v'ÔnöûݳýÕÕ>‘«Ï²N{[Y8GèÔ¤ 0Ï¾è “ôûÉúÉR/ä`YHÛ‚‘Ä­ÄrQd ¢uB•P-û–-HÖ©èHÁMǘ\C"ŠŠ ³e”{ŠjJRDŠIžKµ‰W¬LYĈœ s»¤QvìÙÐ,Å7°Ã`djR-»Ä±P!$XÑI Q$%à± « ¦g•3Õ@¦ê̳:g!¢9Œ† N\Æ¢C.)[È©²FÔÄDsQ3ë3öSAÏ0bï¼sỹ ‚¼ Ëà"»IgbWÄDK):iì~NÂÎL`gÞÇ@Ò”1s“,”aLUcD8fQcß1”äç¬ñÞ¼7q¤Pòù°ul®fÎlÉ … `ï9z†#2ó 6L‘5:óoµÕå5)ð×}Íúk!¡7Á¶R°!$ÝIÙårt¨.ºeãå®\ýayps/ø½ˆÀå_~ÁÏqÚà4µË»jÜtrïÓg pƒëÚôW¡[ NÈ| ~qÜ+œ~ó¤|£=ÐÕÃÛÔ!ò~º<‡=8}{¶éÛ䯭›ê‚¶¶~œã³ŸìÏŠ‡ËÇØ{šòt,f5“²:« ¾‚uð-RäìlòÊMˆ«h–=³/Ð&ö$‡’MÌ“Õ>:htµÂqÆè§áÙqWïÓÎÙx èkP­¥§¬ÓMñ{w äÍ‘¶bä" G6x°ç8–QJãrË£•²LÛij¨ZrÅ7wåJßÛ,¡'þAom‰Â'%·ãq+E‘ì ¦$&E³QTPŠä,9—Ά$H³´áW€û@`°ƒG¦ZÛä…‚÷ì—qÕðÒU+ÒÔµÂfSMÑ«ÏÆ±ÀÀ{xOU[¯Ö‹nY÷ýayº.„zÞuJ#÷|º>‡ø»nô ªW•ñyå?^¼¿|pQùýMó|QÇóñºÞ§„e½ôÍ*Ëõ°Ý춻уÛxÕ9a`ïSËþ”ëÇUóHwëþæó뿺Årª›´\5—t±Z.Wë—Ó ÛEÓ=ÿé÷÷ë}~Rž~xòèòôþÕŽÎòU9–ì»Všñ™±Í/ßðhs5Ø~ìCÜÒ~qV¯¿S7Òbà(«\§k’}0 Å@j(Ç©Ãx«¼‘Ü™;¿ÛÜ®º@°ãË»á³ðÁw?ˆÁn‡mîFHµÞŸ®èá?$>³ztÃÕ°rd oc én79•Ú‡Î×ýÝÑ!›”(«Šs%èÍñs]€:=Aû¤³à›Ðõ_ì:ÇF6‘à›¸ð>OiØíÖËú†wž\~ü›O.ó’Ü/½ZòÚ­›¥7íC²™Bq¬Nfy¹r¥cTcGlG_öÞŽŠÉÌ,Wb…J#¾Žu¨94!¸c<˜¨‰{³Š\ŠàŠ_gr*¢  ˆÆ¢9¡¨BÌg´`¡XÂw°Xò4&ÄhAɵÑ;¯Có—á§ÆN¦YE!s’ …dÀó@QMàô^`R´X65#s0§äÉx>³ØØWµó\˜²³$£féu(688ÏI¡‚à9ÕÌäþoöޤɲä¸Ò<ªjfwx“»Ç”™I‚l° ”")-lnú—w¯JºæîªnN ‰)™>¿áNf¦ª½x $!¹*úÂ7.ò\üù}÷šê9ç;b­ì…•<%,ÐuªÐ T$mº„X¬TÏE1ãç„ õèà(–1'×Ò1£ ÍÔ¤rΣšP®.Lpbä¬"qK¨Å‘kí$%‹+[­N\ÍsT+ZÍ\sqTƒruò ÏjÕ!Åë̪²¬æv>?¡hh+ùÂ<(YO஡ÄÈH¡_P ê/nÙvN8?ôi"úMÆ"6$nc1v¬íÀ+toºW¯võ~yør._âöÿšwÿïÜ7Ç÷ÿÍÇGàwK=•Ó˜u¼öþa¬±& ®àŠiy<-Öî³ì×EÖF&ÕÐ̾_Ð^„üìjœ´8ÅÊmF™Ñ·xþfmŸvËô“e@UÆ‹O:¾joëŽ@È,bžÖ¼y½ZÿÁ6ý–o.ç‡ËüßÒÝ¿ºwë¾óÙÅËW‡û¾qµº¼Ú¼tŸ~7Ù:úÖðE¾³û)»÷aÖnÛ­Ój…‹¦®ÊmsŸ÷é°Ç|{¸³—‡.ºÕGò¸…+iÆdÃ{3æü¨¡ÆhýpXZ²Ë«`T{ ‹ÔHˆ¡KóÃôþ¿^³èÜŽÃõ|x@v¼þ8¿úW«Íÿs˜Êu™š4}M“Ùq8-§yΘ*ŽKÕ:õ!9ƒ‰ äpfµÑ–ËO·ígÍðÊß—Ã$sìÃ:7mÄêb•7r|˜Nº”Mh¶]ÜùfÓôRJqlÛ«ËÝ'‰2‚–Ké¶X'ãv¼ç¡Ø ¬B‰ùl]€x ÞqUÔËÁü  p§…ÜÜKÖ>ñŽSŠ”¹,e6Ué‚FFto¤Ô¸r [+ªÌóRK¢R*ªÉ„¾`«´CØ1÷¦1kÌH*h*Zõàˆ0X-•Š}´Ö¹—¦¹’ÖâpBH‚ØRŒÆâìª>æì9$ŠVU¹h-`rˆ9‘=±—αÒ%Ï&!¤(mCãê>;ÔsÏ;‡H0¨r-pZ”EÖĤ©ÙêìKv^iò…ì $VC0h©^JtöQî/?›——CÂØ¥°Þ5¹5íg2BVV!ãZ«*™Á(@…HÏ~ƒ_æù?Ù#œœ¥&T$k#‚x„W*ðj³M=V"صë†Ú Ë²òC…±€V•h!š“—I3È–<7È-¼õˆ‰ºÖC‹´å«F7eQ`¸@»0'w†‘ϳØ`y_O£žª—HÆ`ˆGâN@%…”¼°/t–7˜Áç˜]A[tòòPðH@¯)Ѧ!«~­ç±ž‹…ÜÌÎR3Š2("¶Ô$¤1J”R‹ ¢êðDVIƒ8»)‚R0Ž+3×jn8œ LB‚'¾€Nvv kÀOd&À gj§Ä !7‚áܲÊî@‘Xô¬"çfC€DÀñégO¼}#â ö’)>¤ì\ÉJ'oü '`&fP5eP &"?+QD ®pâik²3“]õzÖ@Âo:£Û™¤àß`å~%N1JÓ7M— Vuéw—KÍ.gi®jó2«MMh ¹¸ËÒêŦoã–œ§Ã\ûa^ŠiÇ¡0ç<¢aše>¹=ÁøÜ«²ÔB¿|Äó³y6ò‡JJû¦›R˜üÃBýÉšHdäªN3¸ƒ©)%gî¶¶{Ö_\¬›6€*Ø„«Q¾xÞŠxɹ¨ª‰™ªêRêéîp:¥˜tv®ÿ%À!vµV3+¥Tó3”|<ŒÃÃÐí:7BçÕ“ì7/®ê cI䌢ÕàŠí…,ªÙWm’F+¡ Ï^¿zùɳЊ³žÃÃáátšj†J-æf`h‡8I@.cØîÖ›mëÁ8!“žÇéÕ«WM¢iz0·ËÝ®o§ª…A,0«Ãét¿*:‡†£´IÚÁ—Ó°Ày³Ù¬vÛûÇûÃÍ5à% Ad!ošæââb½Þa(ûÛû÷ûÛ»yØÃ ÉÙÙý >Âþä² ÿÏÜ?ÈÐ{*u5ûp1ÿâñóßY®õÍg–ÀD0sU{Ú¸‰HØl.ïïÞjA yqEÛnÛ7kÄß9y¯›zî‡Í¦ÅVÇa±OßSm½æ n.d™9(%j:{qrLÙr™û‘‚J°„Y–»1¯QÛ5õqŒËl¶iøåæÙó´?~±Ü~¬Kw¸;±W—Ï?Ú6kñM³^ùÙQ °(”¬jdNJP?ODR‰ÝëßÉø'MÙ R€0B…¹U55ä‚YËÌzJ‹7ëÚ(#¢N‰ªƒ.â, ³>€²íÐ_b×ÑŽ¥o¥MžZ´›°nêZ7@DØCraÅëlÙë)‹M(C›#S‰ÆP‡œ£1âœEˆQÉ«¹8ˆ0×P+—йàTppLë+ø.Rh(^ ²9Õ²d “@u.d ©á&YˆZ鄺ÆSX„žKi˹CŒxvND"ãÀ"RÕ«»ºŸ{8ôÄ&«ì°³Š÷'Bu8£¤íéŒv¶X ´=úLÇ„3©îü'"y0˜Qp(91©Qqp „Xä,2ÂZQϹ¼ÒÓ@>O9ÄdäçIç¬8‰€˜ˆA $PþÞæÙï¦åe½¿ EÛíÅ'¯¾¿ÎÇz¼}ñ«ïþñ·?þã?z¸»¾ý?ýò?àgwÙ¿ø¹_]¼xóâõwéöêº^’?<áp·s·½hæŒýõ®|ýœ‰PO|ó8>ª,ëMÿê²_E×»U`DÛ{¾j½ÝÉÖµÓŒôÏ/.¾õ{¿ÿ'¿ÓþöiNïyÕÎÕÇ9ýô?¿}÷v¸}o\°¥}èl±¥h¸y57ç:9kÙÏÓ®˜ÔðíÝ'7ïoîo~úxÏÖô9zÂ*6›ôìr½ã`ó¼‘]{$óòp3ÿ§ÿóÇ«Ð6‡öõÅ3÷ãíÝõãÍðùó~k«K§Á ‹»äHD%qmس>³ËÂ\ Õ* †âòé0Z ¬Iá$ IÕÀ#ºËd1×–¸»¹‚UA¦TdãaKÒB9WWOâÄ"-µ†ÁëHh˜ŒQiöä”à¬fnTŒ ‰@†w¯¹ÀØÔl±qÎ,‘à ƒ*U h&îÉÙÍ] ܉ÙSŠÞ€[¡†(±¡æZ4Ï3‘j#×bÆ#*Ë v6×@ÞRn|fÍ3ÁÎð{²÷ÙYáu@ŒÙa¥žë²guƒÈkÉ>«»SaUý&ú‡šˆš—˜|Fâ’;\!&Á‰\½æb³.óq,„Iªª%n:éš>ô­p{ÿÕ5T‚%B2¯E] la&Q±âe¬.cl‚j!vD:›ýa†5Ñ•ðEÐÀñªãØÓÚ©_ ÊOÛJÿ@Ïýûÿ¥&Ãÿ¡‚€D,,î5;+ñïêfûó7W»´Y[›§ ¾Ah¹c5ÛŸpÒg„༠³6§.UÚÉx-wŽ8k‰µ9 5/m³áÜ$ë/Z—<›æsÑS2ˆW÷óDTfÿ¼Ïl @D""bTEÉ y*>Íõ˜u·Ñ­g •`$pVÈäÀ —N@Z£ÙRº —ÏùÕŠžµa%”"bð5É;—6ì(¨2I&·YA Ù@CË^ M† Šì ÓóPáO)vf& 37#7ƒE7òÊeÒãâƒ#'pD߯+ØU eOw£‹5—yrRÔ ¸Cê¤M¥2»o#¯‚Åä,^PñÊÄÅ‹Q0ˆC@lDÌ  \ÝÕΪՓ g‚+ ¦3GšžÚ}è\uHb'2 Db$FLçð8Üž^„ægZÀÄJRô T18R‹胓 ŽŠú”Mb"¹>xLÕ@B,Ä‘˜lÌSY˜å|¶©V+θR8ÃazöÇØùÐùáhþÑ'48~aóÌÌàPŒËNJMYsàÆ‡Ób3š>µ› äaïÞ m3°…š-HâÐ:xyÌ#3gó¦ëÛõ¦é“°–±Þ†\7_‡ØeÃýñtwÙW«f÷¬Ûívm˜–êùq˜æÓ’‡”¤_¥¦‰Ó´0¥q(ãP¦ÓdyF`u)¥G‹Va¥,Z*±¯ÚN1$ffæ¶m›&b¶á~AÈiÒ6u»&¥°Ì³Ï~¼ž‹BpµHÔ"Iˆ)…›ë‡´B×õA›qZ¦#²Íû‡ƒ»?ÞÜÞ>Ì'ÚÑf¤V Õ¼ÖE]‰XY žA–3 µK»uìCŠFÍ2O‡ýu-³{Yu"_­ûí¶? ' ›ÕfÓté³ßýÞá´{óþ«ÛëÛ} ¦M]ÑyZf~þêy¿é¯ß¾[¦œ„W©çéä§1ß¼¿ÿúíøõÛát<îL‰pÆËÙ¹iôä%ÿÓܯjDߌ=úeu蛡èWèÛ¿ò¥Î$ëÇd"Â&‘-IHà@ìPSVM·«‹6OÓíázGÛ9¥u÷òí㣈„÷ã¿ùögwWzOúøgý‹‹ün\¦ªyÞŸ¦‘ÃË‹ôâ™í®6Hìýùk¬ÙO·ÓrÊǵâpÊ6ÝM—_ØC‰!ÀII²K³º€¶vç=µËçãÍßÜÜ|~—snRsûøðx}°X¾õ[¯^=»X5òp˜wõϨ»J7_Þ,§Å¦æáÇ×þW?ý鸜R¿}±ë_÷©mØ£ˆÅ–ˆTˆ%Eé7¦bZ—©ØÌX„ S9·PÀgB0!S «ˆ–)F§³ÁÁ PÏóìK­2¢_¼~™Á&Êê  uÓê(¨‹¯YVуšUÕŒd!"&ñ$9ä"•[b°ÃRÓ{PŠN˜{šÕ*ì0[p+VÔ,e®“NÓ²Ú%f¦@U U$Ã!/ç¶C;§G °ª™Œa.ôÔâP31‘ÈÙáäIÄgUÍ\ÙU5T-(/‚´À&÷Ùha†x"÷]BmÊeòÍB.s×´)JÕóCÚ (ª)nˆ\¡ç: 0£TŒS³½ÈZa.,bqÀœŒ‰]Œ}²Æ„ØM5“M”÷ÚjKJóþ4·u}!9"/GHQhÐ8‘ð¨nZ¸ªÅ”}ñ\J+Ü) “Ubl!W¯’6¡½è‰û<’H£0õz–Þλ8ýe˜Ëo^Ñ*†þü:®¦R!Jš%<>âç?¿^¿ßÝé«=ïõâr%}·”Çöª¤ßÛvoúÃãþþí#í5?{G{ÝÄæb½5 Ý.iÏü{ë÷vp§RÓ£¯Žë«Ì?ûé|ç4S³‘µ™gl×øø³ËŸô³,a\h¶izŽôqwšs`y%1÷6à%¶§%ÝÚ`pÒèÁ³*ˆZ4@$ ¨ aŽMŠ­†Z¸Õ†e;¥Çi‚ÍHL¹Œû"ê÷“k7Ê…^—»iŒLWÝöÑÇ›¨ÞPˆ%T,¬’¯û—ºÌhÕ›AÉæH‚Ò/Õ90iÕøvZ–\u½I6Í÷u¼E-ðéx›—IU†æÀ‹Ú”ë„:J(nT Õe¡_°àþ!_Ãÿ¨8DfÄ@ržH"³Gv€Hë®›Lª9û¢1†¾oÛ ¨yéH„|òi„¾í/×›¶ ·w‡Ã´ZÑjݰø0ìAËÅóíÃþö8ÌýöÕ4ܯú®O¢Ërz8ö 5m§Zîïïûmó*<#׫ËÝ^×÷£Ì«x©ÕÞ¿¿»¹>Ý^g×CÍ TÏt  O«Ð¿k ûŸL&RÕ3å›3 É/£ä𡘀ýí÷þ6{û—õ¢$\˜ÈÏ•é“pY¢ƒÍŒCh›6ãy}u¹=õô£›õíôo}븺M?øè'éZ×µtñÔÒzóæÕ©þé_ül¯îo?¿ùÑ="V¶¼‚™ß=ä§W—Ííõýþ—ßÞIs}øêõGmþÞÌ;mÿþ᡹Á9§ÖŸíÚ¸Ÿçïúñ«îÕi?§S!—F^½xm¸ ‡Ú¯VÝói w·¹ñþe×tÚ_‡ûú—úåK™ÄË*Eá$û›/-h† ‘“»…Àž+ @!ç\Š>j]¾>­ÿ¢ÿü«¯ßìžÿ|ùù—Ÿy÷¸Wf¥0åi«õÍ'WßÚ¾Ðiº«=·òò¸Út[§×Ï>­ïôÝÿ÷0fÂ;ÄãêÙÅåèóãq¾¸‡cÄXî¿Æ)"­ÁÊPԥι,‡‡Š ˜Í²GƒPÕºä«#ÉsÒöb›R>ŒH„’AÜ6j‹[u÷\JHªªócŒ†ª¨8h•…Ä] DáQÉcÑsŸ C窜º¾ ‰9A"U+ãi¨¶ŽÁ+;Ô©Ô•tx9Κ-…4 3•\çáâ»oÚ>>ÜÜ`°5ݬ¢PˆMDDT«~Я›´‚y ")Pf¸PHÑTµ*ˆÅ+q2¦"ÔõÝeõ0 ¹fI…‚…:/–5©)°`º&.¾¡ib­ÅÈ8²QõÆNåP³¡!YGÙ5^cQÔ@LAšVrC47[Ò|R d0BI¤éHÛ T‹JBðBÃÜçŠS´c<]?¢‰ÍÕÎÃÃÐn¼ëÚœ„Lk= ù(tÊ:ë0]n.rÍ &Ž.MÕ C^&S—¾Y_îÊŠ—f¡Uºüè*ô버EëÍ×7žóì@`Q«¿©"ôwoþ´€(E"¦¼ŒãR·„2àç7Ÿ¯^-ñE껇CTZ‡æG§W¿}éÿzs÷Å^ÑæçÜœÒûûqÿŸì¶`¦¸ðãl/ÿõGú‡Í]²æÅöx;_íöýÿ¿ºû+\»ýè¯ßo_ÙÔ7ŸàßY¯žKŲYuoít¹k?®»ÿÅcóo¶×]YNc_Yvb†ÿÑe©ióUi Êxj(ÎK匸DQ[¯D¬¢—ÔlCìæ‡½‡´Ôã¤:1SQâñaáá@ÔÙÁNÇaó¼{¼›>yñr8> “Õu?ß–E¯ž½¸zÖ0n®ºæ±¼Üvùr=.÷!ÒP^0~½¿L¸¼ÄøÞÐõáà«õÚJÍm K s„#Íú ÷oßwC^´½<*N Õì–A‚l>¹Ï@&.ÌF|^ èWÚ þ©¼sFf¬x²‚¼Ì ¦:™N}D~8Úý†¸hu×ì®0xÚDÕêX”œ9Ã"b ^¡í}×ÙUO¯6ôÂk ZP°$Z‰Œëlmß2Iq×R«¸ UÆlùTŽ #xÆœ½l‹.E³6&¢ª£å=‰¤HP@DÈ«*‚Å.˜H©å´ ‹ÎhSÓ´ë>lY.”b¬)’$@\P í 8íª…9õM\`”R¨åZÔŒAÄdÀ¢‹Tz2žù™…­®x›1/V¡ÙÝLvN2˜XD¬…ƒ)²¸«k("º–€žlI,R({T˜ÀÅ9rœQØó\•))ÜÍâÀ˜ˆ(ÆH®0s?OAg±™ªV'{ª‹u5ƒ;1@ †EC+ÒsjD¸ÔZiÎèw‡+Gu)¦-b’2£@M€ÄÄÄpTÍ`qƒâ­Ñ/OŸ0;ü||ã3ÆÁªb±Ò^†fÛ¾úÖ‹½êÒ7i¶pYæ#jª•‹Y)îÞicŒÃñQ£„˜Î3Ž›¯¶²d¡6×UÛtÛµ¬Ÿæ²îŸÇãþ4 }’óyœÍ,Eºz®¥…&uQÄ]û¶‹I–¥›¦ Lf&Bý¦7³¢0QàP‹ÏÎDtöƒVä\óRÉ]–Ù–Z‚$áv»‰µ‚I¦ù"çšoóryyÙ¶mÛ¶)…yÝÉ´šÙù;…ŠýÖ­¬¥Ýnw±OS¬¸§+‰yîãÔ!»;¡ªÕº S×õY븟‹ú21 Ò|\Þ._Ÿ–£ú&ÄÀ6Y㑜÷ûý"%téÙ«ËØFw @#ׄšI3AS•5mÖW¬¹ä°d„è à„Ãñ®êcN÷_Ì'°ÌSñ¢ëØ?Ü<÷Í3yöâr·ÛÅau˜—õï6 z #»¥ë¦Ä‡ï¾ŒqyOuœ5ô&_.»ôú£mÓÖ”˜Ç,+ Ëàêp#‹á«/öÿö]øa•FÜ7ù±¿û2Ï'4€04pj:Ž¢þ01ƒˆDqð(-:–æÝa…´:'zzÒy:’bíÔÖ⟡°J›×]ÍÓtÜûÝøø“ûë¿yÔ/6\»Ýn³°å2eWugF†pùœ¸³Ö)†cHÉ Þ¦ÒñÙŽ%ìÁÝnKñkBr[I¨º9’@ j…yV;¼Š‘蘑LÌd\r¨ ¯:kÍ,î|F:…'kDA¶èX1§hÉ1´ ±bóàdcç}0Cª‘Ž˜ç §q:ÁO†B3y%t½»ÐnºyÐr³J´par%7«µ<ë6,Á%x BÄJª"ÁH DälJ )´‡Ž%Q 1¢Õóɳyµ ®ÈµæÂÉc5õP©%vXq¸{0¸yp U‰ Ü1Àž g£_öRÙ²ì$*Á+»²Tå²ÔŽIš˜(†äÎ &¥™xbË€{\E½Ê¬eiN¹š¢"§å¨V 2ÌQaaGò¾ïrΈжzhƒ´cÙò¼Ì9Ó´”N =;ÏF²ô\ô]*PÀŠH„˜Åò’Q2,wÕÆVÈ™¼àÁOý³¾yq5½¥‡åˆ±¦»ô•.ooj\èB$àáaßñ•½Z½³9—2}q›?ÇjNYs·¹Xñãî«T§€è™RÛwŒŠ|¨žã8t–P¹®šv¾»[|‹÷/@^?o>y“Ô 4HŠºèR͘):œn«vˆ—ÊýœV™]Ü}P*pÒrÈf6=â0㡚aò:ùŒîycÞóx£àh–nTg/•Ny"+Æ Ù§’!ujûn¡HZÐ,3ìÍkF%Ä)S…®ËÀ–cZ\zøˆ ËÍðö –P_öºQȆâ(@*¨2~Â}ù?׳ÛCŠ‘¹³Á±¸w÷©.qz˜ïRžÙód'“³&"Ê f£5V›žãŽû\mèY£;É«€NˆÆ)‘ÁÈ]uÑš$ʱ-3æ¥äYçÙ—Ù'v#‡G°°ˆ©ÏºHÞw±Oq)-LÎ}]ÆP/s™‡|w,‹åÅU¬(fÅ•U-0ãÀrΗ“ƒœÉQ<pA­ôÔ~˳‡ö©ÍGXˆÝÈ |¦Z¼*̆ÈYáq`À+Î|m2ø¹ »åv®ä å³ÁFc¦s*"(:ı…JµRJ”ÔwaõeÍ­”²Û Ÿ–Y­¢ÕÀÔ÷½©æ¼ZÓ`ÂÖy=¿—øÉÐF_­¸G: ^s)´º™ sPõ’K-M$\ï: ¼ž—I/ï†Ø‡!©4jBƵÕ&H;®†8t¹,1àîjݽfAcÒi™rËÍrèq诺¬Ö*,;é†ËÚ©ëeYOoßkÃ~wµK7|ÕŸ_Ÿæ !0ùùña™LÛü0­çjÙtÕË|9ë㩬3¯ \Û&‡¾UÔ}2ÊÿFcYûÿ³DÿBeõÛa¡Mh9ü©1b›1Ñæw†ëÁr0!°GA®šsÓÖ7zÕ_½|õ¢øpE·üüþí_+MwÇé~-–«œ Ø;e IDATo÷ý›ŸÄMšX6œ2ö§úgû?ùÁþêÎdwy.%Ì÷ïÿãñ¤%•îJRâ´î«ì-¨Çª¬§©´¨KÌaÏûÓÏ–ÿóþͱœÊW¥ûËó5b—Жóå‹þÕ)õúØÖ\îM?ùtüñýJ~þ‹Ç_~ð@7}/x÷ƒŽ—¯XI wh€ôñîîðñÎÒÛ¼<.óÜBáN‘!ä]ì‘Âù¸|õÚÅ@W ×nÐvy†á@›mƒºº;9 ¦Œ6Gq-|ñëûgÃè»$ˆv¢Æ./ÓxH/üäÚŸô*„ò˜—c¾Í}J‡y|}áIo¦¾œ¦}'Ïø*†«_-_®X—rY ˜¤‹Ôw²_§jîX*TJ´žk3”–I„„) ֠êêž›[£¦<ÁÝÔÌÀÌCוÕUÚ8››1Ahy,|ãЫx êìÊ nÛe ØØ›A¶°+»¶F‡Ø{ ¬ÙÈY„ P7‡ª’vÑ¡D[¸@ kõE°(4šA­!h¸ÛOÓ¢\‡Ý°Ö ºP8ǘ085²¦h¬HŠHDlk!2!%‚P0«înDDÆPa Âq3[7ñFÈä͵63ŠÄ„íþ h¨^ç5íI"-ªVZEè\c©¸A¹!:Ç¥—t輨-fÔÀ`'33Íì•PÍ›yS0ÀÊNÔ\B,âh«ùÅqL+1Ái! Bè‰JÍ )¢C¬¢¨•†*Ö:ƒ€P!2x …J¦h€BºØR-´äâuÏjM‘­Ë^~‹¢ðôÙwEdÀ®´í’Ë YÉ ô};á­ÑmD ÝsKæ]k-àôî›:‰ü›?³Çã¹O¸ú<\gOþð./=†ï¹$\þöÒ3¾úô9ÙBâ|~ÿðÕié_îU®]zÜöô¦á ‘up6toÐη)Ý/K‡˜Kýl¸û¯ïo;Øó0ß4BÖ¡Žwa×I:ç–mÎP5%DòzFº̧fWíÀ‘C¸,êÚˆ3ÜÅ¥b:£fŒtÏöûù¡¡ú»ŸŸúN>ejý¥éñ2‡X•—æu±ü/0ÈÍÌ"y­²À¬ ‚)…â1¯°+kç=¯Z…-¶RmB½à¼ jš‘g”íùœ›e (0¸?åÄ~¿6w Œ!¤1„\Ía­Eç DõT΄9¡ylcO^\ †$ˆìÎH ¡­ýÆX$Dé{ÞÛQÕº.1Œ QN`&#¸¶:„Öl±º`^½VV8yÓbU@‰Àî¤ÞXRÑù<¦á:¦›Ñ*R)¡&£Zü4×ÇKy\µl±¸Ï­˜OÜÒBk¶EUÍt#R?i‡PEª¨Fذ ˜+‘6Rå oÄ­rÍÞ”Œ¦pg –Œˆ„x£ÔT°@ P¸›BŠæäLnÍ™ŸbDÄDâf°°ÑªA=€xEÝžbG""a…+œMܽ‘V²H½lI÷L€B ìP3¯À¶6_u²SnîÚÔÊ·M¬´õÀ2ÐPò0P(0<ˆÈœÞÈÙ}{ , ®OF›e¤äæOõßU}»’µßü©EæÃN3Ì’¤–¶–Y›¶Ö÷»Ñc¤-Ó9·Ë´.jlL,úé«Ov£ô‡!ôÁLs™Ê¼ÚešŒ¼¹6SÏ˼N¸i™¦sÎít:ºû~è% CH. p”‚¸{­ ÜÄ<4w„ÀÞ,›5"ç-Yß|§îIUM³0u¦ëºÔ¼¢ë¨/Ú¬¥ÜuÒ²/Ë|¸J1õ}êÚa»\ΗË%&QÕý8\?¿îC<—ÓI«/缬~zs)ßø0^ÑU„ˆëªeiv1ZLH¤@‘¦ÊÆÄ)ÅÆ~×íúêå1?lìDVÕ¶h]µóΧ(.JÍ.§3­§v}u!&wø~Ü_í‡y¾|sÿº´<-çýíí†Ò®.— B΄HÚ]íX4Îy9Ÿ‘gD¬WF)7»ñZ?öóe:^Þw ¥žUq¯ÖåK›§òø€¼ZkAŽ>xËi+AþÍLã;:ô4ÌýƒÑ?ýsø„ßÍWØ:Z9=v<„è&ŠÂ)Jd¹?N½„ÂîE7T¦Óúˆ}ùÁŸÞ¾øih:]8×_éòź.%6]s1´j}±ëw1]㻟_£~­³ßÿèîÕiÊÇ_œV.¦ãår¶ä;¢/(äm¼îÏïwi™KTíXo/oüçýëãŠ]?¾¿»až±.õµ]}v{)§ç‡gkøègÿË›¯ÿ‡/þ’ÛMòOêe"²±2µ>({#1æûã1Þ0®(½ Bc³ºÎç¶4¿º©}ó—oß®·)'ñãÍGûþùó1^ù«ùó//âòüÅóë^h\@e>¿_˜³(”ˆ…=)A¬„¼"Wˆ ¤0ÓÁÕòŠ$€DSVC€\«œX¬º73…*PŒÌ+‰ôÃn¸Š×Ý~Wó§²ìÒriºäÕO¹\¼v³°§ùʾ Ó/Ûy-Aùþõ _÷­òd£-yY0iØ,ÖÑ)ºÛÃm5Zx¡û]ö©ºëÒV y7‡557„ο“œÂçwJ}3vT³âG$Œ=F3Ñ¢k«•]b¦,F¬ÎbA]a\BJNÂrC+­LŽK3³¶=oÖêæ;ƒËœ;ïBdª†Ø\Ø“ªW'su5°¢Œ"cL‡0ŸÚªkk…”² ǰõÉ3{`ëÈ; 3 © %P©ù¬ù}ÆD¾’^84P+Ûpˆ³5µVÜ®VZÌ`CQ¶Y—@ A‘à}ú˜¨÷ÕÕ–ëÈÏúp¸÷òv¦áIäÛ5ë·úÍGÿî»[ ¬´;là‚¯àã[L¿„Åìõá—ÜaþÂø‹w7ÿÅÁŸ¥å‡Ýí± ‰Ãd±!ZIQWy úÛ,ýò2aêù¡•D—±›??eê†ÝþÓ¯ŽW‹ÕÕ—2º­ªƒºÝ¬Çý=uÞ|¯rÿ®_€®Äûu]×y¨ãM cí©¦œ¹«jÁ1®`‚p>•|šÇ«ÃâÒ²¬yRŽ¡K¦¶ÂUWL¯áò"!!’O=ûÒ…Ag¨Ët‰#û¸®«‡ SC†œKëÄá8h`]/_ˆjÍŒ2{,ÂNB b6C`¨57„4H¶œ«£=­*ýLð÷hîØ2úàá®»}ÞwµzF‰æs'r¶ÐÜ*”á Al±WC|îiG6—•Ðm¥BM"Žˆ½`ØÎQ·é É9`k©ÐTòñTOGÜ+f5t±§±yv«ÛrÆA ]k’Tφ9ø1ÛCô(¨`­ â#o–³×ö®Ú¹¢4¸³+Úœõ‘T3r±µyU¨Ãͽ¹ˆPG ¨…´AUåäpro­¸8»Ša5nÅó‚µrm0uDDÂÆ!€»•꥚E³'p`NÎb¼Á,ÌD ÔÈÉ€­Û'€;Ȉ°—´§®#c"…75¦  FZ¹ 5™©»7l¤ú@€c˜5"õ­ Ô¶WO's˜n5H?¼ÃÌbèH¢Sâ0@’S\Ȉ¹À‰7ì·+ fff®O´ØÓXû_âš3óßk>­À”Œ\«ª:À]7HgÃó`Ý2­Ë:“Ø2ͽø¤,öø0Ï¿,Kµ•£…ú]Lc÷îýã4QšûØ…juY/ù2[±]G}×I 4÷󥄾[æRæÇu)Óù%ÔqG´fmSpUÓ 109—ËåÒ‰šY©…ªÊ)PQƒ„bŒ‘ˆTUH8iÎ)%"*K-sË3òбºÀœj% 0òÈÔʺX†ð°ë‡±+­ÕZ‰ˆjµu-f!¤”˜ÅÝBâ‚z|œbÝÝŽ7J¬*õ{Œ$dA½+ÚñÚê¤sê(„È"hL‘C$3§¢A˜‡Ànž­UmͨÏÂf8½=6Áî*´®›.Í‹æYû±•RJ!溞N§@5J0Q{:‡ÈœjÓệ®vW·W—ÇêeñS9Ÿ¾9 qèo®hð¶â8$«mÍk£è.k°–ó2çkF ˜hkRÿ°°gú]‘!ÿÃEÿÏrèŸÿ/5Ã?jÊsG-óù4³v3œl Ë‚­Û¥›ç—‡»ŸŒWÁ—_ÚÛ-„ÜÒÛy?þ|Õ+÷¹†É¯Ð]ñ¾[[©­aMº¬³ùçù}»9p]_.õ£Ïˆ¸¿¶[Mì=Ò[·$”˜¹ËC™.Qæt÷JB÷p¾¼y¸ ÷k¾‹2C0uþF2sÞ¹¼û÷±çWýÍ]îäa¦_þ¯_|ù—÷úºôw7|MÂÀ¹JöÎSLq7ô‡nž[ u*Ó»s7ÏZuò€¡Í‘/Cúº¿{ƒOnîºg?ìîþx¼z>ê%tGÞª›ôýѳ­õÒò}Õ÷—Á,˜»[nš/Ó2³5 \ãlÔZ­ ,¢¡½³qÜÒ‡îæ­<‡~]ÊoÇëW?úáðq|¸º|UÞ>ÞŸ*Q (}×õ¡^^ÌwÝÿÕ_>K”Ld]{°œ"U/—P.¾ÖΙBzcÊ&Õ$››iãæU‘[[ÖbµÍ+½ƒÝÄ6G¡»¾EÇ$Ê"-€´ÔV-98IqZÌÖfªj®Ü|/–Œz°8EÔiS@LdÖŒ±Ý3næ»™Ö¦#FÜØ‡ÄNì^¼)„P·€- < ª¢ŠX °-ÒШ(L-HÚï÷qŒx\<Â&³U!3$ÁNvw{­q+V¹1]͉ ÁƒÁÉI 3#ˆp$g˪sÃb 8´‘ySmEšB:⼜½ˆ;<8zÕP] š-ëÓ…â|FòI›.hÅ5¸wQbìzÀPfB àÑù:¦Ñœ³®5‹P ~™«ÑŒXu0 ¡”SÓéS™?=¹,Q¨±mu'îÑLÚŠÕ“³»'£Î¤ƒrYòÙËšüŠ$&†Z+ßB_í[¾í»ÿ®Iz”o u¨pƒ7PÈDïÈ.îgàÁðEÅKÁ‹Ï’à*!ü®ÿã2ü7F?Ü¿ùìºäcûÏ®de½¤Ôcå@þJ…þZÛ/¿¸ãÃiþåˆùûñMXûÛÛåÿÆw8/¥Ž»[O^Û+RKUGGxßdêS|ÖBay?.Т»M7q©¹éG¡Ä±®d´Ù3ÕžµÂ6»ÂÔ)çÛa8Ä ‚c††â#‰!UxÖZÖzÿ–3žÎí:P’‰[¡|Ü)"ö5#7KM—ÙX·Y îëíuu”DVÊÙó±­ #xhp†K ®Œ™àÔ *’ÍPª(¸ª Àª¶QÚ þ“û}_²Åàæhr'wŸ¤›|iù}ñÓ^Ĩ©1µ¬¨’—ê ]÷üpøw£¯÷uB;n‡DÂÌÌ,‘ºïÙ¯a‹Ã’R$éÀ‰Ì]…Ê×'p1Qr°‘73y¶Â‰söó´¼öZ¾bùy©nÅë¬ë¥§únÅŸ˜¸:©[³i†B/êÔ"ˆNj¢O€Y¦j­!Tª…JE«®‰U\ákð­e­4jŠ\$Ë•´º™ˆ$Š=‡ ÍébšŠ31›«¢G3˜¹<©P&2ff²À ®ì.p'ðˆÐS( ”ÁV~ÃæÔ`ä@%mXŠ™WT%+Îxâ mg¹»Ä‹»og–¢)™‘np9wgwâs S$NÄQtOFHŽ@H¶-!"ÓVi&âMÝŽ¹7SsÛž1ÿ&øÎŠÈ·7ÿíïèVäÛ:lcÕ7WI˜×µµEħéaˆôø>ï÷ç²øÃñÑ[„x?Ç^Bì:7'äêÈê"àÀÒw!¶:¯}Šð ©Ë%?s¯a™•ZÓR-W‹Ü–Ü—iÐK,ZjS°{ îä­ÖšÅêMµU«LÁÜZÓyÉ¥8‹p«ÖZ+¥°sŒžóšs!IVQ‹¹AÚØ Ì©ïDˆÜ d}$hµi-Xç%[qk)¥aZkµÖãñèµ”RÌŒ » ô˜gìÎs÷ЩB'Ð]“za¨<ÈšKq§hNîV æÅLjC6oµµÔ‰„@Õ¨¼¢¸Žû-€yUnC’D(òe¹œ×:­)Ê~¿‹µÖìáxÜvhóÑsŒ`RÇãñƒ÷}só¼~$¢ï/§z9]|­St#¢w·wŸÜŠðýë7£mæõѧãzz\¦K+•€&2ÇoPÑ6éŸðhú–qîw†ˆ6šþwm‡—èï颭R8ø–Yb"ÖV·E/¼êÜR«Ÿº~&üƒÛ»÷Ëãërô›ÛgIîé"ÏV¹ň/@ok:§Ûxûþ|l¹ÕŒª‘µOÇ‹ö“ï)žGÿåÛ¯'š^ŸÞ–1ÞtÏúQÚ³Ïß¼=V}ñê¦_1=¾ínpÿÖþîÝ_Ý/Ó³8ë¥<.‡«þœ×KÁEçS?Œo–—õð×qÿåç-¤úW?ûÏo ìŒýAð0=Òª?ý“?çŒs­-¢‰AìÐÑóñ–éòxÿðóü¾‰k ‡ÃÝ›ŸÏü ß=†²»-#bÃ'º>Ïñ“Ýë¿}ÿõq"FëçûóòÍ£îêÃ×§oÜ'Ú{=u=›úÚr. 3!tD±)ÌgóÜňÒ\ɉ[uVc,ËÒ{ ´yÇ66*ÃHÝæå"Gž_ϧúhC’s=¾+÷]Ÿ¢…ôl¼ÆþšÃ:¿Ëï_ç2>¾œn†¡£ÁÆýG¡Oq÷B­,ó½ %’^‡tmõY©¸y@èSÀú]ìo:Ä¡êøþ›”Q‘a Yj(šœ:$¹:WÔÓâÙ„+¬’5!Û\ñ†ÑmlFÐ^¬ “©£º9! NSf°ºjµ¢jvv6­c ,ì16CŒ±ë¢@4+]îr¶¹`¯DMÜ­A¤nvÞÆëºJ PöšÂÌc`ænHqLûg»U§©N¦jÞÈÙAh‹øf3„!†!¥¾NÚ˜ Qu4#“6÷&ÅD‘Ä•©Á²®Ë’ QrJª pì‰ Бô!삤@ &Vê®")¥¸^͆q ’{²î <8¶ÞºlÈ@ŽÉ¨¸»UTeXn3$m3”ªBêÀ„$‰Sâ`…ÌÌa ÐJN­…X`Á•UDµ±"˜à€ºÛ6ˆ¶'ùó$‡Ø\ßyż!¡Ü FnD•À ¸ 5ö~a`O㳎ãJ@þÞü{ì~úù³›ŸüäGß÷îñæ›oäm.ï÷¢ôî´Æ^¯§Tÿf4~ÐP »îNV]2¥:Ü@Ÿóº£´®Ót™ âãåü¦uÞ¥ýrÑ]–z¬|\÷‡~"½þw¯²ëÖ°~Ý /SÝüz)^sv,\fÓÎ}Šºä'3Ó\³ZÚ Ýõc¾G¼)جaUiNçÒê#Þýê"/:gâ]hÚZÂÚ³&XÐbàæ:;ëàéBÀ]ÕõŒv°ÆÐæì£uº–õâÙÐPêØ³(t6Ρ±4öRóTçSU㢔 ªkã D(diLÔÊÓ Ïm}&¿Ïk59sdìëþÚoŒâŠ âGZÝk(3°´ºÂ`èëŸñ°ŸÜ$¾EK†¼áËH2ÕêA™€Ô¡:¹™‹s´„“©ñv²¤”v¶3Û-±®²–VÔ•U(QŒhC1—²FU?Ï«ŠÊÚ…h![ªÕŠºØeª§jã¢^݈ÔÕmVdG0¨zÛ:ÔÉ ÍšêÖqW]+Jñ’­&*âäFÝSC:ŠQVª5S[,gk®(t!ŒÜwÎB¶R[ê²…·Ý7˜™ýÉYïØ¼ÙÔˆ„ÌœAHà#úÐ+ðóðOIqo¥Õu-˼º¯÷—×ý ö}#­kn­æœÇ1 ûC<tɵª•²ÎK«§ì†ØÅá0¤'@ˆ©ÞÅum=ÇVìœs3›.MJ7n&Í­ÖZ–c¤av~ꛢ¥ïSäÄjPv’R‹¡Ôµ¨>æ¬jk*bª!„ZsË»ÅBŠÁ•R2Ž]”óÒ¬2ÚØ%éºyÉK®t9Ibƒ£qÎùÜLU[³H¡A Í^ñxy|¼” #Q?õqícŸbª)ÐA´ô¥,ªET™(%Y±¥êZk£ÀV NœÐY£¨º>š¤;‹Å!¤ºˆ¥-¸~õ=ù|zû [:ŽýM>ôoÛéþk__g5xs4U'õA»1^w]¬3ð©¯sKûþîêE»îÞOf©Z?­Ýìli'XeÀó+L=삚޽øìÇ*Ý—¿øÕy~ÎX > »¾ã]zñðƧcy©>|%ß{1,ïúe!X ß]G>îz2¹Ô²XGKÎe¹8‡Û«Hé€ýâ@i>­ó—÷-œ_Œ/ïìp½KW”´;/×sþ“ðõGoùñ>éŘÇtq=Ÿ†o.Œö–ò}°Óp,Fʹæ ˆmx¤ªÈ "%4é%Æg¦ÓY¬0n.D¼õià ª®­TÖ1PééM;¾~ýF¦LÏrIÅB¸ÚÓà±sK–Å/&Ç|ÇØÉUnúõåñÒ×ùýåþb—ô<Åö‡!–تâ±È{¤yú<ƒGì H×1]ïw}—R’лºi#‰]˜£Q´f0aNÌ0«mmÊPL"E­æ…¢²;H³bv½Tes4ˆ›‘»±©nm3˜8ƒ \f6p#kN¤ ¸™–ZL…jOM.[CS±€œzˆCR¨‰L¬Lxˆ¶L¸NÄr:]ÆÛn-‹ubCƒ! aH¡K}L}´dVÈÆ$`r"‘…ba9Qpa ÜÄcJ)%Bðæ¤F Ô(1eT'&òÀÔIdËE­.}[çìEdÇ]Ÿ\ÌÍ-„1숈9Pd%¢H[XÑ‘#1ˆ•‡W1e'1— †Kó FÅ[1…+Á$4®P´À•‚9ƒ½’Q',îÚš1œ»!†®a—hBÈ­ä¹Z«i·ïû«T¥Ûui/ȼúD­zf¯`P`!ÞŠHèŸX>|W9A†f=0Á¡°âÙ(5’Št" m„ÛôüpûcùÑ!xúÛû/ðõ¿›$ýìùÿ£pèÇ?ûo¿º|]ý±ˆwªtrºœÚa•g/®3ºðR†«éR³tí2¿yÖã0‚oSµK^¾Á’ißòÙ ÔÝ<~ñþð~†ãÝþÁó9 /~„W×7ŠuÖ¶ÎÈ·¬ÆõL•MKÃ*–Ý+÷=ËÀq.•”á­T¬¥©Dê- ƒ­6kZIb¿ö‡Ãí}{¬Ë=—Sˇ†V²_£¾¤*¼Š6F¿z}\õdaÜMÒ‚ktÕŠaèôÆB–òVÇN­«kä…C“¬Y±.uY©ÍáG+çš'd³ìR]V·jf)‰zñ öBy“CöÔ9óayù{RDA ºÜòµ¾ÂNˆ;H츉Mö˜K­X¬±¹†œÓ¼H;’½„+¢®úÙá‘]„àVÛºÔK¦¹³ŒÈ¦Ô¶Ù…³m昃¤¾ëih<­ŠZªja倨¥.°80ލ`9 V³½¡ºp`£Õ$C ·™t&‰¾ÖlNÆPòꮞ}^+“;»“™{# Fµ:kyñ5nÔ… ݦêb k£\¨_Нs[š©;€kpO #‘«j5˜Áªk³° g1ˆòÁ(ý€Äàè’$t:ãÎ9ÙˆH˜Bsß܇0ɶ¯¨=i% *‘¥º‘mÛ$öTçõÉpu2…;™» Ë?8±ˆHÀòÄÝ–èà. È3!ÚØºâràD¶IèªÎyÃL±ˆþe¬9û‡»ø ÂLÄuPóšk™jk¥²íïúÛëçæûÀÕpn¦s®¯o»40żڼæé²è©êœE˜\Ø)¸$ŠR ±ï¢÷­µ6--:Ô‘sæ”êZZm¦ÄࢭºA8h3<ÁÐ]aFÎ]hhP2ªÚš:T½÷Ú´yÉM‹}›d¡àΜi­i37…Ã̉XD °µM¥DÕµÙÒÖÛÃuתn‡qxÉóº¡;ĪjªìP¨ì‚‹E ¡kœñúêÏ®ÜÚ’B#fewh®ëR ¦¬:JÃaŒC+uþ¶Öf IDAT–ªØ¥ÀÜ©™œ:êú péʲœ­òÐïˆ©ÔÆY¯öCŒ1vÁJ+U—µ4·uÍÙ׫ۛá oZµ`­8ÊñÑ»¤c¸x§‡Ët¼ Å!¦K©K)ÆÎ—c¾¼/ÍÛ:óòÏ÷õþ~y8bž¡ qƒ‘¹·ß¢K?½ÿŽÇpžˆ>Ìy¾„8¿õåÿËY}¸ È~CÎpd ›s€ÕÖD<8Fã¥+Š—k§ŸÜ½ð¢µyZWjÝîPPþÓúê³Ãu?ÐM—ø9îzsÍ™³Ž‘=qšym­x¶AÁ=ˆãWoßüú2‹w'~þÑ5õ{õÚ§øþxªÜsûh°ä7ï[ºüë}óÜßL»ãõ‹…N¿þ»/½a×õÞ¥ÂÂm´Ú i·Sn|¿œ÷×ßNïæÇóýt§c?ö{ÜR÷iÉaº,»ŽûNun¯§ù+9ÈÞgø1¥^wµh]¦Ðl~œ¿*6ãõ”.‹†››gó4ÿÚmwÈôî­ï™ I8¹SVkÐ\–7çZ†º;);Ì*L¨eå Þ§.…´ÊRá±#‘$!sTJOÆ£jª7w{/­Ø’™äÊåËMt_î^¼ˆ|ÛÕ•ýÅ@5ÂÓ±¬ÝíÕÅü]»Fƒ8-µ» Ò"g„¸¯†‹ò±þîUô¡ôK‹YD[ØXâ• ¹IóNшˆ%p`©Ìé*¤[–CmTë2U?·–ш hf«µII…uNc s”K,Ä€9±²7ÒÚ˜!ÎÌ Ò2GSé”)x´fT¤MÙx þZ¥ª}SÁcV,ôÑ÷ÔiŸkn¥”ÐuC?œëšÆ>t”ëÌD­µýõÕ̹¤Æ.LJÈP˭劊„CðÀ¨yVUQ3#8“lÛ¥Õµ²5¸‘?µƒ Ôš´[ vQg²UtZb&/è¨J…3I“>IO"b¦¨ÖѨӠ*Ä͸5TêN˜“{0 öªÅ«±‘6¸3àäUUÔ ê‚ z@ÌMdë0IµFѤg¹9KCð*ìI$Á<kÔý´ž ‰,žA\FE/`¶b97m !nþaîÏl ˆ&O³„ïº ØS»}ÈV3°zQbšÔ †ÏÐ}Üí~ø½Ãÿ—ß¿ü«ÿñ/þæs<üoÓ§ßÿk:à¿úèGó§X®²§ä×è¼GÍ9µx¸~þót~3¦wy¾ÿu½þl,óŽp=¦n{*çwð=¼]s¿ïR\Þ-÷ùô+”O!·—7ƒµÛ ‰Pl\k+Ÿ…5’ß§H5iõÒº ¨Š»fÞZà"aE;·ù¼L‚%ƒRÑlmµ*RSp»Ëïç †Å—Œg½ 5Å}WTW×J(@0+Y¹¢gåCôŠB\Øv¯öá:Jó…¦øˆÈ)ŒIÌ”ÚÊa• R`¦¶–å¤tDXæ ¬BnÔÜÁÔõ]·ë›1!!f·­ÛÚö÷ ‰ ,˜Çžöâ¸÷C£]MæÑV¼k¨ ‚Ôf ²¬':ÅoKÚ!î)vT»Ìá­°ÚÈÌz²ÆÚÁÌtEGÀÔlª´8âF^u›jG‰=‡@lÖNŠ!ôOü7¦H\Ù2ˆ6КH%®Ì…Ý›mPJ!Ü|c²AÀI’Y¨¤Êm„µ‘°µf€"—…&vkЂÒPr(Öêµi]}]ÛZ|­PeØàR‘È­©x妮͋BÛDS"ÆBBÊ N©º E Í‚šP€$po!Qd0Q$êÈ„HîìF&„@­sΠž,úd¦qƒ=60Ì [s¨ܼ9a«öa°“ƒÀÎP„G÷DœÀ‘881¹øÖV 3ß” Ž`0»€ÜáÌ›#0‘0Uf€`aRÑ·Þo±T¿Û“óÛ›×*N‰¶ß5÷F@›5?,a¼¾½;vñönW.íÕG/×zúÓŸ~òÅ—_1cìê³Òaw³.yR^Ç7ßh]sÔ¤ y.k;‹z·Èu݆²q §åh¦ã^J~4­‡Ýáôx^gô}½ö”Òèï³õ} !êâ¥Ô ˜n>nµ²æéR…ÖÝîjìe­½ Ëú^+’ÜSJc?’PŒý~ww¹\NÇ3àf¶¬YuyùòÙÕõ‹íQ§¥ãÎݽvÒ¥QwØÃ~ÜõçÓôððp|,»onn„ø²^Ô¥¾µrjoËj»C¼¹{Uk>·ÇÂ`£ýí³Ðef¾~~ØƹÍý@UËišSì÷ý%Yn¹®FBÚ£¹$~öòp¸éÎËûi=ŽC(ùxûýn-%õõáý|¸Ý—õüúý‰»Ý8Üõûq ¢|¹4%'¼}÷Bó,žÛÀU™..¡£ûaìäù®»’}_Ouz¼Àm³;?N`JØaíŽßhUŸ»_üâñòØNï1ŸÐ ‘ '·ÈNÐ-GôÏÐ ÿ@n¾%þàüõMxûmôí!Ôo©”ÆAÛØÝl³ú6ÇàæQ@HÏ,Ô¬xi¼ÃéMN‚žâ¨2Ìå6Œÿæ“ýäÓŸüÅÿô?ÿê«/†ï½øW?z9vÝ´´ãýÍôïôÓ¯ïþøßþ«Ð¥Ÿ}þ‹7+tw7ÞÌþöR…«DlÍJkËo¿fè0¤WŸý­Ö‡ÒýTï^Ùáó¿û›öüØí”O+h®ß¾;É»ÿî¿ý3Ó7Cp›=Å];`ÖúY||§ËÏB$–¥Láãô+ýº:Ï_|¼{{Òõk~qí—¬m8kY^¼ü2ýê—_d+™SrÍÕÜ¡l.&û.„~Lë˜XÈwc®„\þoöÞ¬Gúí:ï{ÖZ{ïÿPCïtÎ!II$%E‘6$¾Èeï™Oà« H‰ÁQh’É£Ã3¼sw×ðö°ÖÊEõKR²c˜s誻P]ÕU{ Ïó{ìèer•(,×¹»Ý4kÔÁ:A ˆË Uy%.|x–3ÓYôÔ¼4ª]r ƒ·R‹°‡€$ÆúMÌmq­äSßí»V©®Vó‰ØwÁ£•yïNoבkh„÷< Ü´§¾óª°G­ZŒ-¡¯„Bð˜çõ<¯°»¾Þ_íKhç<·Ä¾†þY|ÚP‚šáq‚ pƒ_„sL0ôwjŠhŽç”ÂÅâÚŠ(µâ-ðo·_žúOÆï|ßðßþàGÿtÎÿÃÿþ®â¼Åó¦/iþä¿úÞðæËÏÿùÒÚi}-N•x›Ú{>üôÛñ¯wì§!¿šòOæë„þšÿðßýÕë¿Ú€n?·áø³+ÚüQH÷ïÞþêÙõ“åú/ÿÅ7=°{–î¶›CWw­Þn>»ùdúæÿþÁ‹õ/7Çwóõ>å»ü"Rm~Z°û¿J“ƒ½kWi_ßÞ«ê“}ò™ÞäyÜ쯟×v¼[)jˆé4OåaÝîŸá;ÑM–/u:`$Ô¿`Ü­åmûi•û+Ò¥+Ïm]5õûĽÁ¸87?/ô°úÛS~{nïW;7¯ýpEN*Õ‚HñTõ’[%áàÄVØ †åÚjÉ K2x”Ŧ֚ ˆ1!&HÄÖÙòä>Z\K»äç´Œsúú2a3Äaàaâ@‘@nn¥j--W׌™b¬ ¯Ïœ(ø1¿Ÿ0—PZ+î*`!˜æÕ…I’Ñm”™È›.àþ"óaPDØÇMO1ÄÁ,tA!©‰;½A9ˆHDÉ[µ¹sqç"k0'Ï A”Bs\¦†FÕ¬4Tv%X#€yug‘…ŒY-0á\ Fì æ |ÜÕƒû…0ábèÜ…J /¦Ù˜,°’UW-MÀbøÝDü›v œͯä¸Áš-O5‡ÐrsÓu—•œ(:Ѐб$âNQ ÅÖ ?}qÝ¡{óÓ#Ø ¦Õêš3“ÅhdÇøÇq )¨jÕÂn4 ÆØõ[m“#䢿­)bNËÚX‰«æÚT±†>%tÛ²œT±ê¼æº:9@kPP3hUP¸ Ý]›—UyHâεæ%Ïk^ÎçÕ±”«ý N§‡Ãi·Ùªj-zµK1FW›Ë:ŸWf 7E Á¡Út­Ð0Pˆ½o7WÎÒÈs›x¦ÕæZóº®êVæ\8çé,̦Тdžž8dÍù\Æ«nØ]õW7ü0W]¶;ꆀl!P\´Zs­YÆU­‡sc7CŸ(øþ𝝝i RWZãR´-ÚØ":²¤ Ë\ó´Ö5“*‰/%;£Ocßí†t-èçy¹{{º§óŒyB®#†à‚¦ù‡Îç?´Ûù[ûƇxün4¾=˜ˆ/&"Ç”J8E‚燵ï1°ÄL϶WöÑgÏx¼éwÿÛ_ÿå[Ê·=Û<ò ezý¾îO×ßüäåég¯_þë{õápÀ©¿ÝÜZ×ᾚÕFpF rQÜ›ò®ä\û'éðu¹¿ÚﯿyûyÝÛõn3{y8>¼x:\üÉÚí³«.è:U=¶®£8¤ñj·zCç³Ä»pyw„Nž^oÆÝÖ¿:N4‹Vº±¿¦=§Mf¥è…ÙÌ$}×A<^ÅqùrÆ{zžŸäÏ¿?|÷»ÝgAÛ«óO¾)÷¿ §——§ÍùÛÆû’nfJÇ6ýâMûÆU¥‰ÕÄL}¯,×ÚmÑ#[âžÙ·@GÍÍĸ](ç¬Ä-šÒÍÕv9™œÉÅ›±†¹x?K„[YV*L(‡¥K}0[™ÚçíöúvÿÑF =QŠ–ºèC\ùõñ(»ö§1\]yÚŽi¸ åD]l pÐ%ÊD/UøÑûª¿üêÍÓ_êæ]ÅOù;ÿÍî×uzŠnwýòëûÏ÷òO>yvÿ‹WéÝC"Ù…Ôîët¬½6Þ­cx—ó˶º?ë_½óÏžm?ŠË7µ½y]¿ø—?}úÏnè–_5wþñ Þ¿Oòt|ñŠ´àí7ï¯&jß´M·!,ÝFnú«’öŒÚµÛk¼54h¬cµVíPf6Ζ5iîm¦:«EG‡ZU‡–Tò–Ú¡"UôÎ\Eì(uÚ™^¤žÖ !`Ì𢫯§{oÙæ§]LÉTµó%¯ëR&ÄZ ‹·•J35oðìd‚榮g0ƒýñL!ýõ:Ïþ½Z¿Ûdð·îè7×ÉAR[¤)÷ÄqðHš0†mûÚØ`ê­YÈÀQbǽEjãˆçÔC¯º˜BÎNËlN‘ÍTQæVZªê޶Úynw³>Ì,ÄÉÂÅâË@DHðäÂÆÖBTMÜ‚3Û…¬EÃÔ agv†` ô]Œ˜w‰bT¬1"(¸EòÊ^&[,,ÂL„LKó6éÜSŒ`qp2S«Í[C˨@H3µV‹—Ì °3–eAi¤»HñøHDñÛ© §oÖç›ÚÝøø«ÏHµØôu^¿¶ôdûi¿iåõ<¿î±É‡†wí*m×û i@ñÃ4_}ëêãgŸôiÓ€éÐðöduìXb¢¹µs+3Ú"èšôÜu©Q»XjÜ]s—C ÑÜÍs$R¢ZÁ¢hŒÊ@ÙI«6St¬pÞ'ѦëÃJ¡õ.­qoXÍ{’›yP·Vï«Í‹ªp¡æ( kÖB„!ŠÐü® Ò§aÈ£8É%õ¢#tÎ"R[nžA W¶e2¸¯sW=M^ u5¤¡cëiŒ]é¶ä@Æjö@si-hŒl¥¡Äܲ6Á3¦CæeoŽJJA‰sberÀÌ«µ†²¶œMÍjiUQŠB5¢ª: äp3"Ä!‘™AKzýoÖ™`öa Ç,"—#ÉÌTí÷Ð#¹ƒ"(:‘«ÕÄk¢s‰†uÉ€:y x:òw·Ãó÷À¨1wÞ6cG>msœk=”’k!#‹R)¼6ÖŒfP8%™ò4·ã\g•Õ‚1“;µZ#âlÎ$† Ø êâ;‰ ŠFä° [ô‚)Sqe\ˆˆð^8 uÄ\™]„˜A`!.m²ƒÉ¡jÎæÙMû u€aSmS´ e0Ããå$2o¨P;ÓºÒZ]Ô"1˜Ø˜Á§žR1RG$D¦FÍÈÈÔ­¹*ÁLÊÜDˆÙ‰àìFƒÂ(J"»°á1â•z;#ù¦£¥QUnÕ­´ºz=cÎ`ÅÅ–À´™ŠÈåäב;Ü]À̗略$s7cæ ¥èõâ¿ÖÛê%‚~ o…3]n%!á÷õÑtöÄìæ(çÓ´ÂÂÝ&@:íç4pÚ«¤®ßoŸtq„&LèºM:„°}²‹©ZÔy^[SÕüøÞcÔ¢çÓÊ\Zk¥”º4(´ïsdʵ833Á×¼š"v¡çQ­ 7íºÔñ½ÓVZñ6ÃļµeZ]ñ¨žäP‘¡Xr5xÕ5vµµæF}ßqJIDîî–&´VBàǹ»Â*ˆ(…BG1!¬ašæK$€aè/ÎàCŒ¡ÖÚšå\ݸ5c¶u)µÖe]K³Ëú8¦BŒ1.‡Ã:•¬tÃe›VfÕµµÛÛëÍvÄÓélú0\ÛíØOÓT—ÕvÃ~³ÙlûZÖœ‚ÆÄVWDIϞ›óœ¤ŸÏ:ß͇ùÔ!°“WÏ=ÄQÕ¼µFD)¥¡}?ÔÅ–Ú^¿=œ—÷Îéá”_³”¦ù(.Q\3øÅ©ømÏïÄšûÛ­‘ÿæÛ¿û\~Pð‡+¿Qˆ/¶?ƒª_rÜ]ܱ7·j¹ÂAYíáþýO¿øë»Ût7Õq¾_Α¶œ¶ÝôжC|cJ½&õëÍ{ÈÏ4sða­R«‘j'ç:çöâÿÉ?ýô³>ßõÝ×?ùòçÿó—¿øù«OwŒ3ÆIno¶²Ùþêî›Ã—^|Ǽ«ÆÙgÕÒ°0ÚfØ<¹}ööÝüðî­®%EÍëö¹ ›•£÷·¹ÂŽ‹úd­5K ‡ÓÒo†½öðÄyJà׿]ê¼~Tn? ×{ÄíUZ—ùíù]Þ¶_Ü¿|•O'À‡`fëA–_µó\N¿œì=õÃfÓÚòä6ø“M Ë•mówx­£[s/9;ÔÉÜáÖÜ#èÒªJ—65•I’xñ¢03—ruõ,çjÙ#‡ëí¶cµuñe F[ÅȰ‰¾Û¬Wö¶òül÷Ñùôvº;æ×G¼ÖSlÒÊ^âѼí¶Ã§û•||³öÛÝÝrF*ÏÿüÉ÷ÿà³í®'ø8\Ýí„« 5r¨V `muâræSÍÝ“Nvvt&› Þ Ö|:š÷V4OëÀÝvì…†âk.@h”:J@ȵ é¥J*Ac€º·©_ ¶˜¥†\shôTâØW¢œ­sh­±1 âÔ!¦ÊÍ»èÉ0:u¦R•9uHøõbB\Rb‹„4*]¢Š8xŒ–¨‘Z²¦Á¢— Òá¼x#•ubQ¨³‡©­©­õ>¥è^K9S!bÅçDÝšFo¤ÅP#œ«ëÉ$¥ ´óÐI³Š2C ®oàfsŸ<ÄfÜ´k]Sè·jÍMÉÁF,ÎÑ©–.£³V¬yUcìÇ ÕZU a ´ Òs³Bè©5¶µµÅÛ¢M›×šfØ«foE†¾-'ð5§h s QËu‹Î3B®ÍÌÙIØLáV[Û0nǼi§Ùaܨ¸Ä$Þ!† w×éB–3ƒ¸Ûy ·ÿïl¡îJ¼RÚÃɾ Ø|ƒí¿úâG·Éûï ô2–ã»:Rþ–ûÇ¾Ææžp^ÁÅþ ¸:‹‡ô‚íMGî=~òd'zó gÇö ²‚¿\¿õ§×týGÿëùÿxw´®ðI¹Ý¾ {“ñk¬óþP é¡ëß´TRûå[ºCÿ¬¿‹§¶ƒ6ì$õ†JªÖ¼@ h’V4ŸÁàyÒÜPÿᜠIDATHW”†&˜ ±˜/ž¬õ´Ø¡bg–K¦ü%ãçâÉ'@Ü8qœ… .PvˆáW"†]2GP6}¤¨‘D¸F¨¸F¿Ü'"…F½1ŒSôW͹®Õ‹ÃLB¬¶V?ªçÝYÍÝ¥ œ…54€ZÓ™óJµÁÌ#ŘÀ) ö´iÓ£gN„è@:5bwVP{ÜJºq£ËëÃsœŒbðË­ Dä1 R¥Z©X0p­”3/‹-¢i²¥àS^Ü5íâHÂcPáÑÄff€Q]’QåøÛ|#8üõr'¿Ð蜘õǯ¿W#ômó‡dp˜a]›woO;Š!Ðz,ë¬añù¼nöÝùn^ÏYU§ua­²Èª«wûŽƒhlž|š–²zk 5XK­õàFªÎÎ)¥”š‰UÕÖ¼¹»9¹ª­S‡‹Úå¤fè\$%]=ŸsF$CÅ~LˆB¹V«ÚŠÖÚàTIͬU¥ÈCGS«EúÔ¥ç5;€ºÖ³Ny)䈒B衪)tÞÔ›sŒîîêDˆPToZ/ÙXÑ奜ç©5P]áµ”BÉË´æ±ÃÓ§ûÛç× =Ìçe-…Z¥¬÷÷¥¬a³MÃÕ¦eÜ¿;½çîOŸ>­k#öe™¶›Á˜`uèÃí~ûíOžG¦»£ÏušËzÈm53Ä@¶–åŸÿÅ÷þî~z²yNméWûÃýM½?þòÕy<߯ã(áäç%/³…eéîjg¾×O^œÕü ¦A ·cm7W×O¤étXß¿.®JÔq•ë¤XgH ÃÚíµ£Wûî.=åñÛû'ï_¿ú‹/þÏÍÇ·Ÿ¿8¼é6ßÖ³˜È°é¡¿ùÅCœNïzÏßË6í”%¶åæã­|×[Ú^ñ§/W›m9¶Ú´ZSó¹dé… vc›‘Ù˜åt^´"ô‘Ã@£À†(ÜFJ^½ž‹Y![bÓ‘»}H7Ûq®ÚÔôœ—²pnß|ýöÍÛ/mñI¿¸íùvŠi-Óû·/÷×q{ããfÈ›’ÙçÓüêÕïùGöí?ýó?Ø&:M/ŸàOžÞ>y5ièŒj­¥ªU„†Ðpj¹_lg¼OØʵ V]³©s²šËŠ‡Ã¢ÝiäPGà,P‹!Æ"›¤BŒpC‹:AWà¡9¼š¯0)X&CÌÏ”žeÒ³: hÚZÍEÙâÐÅ^8&T;µÑ¨‡†fìptÒƒnp7Nˆ®¥µÒÂAî’<†ŽƒhB;‰{À‹‡Øc.Á»6ÒÈ‹ÁÀ` ‚‹SfT]Öp"C-‹ÏF.1i™|%_ ³£5aa—Vy¦!L=Âè¯êHDOÒ³ _$®Fª½ÖѤ!Hrò%·sqŠÞ߽ñàÜPLèB˜bª£Ä° dñFxt õ8Mcн†¥(q¤Z,×âÎìÆ±“8p0ª¤‘³6ݰéMÕIC@mÖ¦wÙsmÕÍÀCd£¼›§t4#1 q#]×…-ÇpX&¡êí‚ývwý v3½”0¿)Øç¾_œÓã?æl>.½‹Û)cXpwñoÎOþ wa|yœÇ=F´›„Ú}|žŽéÛ_¢ÜY}gi‡'»ZqŒxgèovÏ?þ6ß¿+u©çɱÿ<ýÇ?|–ËÏþÕçÿË»ÿéü­ï¾ý•µ·øþ÷öü•—ünµ·þ3„×h7¯(¶OïƒyýãWãCו„Ó¯¸Ê©œæ\nìðv×\ȶ*:ãÛG3.˹TœJëYóÚ²F£Øq RÉa&Qm"æá¼¨¬j¹ø.m½¨Þf]¼Î53ùdv×Ò U0W'ª ¹¡9И”¥E6 a&^)•äÖZ³ªÍݼY3¨ƒC3³‹UõâæËÚÄÜ“€÷[×ÿÎíЯg‚NLaÈÍ&-€9‚c2‡µ9åx”ÓRŽZWG‹à„aƒOúVÔk©cê61™£vB$©¨«‡† ¡gé—v¾?Ñtìr¦¼5kÙ&¹.Å–†fP"7S×J®ä‰Ù#æî`÷æaµX pr5oÔ€ÌÅpIe$&g‡¸ ]RÜ#\`lM\`F 2"cLƒ@™zº]@%€à†Ò.Ú1'8™Óå÷Ý›_¨ØO¦Ù%£6{]¹š™;E°3È!àˆØc|³¡]‡ £ƒGD«“º¸š5X55z\$@- —noºøš!bº¼«ÉÀ«Ò´ðC‡hìu™TVœ3f³"D­Í授‰¸'Ž~‰r""ÃÛ〠—ì¦Ñ%3&}\’]-þAMCWöïmG±ãÂi¸d,)´ œqu-1Dj©–©”².Å?¿û†ÕPºãîÌÊR>~ñ-iÁL ˜ÛŒÖÐÇ ÅÕœœ ´–šgeÎ!E ¤êëR !˜yÎ5‚92±B5+ \Q¡§69Íë´æÌhE/“ 8‰„B꺂D^K—@D9g3„–e©UÝ_}"›Ín·ÛlËör«¶ö0MË’S }ßý`ã&ƸÙlN‡R 3«ªª2«fʦ|ÙPu1ª¹™qJtÙ>«Z­Õ½8p{µRÙÝŒßùÞ·¯_ì¦2Ó½ËÄU‘Žg·v3ޤAKFiÝØÝßßÏs­ŠÍnQ×~Hªº®³ C«ˆ„ܽ”š—òþ~>žV®,F¦ «Ž:MÚm¢ˆP+mžÖÓÙ›-çˆp¼_ÎótÖéŒ9ƒ0Xeó¥'ÂEIëPÿ÷“¥Ýýz¡W2÷ëËß±þöŽèq;ì«Vøõ/\–Ë®î ¸À 0¹3µVW„1\_ݦqsZ懼¢ïÎyq÷¡ßŽû«ªEPÑͤÓîÉ·ÁnÛÌôn]Á§nÚ-Æ›nh,®Å•.V©˜nžÄÜjñ÷+oÏò¾ÿú_Þ|ëË÷oÿûó3zv^ß.Óá£ï>»û¿z{|ùó·é°ã´†uÑlëæ<ñ)!‡*÷66äÁi›Ö#Ç´ ¶û•Òëx¦µèb¢œ¨sËõ¾NË1,T"”6éžv؉óìíëõî‹éÍ•ÎËPÿZ²×uß¡6ćí®0û:—oêbºãÍïÆskÞ–¾ßÖ¡…pƚ燇Ã|€Ì $)3.¦Jrƒ`DÄcº?Íð¼hv ‡1ΧºÒ½†°Ë”¹•í®®ö¾®Ò‡°õz:½_Nõ!µ^‡0l®6Ïã'^k\m¹_¼»Ïãí¾•~8ŽÜ' Ûή¯Î‹Ö‰î~úÕØËËw¿ú·%ßûèÓO÷ßËx8=<´ã)Òh¦Íªi…9„pj5º—:O^êXa `*Qú>ÉìކyɶƒmN!“Ö\Iò~Üs6²õ¡àÞQëò^%8¢ØÂضü6Ç(´ аLK,¬njÞÀ !uû´R¡‘B´oÔ³”ˆ% w ª­A j­vqpRec UÐÜœ½ q׳ºÌ!&œ‘ÒÐf#D¬ “C"`@ˆØøj³ ùêMºµÖºš¯ÊS_TÏÕ'Gq,0«…†Phbq@Ú Ü÷؈uh’º'l‰É«·ÌZÄYÔ‰¼‰9â X*æŠlp0ÇÔõ›þx>ÊÐuc¸è(ûTjND”KmëJU˜CKVc µ)¬·Ê™;‰#**ÆÈ]ɬTmÓZÍNÊg•B^…y+JäÉã¶Ï§ª˜ZG¡­^ʼncÇìËãNÐ/†@V·ß’ ü„¢¿K?ô[ó´Ëxí)ým„ÝiÁë·t‡ïÿüðÝû+Èø&ÌsÁîá{pcÝtß3ÿùûãKP(øhIxù2p"¤nÒÝðUº{w¼·-v†þÏâŸ<óþÇŸÿ_ÿ£ù¾”"Ý•ÛùõÚî_~ñæøWî§8œ¾)ó¦ñýktΠ›¯#âWm>žm»‹›¡“ZK©³·Š|*®¼Jp#&)ôÃj:Íe±×ïîúècÛsŸG’B|v/Í¢b…Ý›žÅòÒJïÊžM›’ c°RYš˜â²8PCQTºÐ¢Ì*h@e'!r57s7ƒÔ¿.ü¨Xbfaq¦Öì"“ûõYöx~ý~°C#RÌÍ °$%Ë ÔZÏ©Ä3¦rR/ep‡´ 7}ºéeO”¢l{³ÌTšQ3¸„8Œ$œm-ó)·C­µ>Ãbë¼Nùx^L@DÚI4˜ÔM›Âk‹® ‚Ww1o€Ø½«2‘€„æ¶Ë ‡@t 9¥\„ ñ<ñ ¶òÿiX#0‘g‰(aq†©Ö\çMáÕ ¡IÜØAÄDÆÚ?0Ûü"Ô¹¼pÌÜ̽ÐÞ„$ DO‘úDCO[ÂÞ àèÕ.¢3nD jî‹q5´‹[Š)g7˪vƒÃØ…Œá]ä}óa†s±²âÍ Cä®C˜4œÁÀT"QõÇ€3 …(!±$s²Æ˜R—B"Rø%8õB«»ì¯œ`ÔíñÛ ,tQÔ™ÁÿŽôíÿ—™»ð›ÿ~3 bP&ï‚„T£©ê„š´®àøÈç´†¶šˆ7GñRH}âîÒ\Ã1W¹@îÈädÕZ!q¢Ì`UóZ—¥ˆ0{­5¥‘U)¯Ê‡nßrÑÕÏËâk&9Ê’Á '§‹çNà ©ë‰È×""'&±jÅ ÍsíB!òËVµ Q@÷½ŸÏg­­Oq†";„åj»Ûív-—”RŒ1ç|šÁ*´<ŽÖBMUCÇ@µ¶FÍj0O1Œ›>vÜÖC'ŸoìëuàM†›-I@C‡õhçyºzõøp8ßûõL=ÆïáÏþëïÿøM=þìÕtúúv ßÞ\o¯¯¹§5ÛoJ` ñ&bK¹kÊöðÕ}X+hs}k¾xw´Û=®_ 5|ýB…žáe"–H¡‹©C?¼>ÜMX¼;/á¸^küd ±:¬ï”»íÄóÃÃí ðŸ~çÅ?þ£äÓ´Mé«/~αùFãÙ>ûѳûåðË÷§¿¾ÃõÇ?ñÔn?â„5× ]}¨¤äN„è• &'±ԢõLØnµOûÐóFÔu­˜K‡ Û¦ #)˜7·+ÐJqǾãF¶´rÊ8(NÀÓµßuý¦;åGnï õ,’W>i€A€(4„pä:ZYy À) À`jÓêF‰Ã[ïˆÚBF"h+ÁN!0³¼4'(¡ =JÀÙ,&D¬K0ƒ‰€ÜÉÄ3Ùlµ³yÎ:{=ŽÐû¬'Æ ´kdB!4vñFfµÎaC"p6 ŽÑùÊâÈØÓìÅ¥ÕTr³»ž7ì-OU§¦f¬!0¦FººÄ­ò T8Sc¨™£%®@lGa ÎÚûšwP·¶j4°ô†%ƒøÔ¨# ˜(sÂ&,yÂFó¦nhSnw‡ŠÉ¤uQY,”œ­¬ õ8톺ª'Ãè„å¼ÎëR*PBhdú˜òø}p‘¹è²yÃï«Ò¸æ.:Ef"õˉr鼊ù«úd‡ÿË×Ïþôæÿ‹­íËp½¼ô|Ýmlê6Ÿ¦ò#Òûa:…m·i³\¹6j­®õp~6^wÇåë»ûÖáùòðíøj¸)On;ºûúË:ÈŠŸüìËW_¬¼¢h…|oΈ™¿xûqÙP£§kÅ\ÎÝGW¸Á¸²|q*5Ý cïËÃ9ØYÕʪEÁ’U)H×w]\%ÄAËÚ˜!Þcm­C´D¡j=€Â1[8½[k# ½f;¬Y][΀÷ž lUë Vr…6r'SRC3U¥J^¥¶È-BƒW2jÔ&P¡Ü´]6Þ—šôâu#0ÂÅ(CÌÌMíñòÛMÑïíXäGu]IƒxI®˜r›z’ <ÑÜh ÿ{oödI–œ÷}î~–ˆ¸7÷ªê½{é 4ÒL_$½èO•Ä™‰&‚Fƒd€($1˜fz–®ª®%—›w‰åœãîz¸Y³aà`2šŒ×Ò2Ó2¯ÝÌŒŒ8qÜýû~; xŒ1申À™¡ê oîulcÃÜØ<á.¥¥'â‚@5qET= þÖIê‡>ˆ6]–ÂÕ‰ÜS0A5:RšðQ·6×V“¹¨’ƒ]ÃÉIƒGK!RŽˆä! Ž;{õ]F fD§&Œ(HLJe®y‡iƒêPƒY;^+Gný±îbDp$ Äây QýÏy ~v D(ÄHÑ ¾ @>C3vÔµ5PÈ}1ȈØ­;»Á˜`$V'%œÈBä“`ÈU}ÓÚŒÝY4®B7¤.#Iá¦á ̨Nj_@’Ž V4‡¼H2±=”éÇ…èHYø‰³Ç”ÍÌÜpqv‡9œÌøˆÓ/iFDfml{°Š½éO/[ìî,§¦ nJ48D@U´ jrõBH)Æ”^Õ´ADçm+EmÁ‘»n9§$1g)Z³B𣲉HiÍ­V¡ÐIìB·TZÚADÀÌ]è€ÚZÓâf!Åfj°f*ªD^MÝ}Yj÷9d"ʹ˜&Ézí(–å¦ú€‘¨uY–õÙ©™1sß÷}ß«ê~šÝ™SJªJD!„yž—EÇq̹w‡ªµ¦N,¨Zk-$0˜,läjîw]LYŒT¹tëx’W_<墒™”©p‘Uó%d¬OW8xEy½™wóÌ„.RS³™µâU²0!&#—ÖÊa®ÃÙyê†a†¾_Yã9!û»‹ÝÝas¿ÜÜÙ›ÂÁ1qžÑ(½Y½Á£Rõ¿<¾¬ZèoVØ?Ì‹ÞTD°‰säÍ««ÔÁ)}èh.µ]\c '½ìÊ|ÊíÑ“®ûêeøÀaÜ~‡ÖëTcˆßˆ¿ý˜.ÂòT[‘Í‹C½uš0ƒÈÉú”×yGªàÛ×ûÇWo纷ó·V÷z³­‡óßùõß{üGßúãüúWÎ}õJÏV¿“^Oõ³¿ü<.FÂõ@£Öûݾ–V6»“6“ã~iÜî³õz´œ¦k V§Cy½4¹:m%Ùµ”:–;xÝõ»ç³~øÞéÕ'—ÏïŸ÷1|üÑ{a)e²ÏîqÝ,§`5Ð,>É[o}¨w¯¶·?œ»šO“H‹®$ïwã´?hE7°HÖý2‡ªpˆLDÜÜܽºÝÜo)×þ¤=zßø¯.ïŸ}ºZåg?xõ¿ýOñú{8|J‡U!¦Zw·7Ú§ïïB='|ãwßyû~p¨Ë~nßÿìµUlï6šï}úÎïýw_ÕwíOÿê?lôðáÙû»þE?Ä*õàíüòíþ2ú¿ùðÏÿ›'|ð(e5,u)~¶,ˆd&®­¢1@ƒ Áö Þ0³V¹Æ¾Ë¼„yœe·´Ý‚ÛâZö¹ ë˜"˜œÌÅ<'pψ‚‡VÍ ¥%Èl:jˈ»pïõõèI».ÄNò[çË2U-& êØV¾ÄÅ#ÕìÆfäªd•°x©…‰¥ãÖ¢"9zb&IǸ©*D·@KÀHÈŒœ… ã†^öpöJm¶åàË„²( öz“àÜ w(‰ª©Ä… MçVƈÈ$)AzÏëä5.®¡u®€Ö*§ ì¨Siõ /HDCеX=TªKÀ¢XÄ+û1&8ç®±©ÖyQÉÖS¦óýN˜„­‡Nú>­hœ÷Ý–f8«³€¹´¶^õ<ÄiCÈY\X æ†Å¡¡-Î.â!A°§$2„Ã~²ØÒПw'ÊRæ­N.!jZƒ('Êø8´±Zx€?ýí j?¾ý£þý5'3‰S}Óg¨ƒÎ!µ?ý·öîå·>9ùýëPåÞ«Iäk‹7õ,œëÛ<à}‡ñó)z™oÆåN¡†öÛ¸±Å;' : %êyµ9³™».æÔ‚y_’/î̀ÌÐ`Iµ[L7а4jã=,P¿îd-×êËR–æ ‡¶4_jÓùxXéM( ¹SY³J^`¬E¨ X½Í }P'>”C‚È´T'3²¿ß°LEÄÞ̈Ž=:úòlÃN !0¼¢9óÌím{W*Tiq®Ä$ 5¸¡Uß)o!ÐF­FõVhF´Åï«L3ÍÕæàÍ­ÎOW½Ìå®”i<ŒõÁl¥†&†Ø§(µŒT]àÔÁ+ $§LÌ Šìîͼ’›“;1…DLÍAdG¿ ‹‘‚È›Q a¡Ž=‰F#£XÔLý¨À“{pZ­­ÅÍ¢{ÇLžN8öÞÍ~«€QSfs& 0çÎD™B‘3 ²‹‚ݨ @p„# Ñ)€2¸‡ð|äG@°à¸jšz3Wb¸1ÈŽ#83$¢àFìnêN®LÒ­o¬‹·tábl)ä.0W/{›'/ ° ;"¶Â`rw¹‘ÓQs‘sQÁ?"Î9ñQÓx {a°¹ “£–—œ•ŽN§ŸpcÓß*aú©ó›ì'J¢ç¢üØæLÓ²,m!¢¾ï‡.]žž6‹N·›×É9eá.áíwŸÜ¼¾[gî¹oû…2]œ¬û>ïé0 Ýúl¸|çâÕÍ-÷˜ —g9QìúõÍó^qš‡û›ÍÕéÅ£'íþÕézÍÆºˆŸV­¦ÍŸ<~tõÖeê¢Ä™DÖ]?dë§ ãì,ó §:wª †#X¤p:J y³JþêåÁηŸy0ó/õü_ôú¿l[ë—}¿áùfÆGÕôO<~ŠèøòºÀü¦E£w¬£ÂûáU\DU”5Ðqpur£ËùÉ9ævvy¾ýðòÝÎ¥úÉWÏÊïÞ|'}w:-|VŸÐù‹g‡á*”xsHûÕ»'ô$^¼Ã¯_Cv5Õ&¡í÷ÏBëÕ[ÃÅÕg/·Rq÷½ùå·÷'OÒê$QéNãéÛñÓßûȾx®ò㯽õƒé•õ÷mœ¾rvÙž¶å/'Þ†~ßó2„[k6?²N³‡CdXÓ¶ìÂËgóRçVmž^LûÖž2!m÷%žt‡©Nûûé°yû²ÿÍßÿðñWÞú“ï¶×‡Òm·)_þƒÇÞÉŸ]ž„ç´2ÀÊØ:Âa;½xݨ ß—¥êПMv7Oöìé«ô›çð¾‹y»ùþ0`µ>¹¾™Ð =·FnEÕÚ̼´YÊX%âfÁïü£óú?|íýOVûÃÍ?ÿ­O>ùôÝÿóýö¿ùŸŸî¿ÐF­˜ÏóŒ,*¾rz’¾öŸÿÎiÿÑÊ…ÿýøvYo^í,¿ûO¾ò¿õÑ,϶e{ú±Ýòøý·ìd:V]¾XwgÃeî6øÿýïüöï_\¥'8Ð œ ” §`IÑÑdZšßWdEß°jX[ÛX?iÅÐ IDAT¹“0ȆùÕÔ¾pÜì4ZIäéìêÑ¡N›¬CÈm¤¹%ís¢—ý<ßTë=9?ÿ8Ï_¼|QNåì“·?ûö«‹OOäÙn½ÇeÃ?ýµ‡}ýÎó®Þ#z'çÓ“<½~Œ¸¼º™%¼¶q®ÚåÓŒn*‡k¯oç«ýB±¹ŸtKjøá7ïC@:`¸2úË““Gisؼ~vØï·'é~¾ç éb­·£N•i ´Z&UP»•yä–†´ºØP— ¶4Ùún»8¡gô¸bœ°Wupki»«$áúzß¼™» ¬˜ÍGŽœýèx’@ä Œ‰ƒºsñF*ÿ]WöÕ“Ìñ06 <¬ONüâìêñÓg_\oîJß.ß¾äKþüþõóߟޚG”‚üLK©1´f9J0o_p.UJ«R:ÐÙl'›v2.öòz™ž|å“°ªÇç«Ìº¨ä‡Ý!2 ã<^ì"Ëãw¿óÞiöw׫'üÛ¿ñÑG<žùvI»/ž?/,[].ûõ;ï¿c¼yzøì³ïýð‡_ü“?xw}6ÜÝo(úÛkö.Û”Ñ(²¹°ÃâJäêÖª£¸¨FãØ2uÆ@w=öŠ9c1T²ÂSmu¾+¢68!(\3´j|¨~hSõ…}QÌ UÐ⡯Çq$¬@̵oˆpÁCiÄb ˜†ÏáÈ ®ª•ivBŒ±[õó)†% !Ä>J £:W›½õ¢mqÊQ2y±âE—†À]Ì^}"2%¢Žã@AÈ­ù$‘WV`£ëÈu |È´Ìa†À¹yDI¥y„Ôö˜Ýx<4 æiië'§Èp¢Òj]*¦¥U—lîh<e.Εy&* %b6´@êqrAPa¤œóJ80%aµ˜2R Q¼KFæxˆ&Â§ê‡ÆÅ#bŠ‘"·èºPŒÝª[ŽÊ¶`afëbŒCÃrVgµªpÒ°†²Ä<$t=Ÿ-¢'z²ök[çtz")"›QUÕŸ#Œ¶Ÿ?èù;Œ~jÍöÐ:‚˜sT d·~øøVùÞþ¾÷õG7W~þ­ûùñ—åÕ£³WÁPëÇï|>]/à.îôC¼kXnób¹™OØ›úx7O_=>nž½úæ¿qw‹A]Úf‚øIˆt6”¢DKŒðÓ¨g½ô!j\Å:t!?:GÎÞ Åb¥¤¬s)d»!$'­U§f#ãÜd`EiÖ–‰ÊL%PãÈÑ+;“«« ùÃÄF­˜¥a&®Bf£ª¤FÖÐ ¨GÍ›KÛC¤ªQ{0j;‚¸ŒŽ›îH "ÏZôȇœðЉþy]<€üÿ j’ƒÉ¨9Taæ³ë¡éAÍØ<7‹ÄFÍÍÚôrÿ™³…ËA– ÈŒ4ò™L<k­6í<´Å*¡‘Cbà‡”– E+:ïfŽ9R×ÅÎXÍêh±Bè€x¬ã˜|a;Òœ-2'Gr­ÍÝŒšÂÍIã[@bŒNÐ b!’rpnðFLu×ÍÅ ÜQÎ$âp’1CØõûjà E“¡'°8\MÕÝ æþÀ'6Dòàc֘̔ˆ(™E!58=”Òd€[)S5u4>f«)g8§)·âGO­9ÜXœAôß ­Î}Â6µ >“·hÊõ ZÊAp&rb€ŒB 8ȉd˜ü™pk x`'qH„XÈ,æÚˆŠÒ/&+üÂÝýLÓÇ^ÅOnÇÃ[[p;™¾Îä¿sùÎÛWûys{ÿj¹ŸVç']¢ aë8ÍQÀˆe6«£÷ÜŸ¯¬úv»UU"& ±JÍ\áÞrÇRD"8R·Ž ©øùv³åÄ`֍л;‰©A¡ÞŽúM!jp ”Cˆ1:I)¥´…)Äœ8ª¹¢¶æîä8pà²Ìã¼7_H`Mw‡­6_­r\¬ÕR˜9÷]JˆfVk»zçŧå×Õ÷‘7Gìe}Ö3ÓX ]ò%JJ‰d8ÞLD$ ¯†O¼¯[ ©ÕZç›ûëëû“am‹…@ÑÈ)xè¸Ò¹œÉ€ÂÜ´ïû”ûœû>­ÌlšJ«H1±SiËrhÛ»ÃÛŸKð™|Oê~œP†ZHxeM ã÷[»¿ƒOZF:H9 ÷¥5SfJd?Uù/½û§¿gT÷nÔ—)¹¦Ÿ=zD8‚ÌÌ™!,(™Çj§CwyÚøè­GëÓ;½O1Ä.Šõ=¹øjF|õb'‹—Õêõ¾œ—óÕÝ[«gébogÎ7uÜÑþõõv—r:åÔ‡–[Vkœ¾#¾n ¿.û=ž}Ú^ÌãüÞ?º\}WoŸ]ýƒ“Ó››§ß¹ÝMxõýWä.Ð÷,ÚìΪ»çjXªÑ!¤© tÎ,^IZõÆd&áþÉúpØ· <ŸKî¹,³oôƒËÓ6ÓÎi c9ñýUxyv«(w-´ÃÔ6õêòQ/«~2rN9¬Þﻫ³íóz»ÝÍû÷+ÒÖ¾«ëõÉû¸±û7O_ß^[wž_moë3L“Îå˜}Àf ‡ð1ó&—ÌY9²ÊV8}ÃeµPù¬–iÇl›Ãf;¡5|ŠB ¨Ë×?øÄæë°×Géч_ûPÞöí|ûôùg»W›Ís¼siWYÎ.‡·/`ññþٟݾÝ=Ϙ÷›éÖn¿x÷ìɧ}zÒõÞšZFwœ¡®‡t5Ú5Ì6‚)‘Ã\T]ÕjÁRmV¡Z2µÐêÄ2u6'/ŽÒÌiZ”¦™V„|2Rv€ -7³Ý+v £ci­šà^çStP`3‚|Ê,Ç‘>ˆ9JãVk‘‘ÃÉ8g¶šyõy»o¡¥’Ø™E<…C@Š™È–†bê°Å|4ÌæÆÌbË<—ƒkwVEB”$ô’Õj™ëi^£±©A;4á6¸Ã܉ԉ8D„Ž“Kæq4”…Nv·ÄúnµèRv5jIФ͋W18©²š2ÐK •ìÐ0kÝ.mß|l8ª ÄLRw tRG[0ûaŒ) ¹›6…D"Å`NUÜ£‚¥Uôdí~Ö…‰#;·©,u«ä+1¡¹VÓFQ8„b¢’ªGV@2tZ¢£ëy^Tw»éÕˆ[½Þ½ÎXRˆkN%%tnÒôÇ€¹ã{ùÕ* ¿ö%Æ׿©¼ŒˆˆÌ †RLœ'ÎåÖÂÿ3âÏëþði¼Â§†‹k„úñaÀÈû§² ¿û$]œ§ó1ö|¿|ötüg'ðý¯þÍ·ê%ío¦ù&† C}ÜŒ¥»ZÇ>ën'kä“ÀëlÞ*Ju†&œ_æ¶BÕöâ»?øŽôZßß ±Éør>œ¡qˆ©x›|™ÆiBHoHÎ kðâT*+ƒÙª)HŒ)SGd`LÖlq^HHõ¨W,ÍTÕª?hÞÐ@ â`‚72P{Ø×]Lfæj¤ œÉ¡æ 4zãÞzXÇ~Löñc¦ýYÿþ+"sVx4¯F‹‚LÇ`c쀹«J`âÎÞÔç”öSz ³iš ®  £¹ÆI–s³B¦ÒlV­®`ì,")EêrG‰ö›}ñBR¤ëOû”™ÑZ#]WsEöØ9EsÔ$TÖƒù´s8Ѭ˜zà ´Í„HÎnDFŒÆ`ñÌÜ õBƒS"ïg^ “x3©e>о(s FÑd ÔSÊ. 6ò)±Ä#¿Á!NLÒ9‹µÒC’ªVÖbnP2::hB‡ãkjÁÀ@ Á ö€l#ð–`;úvàªÖ¤9±©V¤€Cœ˜™áQA€2ªa ÀÁIØWÌyéÐêbNLKrw´7–  Gʱ:bŒ”ˆÞ~,y{˜OHØRÄè"e–ܬîl/Ûêúw™ÑCÚý´g‰þÚšåÇÃ͵,¾Û,sòsZ÷²º\?YõC™æÛ©FÄyšMQë’Cîû5˜TÕÄYy?öÓýÝ=#"‘0ys< 9Ø‘SX– ìÆÑ¥ãœâ¹œ\ßoº¨9&Ƀ¯{µ¥Lã\ëò@uË1öY„šimKêÇB ØI8Hú\Æ‘³3Y5"GŽa ÞPƹPD Vr‰Ö9…Ìâ€7«­UfgNFB¡“D™ëT˜#1$‡Cî5ç(щm8ÍÙ%õévs)¤~Õ­W,qiUU«•}IÚjÕåU‰æ:o¶ÛÃûe¯XxIÓ²™Ð©CÐjAƒÍã¼,%¤N(°óçŸ?Û]ow›qr@¾J›§ûM9½è$‹†€!÷'ç!f×´ß-‡i¾{½»»i‡{`F)ˆAk;’ ­¶¥ê1[œd?užø—Y!|‰*µ¿×JìW|¿•5÷‹¨Ü?ócôkf3sõã>…lNjëÜ_­N­N‹Î¥t¥Y#eá‹Ý-*xQ‡ëþü++d›³?ÿ“§òåìÝõ{¼uÕÒ+ºçAiÕUz¸÷,õìýüÉïþZÿáÙÝ4?ýáÝí‹ýçß|}óú‡›ÍÝôÉ?{o8í5h8 Ñ6¸û|ûÖJGL»l7zûüÙöþ®p“ì$VR¨¡ 0 ¬YV) TŸ¼ýþ«×Ïoo¶ûÙÓ~ÛPYÕ% ª;W¯S6̆ˆŽ‘«'ãñ¦¶‚°î6’¯òÙÕpñø¬³s¡ía'¥¶Õªç¥»=ì‹z(aáÒÕ&ãM=lÆs'bÅ‘DòbHîd°£Çœàâæ%ÄXØò ß;—ÞïìŽÉ"Åo~û³Ï¾»l7X­±†>Åý÷_|t9<&šž_ÿÕÿ}kOZ>ç­²¾w‰ä¸{úr‹]xþbúö³g÷/–ñüP·ó‹ç?Ü^®Ð·³üû¿õ¿þér,­ø^PsÂi›hœxO.Œè¨Ëv+ UªÁKÅl6Z‚˜q33Ò J¨¦5¸™³¤@3«î’8Y/V6J{ÇDh'fç¨ ?Œ{šÁp2q Ø’¿¬0ó¨°oÁxðHÁ…ëR(gwAÈH&^Õ±EAi³Ömµ}C‹1§U»ê>»Mfü=8p4$Ci:›UDÓ´T[hè=0qÒ ,^'FAÝ*eÍ AbiÖæÅ&'dîææìˆ&‘‚yäÐÐL™ õ°Ø:FëꢵÍTˆ2<—dfÑ;¡z&ž›2“¬ÜZ™nFÛhÛ6€jP˜I@BÌiÝŸbÅi¹SXŠ-A%¶l×3À’… µU xÄ&)“²и)¦yñLêm^רÃBÀ™"S¶â¨Œ‰Qá=aå|Ρ§Ü¥X¹îSÀÊnò[•.Öu8U„\Ì BÇDN£öå¯X_fBëƒdît´.Õàf*_„î”×ïÒ£÷ž~û{7ÀuÆ×Ïñv€¸,µ·ýnWãþÞ§õÚ¯f¹_½º±¸GÙ¡¼ÄÕ£ôÝ¿š7ŒyƒóÊ£þ€ž¼-ìDîfV\ûQ6Ç~Œfƒ¡?Aÿä”Öú²ÛN_|Q^ÎX/(·…wo1Ø iÅ™¼¡6„Uh9˜Á‘`n„FÖì¬j^éh£ srTðd<;ÍàÒTN¶”òàŒÑ€êPWBv:ÚˆŠ’;fP*Þàp°AÀþàÁѬ~IýˆÜõP#Ùïø›LçŸCý’n§&âÔf÷hXEh$ìf¶XkêÂàînggºÄ8!/´€ˆ•ê¨oa²² ˜µHÒ…ÀÄ,˜j!(œÄ™5K"1°TT€®pk`ì,VyUŒšô‡&QµÂ§@3ܑ̄€ ~B8!:#B”=ø`4GÛOl¡ihXÈœˆ˜‰`1uÑO lf¯DÔgX  Q‰Pcr&æ@, Â˜Ü3‡Ž9{H‚0¼X-†æ0‚³“ˆŽ*}g©šCߤÉîb†ÚTÈ@Fânvds¸7#sWwUkäþÀÜc#H„#Ìlس±T…’ ˜Ž‰™•äq¤¢ôâÇÜP`~ð Ø æ&ì`€ÚC›ä˜ íê?^mÜ ÌçàišÜ“Ä£««"Ç9‹t€˜'ë/(v,âÁC²H·Š/‡ äžN.V'çgD¾Ýn·ÛY©©6ƒJH$q!I KX8rà” 3ˆ„A±Y«µ¤.jÁ~Þ?>ïRÍÝJ+u©ºˆŽœR—û”º¬Üæ©”ZVfÖCî¢K“È«BêínãÖ¸xè(…$!^Ì]}™–™™‚ 7XmÕËÜïç-vµµBX‡›Èfg°t"Æ¢^§yÚ¾$]¤ábèÎN‡©¼’È]Z¬»²+]^ ýILÃÍýîÕëíõÍn{_vx8J`…»)Üëƒý’Ž$;†S9ùOH&þKÑBô¦úÕ‹±Ù^‰èˆ£„¹ÚjySª#e s÷L]Š=o¥÷¦½Ûà·_Œ¯þågõÏó ÛþÙ+~Öºý²¹­ûçgªh–éÐùýžùÀ}‹¼FîI?|xqòé µ]­S>?[¶eÞÝï_à‡´ÊÓÏ¿Øn»iûòpóv‹{Ô®ÇqCó}®­8¬‡eÞÖ¥€“i±ÃXœ’ ±“]_ß\_o7wˆ‹žëéÐçÔ_óX;šI Ì«éØrÎxh7Ûò´Ù–{ûáí«×wèNèëW_ µ-{Üîn¿÷ù³ë/v¼§ýÒ½ùן|°[X*"ÅU<ñó2îöÛƒ!2wËbÄŽÍŽ©.b…#Z"Ûªã™1œãw¯˜·w‡u>Ó±û£ý­Ïþ>¡NLÙÝA–‰¾vñîo}ðΪßLÛ/¶/vWOû¿ñäíßõÃÛ?¸þßÿå¿ûWÿËŸß||7<¾xæìn–ÉÎdza{9¾šíû[ºVÇé­—´ùàf÷ì‹ë¿¸{ZÒÇ_ÿƒÿú¿]宯“ý<ò0Ç¡âqœ…ê&äѽ”jTIŠÀÈÜks%RvL pr͹açuRéÅ+ ËÊ«Í&ލ¹°™;ImŠÈ}aBulª¢,8p¹tÍN“‡Þ©òú¢SU(‹qQS_Ü‹ãÎUÕ+ab*1hyq[Ô&³‘p€m {Ç¢HFkJ$±K­rá•AŠœöÄ8§À°Pƒp˜6;”kBncœwuÚ7[$‰˜¹àÇj8î×'ë¹Î)IC«Uü@zïÍíìñU#'b¨ªÕÖJ+:uCÏÂ¥€X©Öy\¦W[,Üi™[4Î\äp?“E%!÷jÕ¥2±Hr“@,Æp²äÁ Ás QCÈ ©¥eQ`¤HœóÉéiÎÓùP‹Ö¥JZ[eß3FCe¤ˆ“€Áií’9å'v³ V›ï'lë³gÝ"p.#xöÍ<Á¿ÅÜÏLŠü„îGAÔ jbfìêØ7Û¦ìÊÚå1¯ã­÷–—ÏÊ‚Í ††”'¶ýùp†·.®v—»“i¢úÞ7N»6á4¼øwÛýÞåÓó8–âKÀèëí¶Ìw“Ï­ÚÝí8ÔlKìBÄÝ´6» |~׺üþ£Ý4Õ&´„u)O ‹ð6^îòŒ¼‚€R·Z¥eÂ<1|.¨:ƒY#Ôª¶Æ¾”VÔqÌõ4CŸQYm6š]«ÃÜì(3’#ÝYHR½Uïä¹Ušx# CèÁ ó±É?€¨ªÁýD¶.½\ü$:‹~¢.ý•ýbÿI/&Á|6Dö`^ƒp☑J«f­¶ÅQ…\Ñèf¾¿ŸYcÇœ$$Õz;ߢÆM£-0()uDÙ ÍÓ1@+löª%µäЈ˜‘'JÓä °3“ˆH’àM[ó¦MȈE8w/™¯ˆ¯œØ ¢N]äD0ëQZ1'3WÀ˜%Õ“à]D)M†Y©fm®Gne&’°UÖæfvv;™³@œ3Çs6¸ [ 3ÈàŽ2É@îªU,°êVª@áF¦ƒ¤ÄŠ£âÚ@MàBnÞÈ•àBÇx"Ž”} &#(Ä)%%s,€¸¶H” +!ÍÌ`©z¡„ͽº+ÌÙÝŽõ„ˆŽº<燚€«=øÆ‰äØš<ž¨8Ò0àqïç+>ɲf …á!ÒPJk®F¿8¡õõ¶ ô½D?U½aþþèS~ S8B­Íªµº¿Ÿžýàå´ß_\®ÝJO.ž,Ó„H¥,:×õÙY]ti‹u©ónv¢ÕIŸRbÆRçiÙ—RsŸS"jÚœ,ÅÔŸdŽâ³Í‡²;|Æ -Í[9[¨žeŒiò:§Ž›©smhG‘&A{`øXnç!à `"$Ü­¶V—Zkc&ïûîòê|]ºÛÛÛRìvsCDp&ö…"¥Ø…$î$I˜Ã ¯»^çe¬E9rY–.D ÑYCâá´#Á8ëêŒ nT—v¨^œiVëÓÕ°:­mZÊ¡.ó1P€Z¦X9& ÔwëœsˆT긛w÷ûûÌ©MRœµ¨±iКªÎ«u„D‚Óžž\œõIæa%ƒäõIÞ߯Zu·9Õë»Ãó—÷÷›¶LЂˆÃS‡‹i†Xd96j©?šú¥ÍRþs{þ—5›ú™¯ÿ$¶ñ—šýÜŸÎtd° 5:FÁšé|½ZÅÜÅÔÇ´êú.ÄCÇËáLÇ™Ïp¿/ÿ׿ú«MB[Ag 9!–/øóü Wœ®/¿vZó¦Ü(WäŒ,S7´L|ا[yB5 L˜^áûµüàéµ%„†´M0(Û٬˰¬ÞéOߺ“ls»¿Þî^[$˜òLM§Ñ˜ši3Ûn·‡| šb»Wæ~-œ¯¹Ë¨¤¥K IDATʪ5O±Û…èÏ´ÛÏ/ŸÚ2C·¼Í¹ÝS8]ï®O__ñz'†««ÓUw…7ûíÕåú<œ¦ñ‹ÝÍÝ<éß»xg·yÍ!«õŽjhÕ\ƒDb†U8’™r{ŠÕëç§'9ynçC÷ÖëÏõÿ›/+¸»ÖÖÆ2z¥3I|=NñÙÕú?øõ'¿ÿxýöp¯ßyûêý‹¯|ög·ÿö›ßûûç'oÏøøìÿ%îÍž,Ù²3¯o­µ÷v÷3EDNw¨º5H¥ ©mˆA·Æ†ñƇñð†ð &h Ì ÛZ-!!U©êV•nÞ"#âŒî¾‡µyk.SIU(Â2;‘yüßkø¾ß÷Õ~ãõ·>Ûøµ6rü:ë­M·ýÍÿî¿ýëßý£íïÿGß>yñ{7¿½¥twûÙé|›ú©Á}q­‚™œàFÎh¡{0iùDsÀHœ]µ–fÕØáj®ÆÌ®êì`Á,ÔÀG„^£¡¡xQ¯ffÚà@×+9©JL¡5m>6T :ζ3‰»l¸çA¡uQV®c«cÃC3%HB¢ª­èeœ¶ÝzFiÖȆ\Z™*ÛYË*s²Õ¶ÓŽfFØR^ ­‰‘‘7jb‹ÄTÜÜæ)—ɵÈ,õ줱 ÉÚbœ€@3Æqr´<¶(`¦¼ÏF†Ý, Z[¹h§îªë‡Ø27(;ô”±ŸBØ$ ’b[i…šB™9VÃ’BL)beÕ ZíL´N¢ Yd).fãI‹újÏæ(\§Z'CvÀ`»í.„•Ï]9ñ0ÛV‚%Zõ:YLë¡Ûõ²‚ Uë$Î6µ<Ö|œéÁý~\oƒySó:G¤ÈéQ-G?i,6ýåå.øO¶WÎJú0O"©Sõ;mб;Ï8ÿé/ž^=í¢ÀžâäuëÝîy½¼\ ^¾]}c}õ¬?…ަ®ÞÖó«Óùa¬wÉzÛ©¸¡÷cÛRó±^Ö¬ëýºsØæ”ãŒ=RO¹ÕÏç#8´ÜäåŒíŒaJ~BÛã:A%¬BXwìêY Âh&f­¸Âà âŽ<ñT›120à’`fÄTÕ'`rÌîͬ  D„n¼²Š:9™“+±R€ôè®±zŽõ¶ïûþršO·ó´G;ŬÔå2ò£s…>ñ?ñËWè‡ú¡üõwßýâC?ya“,À ƒ˜  ¢M1–ÔÒЦŠoh³‹bLÛZks­hO:’y£Â¬-î•À©5w/^ê4\‡k¡C ”\©™oz©fÕg’¬1V+Z/¬SB‰¦B]¤(¼fÞ9_ƒ„¹ð³ Ä1ØXm2WUmdF ž8au så¹ã.# xS¨Z!r"I02v¶@ó¹V5[ì–`r2Ä›“ÒòŒ…Fª÷àb"ekŽ6@M³Zu+ÆU¼9šxX\AK+5#˜»29-qQn #¸0w¢XÏŃDùÑÿÃK.-%òžÐƒ8,„bàª>Õ2Õ6{1 ƒÈÔŒŒ„„ˆ@F‹éq„l 7o!"ø¢c'& ,‚aÅO6íyO›Þ×pލÄIb:ù)[®¦¿pGô3ç<ôƒÄ´÷…-¤܉ €´¢w—Ëùòêsl®°{²Ú®¶WÛ+õö¼÷ qMUФµê—ºÂZk¹L§óù<"%ÄžcÏPçjFÍ ËJ™ÍÔ«Q½¾¾v£2×B3ƒÒVë¾ß íB×u¬çé0åœËA—‚ébìàÁ”˜CŒtóä*ç±ÖÆÌ1F6›5‹}X­úÃv·~ñâ™»v«xÚŸö÷#BÔ¥®ëc…ƒ3¦ivr'ãÀ}’(Ï… ®ešO¥Ž±N}ç%ôëÔ¡huj¹Žy²Ò0Œ§Ù6ÝÌ".d1…m¿Þ(—ÉÞjñ~Xu«a½éÏÓþx¹¿œPr¹Ü%@Ð RæRÇ™[.â~½BܰíÒ:pËgîj)g"j-7-‡Ã8‡©ðí}»?` CÍmÙ «:ð}c€yY AäÇ-f勵ZæÛ?êúWg(zÜÑ?èÿõ¸)r˜5fA–ܸÈ<0oåËx<ÏGˆlwZòx²ÃéÁiÊeDçJ¨O ™¦.Åßù¿ôµÿ¸Óx[Î÷~[_þo§‡o®»«w§Cúª_8W¥snõá||}Ù¾˜}u|qó4^ÂúY\m‘[1°çÕþlÚQ'­_==8°Ý}§ÉvÏåú#v í6»o©¢ŽqtjBæž=³V´\çRjŒÒM:zpƒÕ–IÚ&ûÓô!õ m‚–¼³?ǹ_íöõ;ï­¬ëÎ7ؾùÖí7¿õnOxW€†ßz’¾þë¿öìƒO„Âgßü6u>g›¥çAV<Åz*lÂTá&BkÚ´EˆQ³©0$DKP-—Уœ'¿Øžé´þ×ÿÇŸ½ý60!¶'mì‚údZ;éËݹ†¯|õÉïÿóÿÑõþúݽ¾ž<Üßå'ÃÕ'_û'¿ý{q~{8Nó|<[}ªÃÕ¸Ù¿òþmüðæ“.ÿö—ûÎýÑöÅ﮾üîˆÛ4Û;µýúƒoÔÛâ%©™²Q ~”k÷-j? B‰\Ü ò‹ˆ£:5°Ò1TóÞSL¹ ]B“Xµ5¨Bg8À±yƒ‚L‘ƒ“H§¥0´ݨõí¸ŸšVˆBã5ªckÅÌÈÞ¬F ìb“—9›A¶\γŽk’)Æì(\Ôp¼Œ a£«ëMˆª&° îbÍj-µŠ,gUe«f u2f dæÄ”[# !ÄØE Þúêý“Mãë¾ µm-m;2”cö€Ó«%„EHÕsÎ6eä:cÜ­[)êµVÊû ölûjóò¶7iÎdÑ©5²)Û¬À< —ÕÜ.ÓyÌ|Ò:uë¦Ð{ˆD$µy©uTË)áÀþÀzB-ïcM#.cJµ€2…ѹ°Z6-v B" ‡› U Û°mh5zçð(#¬ê‡b—±Q³ÁS×\Éæà•¼°‹ ï@=0€’8„*SaŸ³ysÕ† ËB7w¼‰¶Rô”ð¸c^ŒÆª Êîà%—ÙjõÖ–gl Ÿž8rBÎA‚°E.¢¤¹µ¬Y`a&pqSo†…©]½ÎJ3Q†T!5wb”\Aê^ݪY1o #CÉM& ĉE4ÁyGˆ;!0ñ2ÔXªH8y‚ e«¡¨_Ê4–¹xs,ÑW€»B—Õ</†"ÃÒ—»›™Óò ïÁïd0ô>‰PêéºÃMg[XHàÜvñ^vŸGšÿ;¢åñíÇ—¤?½pµÇ€HéàÕ­æ¥À¹Žwo/Ç»¼¹^£¿úô%ñ%6Ð&m žçB°)×ñŒÖ°ÙÐÕÕMß÷-—êS©¹¶8P¢ÄÐw¡ïcŠQ×]^¥à²îW)%Wo˜bìˆhš¦ãé2M3YEpL"1tÌÁjk^IÄ% ¬4¤Ø¯»ûU¦q¸œOÝÐ1£YË(B³—‹O»çƒ+ˆ(v©ë:b®µ–R n^ZsU ]’b'Gpu®ºÚ€:Ãì»~»Þ­_¤U+˜Ôép:ÝíOEë”§*æ¥Zq1äÕ†®e›¶‘Óë›qʱKýºïà Z›Ûôd:–©œEdèV}YØàúÕ‹Žtœsió\.ªÅæ>x1]½í?itôª?½\ñ%}Ü=ëÒyswœæã¨·ãå0íëøÁƆ§ÖÞ¼òSÄÁºáÜŒK ÀjÂá´vG=YåRÖ»mzÆ«Áº›lË&‘mØíâ6Z¬§Ë…á '‰9T‹ÖŠ ­3„ÐCGµï¸ÃT÷Ü[B%4jcÎãC.–_(t12K:gLØ„zz½¿új"*«„Í|ôµçÏ¿q½}ÒS£«CϤ•ˆfâf‘È ÷•‚Áœ<°mðJÂÍjsq"%(-UH¢¨¸ÿÔU‡þzsw[ÿ×ÿá‚]’X¢{ É…"õéºÛ~ãùo>íe%v®6&¯ŽÇ3ãêÃ^_|ÿ/Þ|ëÏ>½¹¯óÜ=6ýÕåþ˜ï‰såS[™}éÉÎ:ÿþè·žÿ^8=ÿìŸÿÝóóO>H=s›åô½ˆO¬™ª> ý\@€b|Ld\îÝ´Ä,kµ±²Ã͘8„@æX(4U¥©J™ª“iïjÖÌš/ðØÇ À€šÝMÉœÌHÝ•EI< àIZmó})}µ^Ô@äÝà±ÄgLjè]=UÌy$2˪¹AíáöcFáL«®õ~έâxiÆþœØ”BâØõ;7ц26›Õ+|ͬÇÄÑÂfQTSk(DˆPäÐ%êzñ¾…ÎúçÏÖëx™Îc=¯Ö]±9Ÿ'#ï“¥qC‹ ¦‚bÅÎÓµ”R …ÎÀ>ã˜[S³ÜÄȤ5óâdb0îÕfZ-J ¨RŽª‡Â§bÇ3´Ñ¥X‰G«}C Íu:#ŽlŽ–"( ’yÚu¢mž\õO¯´ø*í’õâe²B­´ÜZ/åøýÏq̸S|÷¯‹WÕŒ˜ÎCÇŒÄlX€ïç¤?'Sèb)yÌeýA£EE[­`Ed$ÛÞ*þªà7B¬êŸ=<<gÀðö«~çãæû.þ½¿¹[‡UÝŽ«³WçׇJó´™Çàa:žmï>5ô¾Ž2ŸO&D‚î0*›ŠÐ‡Â/¶ýG<Û_é›Îrñ²­§þ™\¯žnãÅï¦ñ¤—ý„Ð`Ç1w¼/¹TÀb¤4SðB Y§KCeÄØº«võôÊ\õXËmBóbU5ûfXWÓÂV`Å­¹-}Ébo Ø=z3TBA?ÈÓ›ç}øÉÓž¶ÖN©Àï[™ZApÄ;Ne¼-î o ÏÂù\ï7Cdµ/DuxL†¡GÁüßé²Ó÷¸?¤Í{шpfñ•ÖjÑjh¬¬Oîµ¢Á ê¤j“Blî›yl÷º?Úxò©z B‘9(¹ YSÒ(!‘ˆŒÕ¡€£U´ÉfÖÅ0 \ª¶ivÓR +'R"oÚØk`Ò0I˜™3ID«Ó¬8Wœ«NEs¶ª®–µ /ê9rõP x‚8ÄrµÌ¾b×ÖÈ©ThE%2ò‹¹Í(YŠ¢)jc#1#v×JŒÀÜ…®ë{©ÔúrªZš“ˆ€bZŒIÐ j¡Ì>ŠŸ=q`b÷\ pËŠ¬>5½¨Q*yq4‚² ;{"[±n‰«ì`#QÀÕLÙÑ ä r©ûƒòÄw£¾Û±èPâNáL&f¬Np¡.èš\¨†@VÑ5E34'µeD‚@΀9 .Îfâ%’ .@×àëÎÖÑWQûŸÙµ¦ÇöÏh™”À€1Q–Ecî¨ ^¢Û`yž[Sü«ÿó[›«¾Ne;|ÈYÏ¥ä\k)åKŸ|y

|ÒJnÖæzž¼¶ÐÅù|9ŸGñtÙ—MØ\j>_ŠÇ©H1®ëíJb7¢ŒPºdKßyõn½^{}’/yÕª\ö¸}5žOÀžM>aš&rPÛ077,F×j„Trº£?ï|³¿çëíW¶¢ùéCÊúkçý¼lYÑÚi¿h–èÌAÂû¢%ñáñ!V¸Ùâ1zÌ¡~ĽËY|{伨f™2wצ̉BÃnƒÒ$·Ë:lÎóeö1lWr³ !}çííó¯|²ùàé¿ù‹?>¼y˜¦ÿçáö“¯ÿÚwg|ï¢ý®½Žü_|ø¥>ŒŸæn:²Ú¦?ø¯þàùü_îç¿y[¾ÿé»áÅLJª·Çy÷üYx'úo¦§¿þls½: 4¼ÓËÛiÿt½ê'mÙ §èí2{Óa¼¹º °Ëå¾ ‡~»:Åœ¶ëšùx·÷nUºùØåUHTÕJîœj-¥ZJˆ+nˆXÔ¬RIHBái´Ò±šažËج¨6ËórGÔÞ£í%іέòfxu?å€ÕBØ}=”ç¾è¾/ß?›oø™ô»é®”Û¸>ŸÏšÒdÚÌÔ[Ë3ÃSGDfÀèMˆB—R×õë.õ«e¢p8îÇþÇÿæ/þÉüÞÍSûÿòÓù»›bxp=_Z&k=pÎé;Ç—ÃõÓdñ_ÿÏßÿR?<ÿÏ?iOÚƒRÙ‡—ùrüîmy{ÿâk/jåCúÊê7¿ûöù)>-O~ý:]yüx¿~|ýb´/-„Ê]ï×/ëžâ(¹pS¥“¡BLr]|dçsI8¸»Öêî‘cŒÚÌêt±ZAc§JÚܪò‚ßÍ9¿OÐÒ<ÏAܬ¹©’1&.5ƒ`¤ÆÆb!“™ÒˆâíäÔy=lV=4zCÉ–úدW""¥ä©úh4óÁæF9PÒjì=S`ndBœÚ´Æ NÇ¿½Ä]Hë+’ÀaÕ×fâ´Æ s›.35¨ó)Ôs³bUb´ ri%Ïh!‚úÚÕ¤a±|D¾.µ\ÔrÙ_–‘KÍS%êûõjØ­=yÊŸÉUz6·qºA; ×t nèÝœƒ¤» xmµ Ú4}ûÍ6ít<Ü·S§©žs}yDm1H—˜¼ÔZ:z/¶Nˆ¡hU½8É!œ“VñÔ²äðÉPaÕ›w¼Þ>½4Ëâ²æh\/SÝía 'ð;²WÕ÷ÑFÅaòÑKN!¤^‹NûTÌ@¥ ÿ¡JXñ#Fÿ,~Þ¢É3ª#ÛÇ`X “êËêüùhÿÎvûâ§­¶ùËøæªýËküñ¿¼Â÷þ§é?ýô÷þë?Þ¿˜Ïèæ?ùäîö;Oÿ _?çWŸ¾ý°¾±êGÎaÀwòøäKÛ5N|Än…C7ÔçÏÏ8õãqgú4Ú»ó·?¿Ôn·þýÍWæïœ1úaÞ_^È©Ÿ_ÎÊ)âEÀ×Û—SÅ‘nvw÷§Í˨C™µ$ÓÕòo2.ϱúÉO¼ëÖ|Ÿæ¿¹÷—j\áª%±À÷ç»KžÝ¨™5‚ŠA"p+VÂ+ n­U=-p!uZûußž_òþåíçŸ>žòå~¢#††¤!šD«Èv;Ì5ß%$¸`n¨ ‚÷… p2Y€öøñqtî?DHïçDï\¾l™øq×ä9Ôáä ÑÈ$!CzÔé8×Za¦nÙÕ^[˳–I÷zÜù݃lvA«ë¤b —ìb“z."ACbHj›w‡GPO=‹Ä>Lçr©§‚+µUåÔK4¦¸¾Ùgƒ®ú´ÕRϸïÐ3ljå4ί{Y­ú„ݹáíÜ^æz[ìÜh2ÎLVl’ÁJl@[ ˜¼Nõ?t‘‘¸iÚˆì;Ç9ÅÍçó|7ÙI1fÒ“žJ¯$Mí4ë$NL;¡Cèiµ¢-ùJƒ´kAêlŸ÷¦Ea ŽF¡1Wõåhìᆥ§DäTêï “)\ͪUõ¬ÈçùȰHD$ˆdÑ[Çx ݱ!Ì ?£µ–ÊF«ŸI8»?4j–îÎúù¡¼:Ø}“c–ZWÜ’5Ñ&:14`½Á‹kú„¼_¡›}Fo÷íîäîÛi>÷©Ó) ¬¢Ú4òs¹í(H$V‚„]"ih7è~´îgvD"ü Ur?‘€éËSÇ Æ/ï¦p%Õê¦nE ¥Ž%4H´!¥õvõüúY)íp:ÞηiHì9Ýj†júöõ»Ãñ¾‹“‡±;¹“ØÉ‹‘s ÌÌ­µ¢ 0 Þm¥×n—/Ô9GÑ·aóáfu9Oç:vê=€Š­6w‡wHÆîÊuÔ‰* ¢÷ëÄ£Rh¨Í]ƒy´õ°JÖuÊ^Óa¬S"¹ÞíÛnz g¶ËxóÙR\mûm ÐZ ½¨·1UÛiœž={&‘UuÑM®†!…®Û0]ûœ/]íH÷y¬MÛ-îjÍÇËq¬S· ý&¬ãND„‚»¯‡M‡>I(¡„ú¾“~Ø\ }ŸÌ ©ãÞW½uÉ{–¸¿ß窦S9¬f±¦P'8ÿ`1Hª„?MþËR»ýªZÖÏ«þ”M,Ë’”wW¸ÌýG·Fÿ€Ý—ÿÐ T¾ØGùÎ'°ÿ [yiÎØÙ—¿;A°ÀâiA‰`®Zc]‘Dud‰Wõæª]ž]#…ÒºŽw‡<ž?|þÄc,§jÕ‘Ó8‡1l#ɺÎ8)½Ë绲¿{»ÿÖ·5ìPåR§¼óå¹œÞæW¯Îõå¥yŽ7ã¤ÃÍÕ¦_ó¡ç)ìHVXqlíàÇã­œ‡{íkš¯RVÔVE&"Ч¸6”sn5‰[+”ìR`Ыµß¬obŽõ¨÷‡}¼@0•Ò4õf ZI‚g2w37†96×iç'ìn°»I×uÛÍz 燨ÞÅ ƒÛVÂÅQ¦RÎóÜBl„æffîJîN掩ڢ& °@ÞÈS³È’O¥kQ{û­éOþæß†.¨ƒ't o ØÐ….IªVKÇE6Ç3èS?ÿi~x‘çþùôÍiw²oÖÞ;w[}öŒŸÝ¬ÂeÕNáXÛmT¬úÕͳUx¾z9ŽWçÜ_f’UŠ«'›ð¥Ë\Áx]r!–…6äêeŽæÎÍ Îê–™!¸{­P\M‰úEïP,B ³Æ 6cs3¹“±“0ù’qþ(ûwLç „CulÜ '^²‰¸g²Èlè¸^´‰µ¦V,Qäâ­²+–õ–W·æ^ÜŒ|)Æ| …[’rËÄNîΨ"%r ¸›»# OŠÆ‘r²K$5 ‰¡ÊeÈjeB%EŠœ¨²s¶¦îÄL ´¡)´…ˆ+{ƒS˜PJ@²Z# f©Qg%bŽa8ÙRR€I‹ÞDˆê<ø*)±V‰»–/vš/å‚©`—üª£m/›äîta»8$3qŽä±fG6J+—kÈ*† $z˜[ƒ«–‚K–smo/rB¸5¿S]'&5G°Êâ1í¬5rÈÒ9€Àaï§f¿dóOÞ7yñý;Ü À¢‰ýhí;—y›ßnÎo/¾¶ûíÿòk«ßÙøç7ßÖËŸüåñO >¾¿þÃÝÑOœ?Ùà·>dªåk/ºy*iç)?Ù 3Ý)Þàú&Ôuw4 ¬7‘®¨¨Nw¦z:¤Ë·ß¼xXQ‘Òb¾`,G4ŽXÕ\@ÇuÀ:UÞ6Dµ48WSƒ%„„ô ×_»±ë.v}Z·Ÿô~ªã\kÖÑêqœU=0"=ΛÉuÌ`ˆ( )Ãt£ÇXÐÊTîÞž.ÕUhœçiš´¨ÍàŠÁ%pL#i 1†ž¼·í’a ƒû|Nö+ù£ÅˆÁï邯Qü“óP÷/d [–KuøHËX„i-y4¾dmBÁdŽ¢ ÿM˜,¯:›6jÁ½’72u¯Èº,­NfdÆVs› HD`hYNM‡{ 3¸ƒ: ÁÔ5[]…A:ªÍ2¦ÑÐ4O-lÖÛ·1ö‘Ykb’‚1`Z÷]³=¢ÎÈEOUß6Û¨Ù%ãm¶ÏZ{hZ ËŒ³t ÌDA/¼&gÂHäÔ/¤ óÖLÕ)@‚€½V¹® ¹an®‚•·±¨{ˆ`¦æõ˜ÏV»fÉP{-h(4»4½ˆÛbL3;“­Âk‡R‘í80z}§~1‡¸ÃLÕ›y†–ÀAº€Ž½ƒ]5¾L IDATã‘QxÙÒüL™‚OJµ9eÏõOúæâÇ™Z#WwWr(E§ú®wáéοófÃa²cãZE Z¤DVYw«`)hXQ”U½¸ÕI§1q#R‘Xuc‰bÂÏîˆìœmÿìÊï‡9ÝòÅ]Ìr©šª6-Ó<†¿~ÖÇ.¤8¬¶ëgÏ^mfíRÆ<âÐ7ÕÂz½±yž¦K)UˆSêR\Ǫi­ÕMÝu¼hA$yãy¬ãœÛhêrýt†þæÙÓa«squEh›Íºy=¤åÙ“›gOŸÓ<Ë\k±uCr-j9Ü™KRÚ„CD­Õ¼ÌsÕU’5‡bªÕwC·ŽÃz½½ÞÝ‘t‚(i³Š«8µ}K!Æ(ýz`ÁªôFÞÅ´Ö±Kã8Î'ÎÚIØ­‡n×¥ªípFÛ5kµ–Sm­¡(+Ä8QÜtë°“ ¡v_έÌMçÚPòÔ+'N jEUˆ»Ø¯hÅUæÓ<Çýþx:Oó"˜r)¦ ƒÂp3»úböówýü²:¢_´Sú¥tVl`bv8“9–ì]„»ü*ýQ‹qpy0&ý\™¹1…ˆÝSt÷1õ‚àđ٠s­­0sžçäòöÍ»Ož¾øÚÓß½{7›a4:+ábs͈ÀÔSٜ߹¹¸›*Nn´â(ëaµzZKbNëa¨¦¡àZ¶ë)=½~úé›7·÷õXEu´ñä >9ÖîÞ‚Qt%Nó¡N¯Jœã|(zi㛹Üy}uÆ]õu’VeÚ¿ºÄ—6S¨ix}Å÷²­›õzóäɇÙuc·í-îDÇÍŽ>ÜvÛ­lÃzón¸LöÑ“·°Ü½Íû‡´ûøIüàcšŸMÇ9\±¡¼/fÄ–ì7ÓV‰‚‚ ®îÄ Xk#‹2Ä Þnà ×êKž9ÙcGôèu×Ç&щ us#0 _Œ 'rg‡ œ›“º³*G0•Üɵ¶š ½¿«WC]~EkÚ´8ª!<À˜#«Nꑃ5¸ikfÅZÑPœ;/µÈ@pµj^•Yg3CI#+”Ña¦Õ[s`ФBn5ûÔ÷ ”]j#Ï@õeæîR­Ôìdmn¨ %duL[…7Dnj`-‘Å%YȈpr¯^ƒev!¶^`Y"mÝ=gÕª€‘ID`æ~6}0;_ÅÜÕ\aæ½æw6Bß!°›9B5Í…šù¬z©÷#^òÑÛè¡ÒQ%CLœ¤T4R5{ô7ÿãÚ/ÍÆ‹ŸàéwÐwë~}›¿úáu¿#1vóâŸþ³?ü·«ÿýÿš_ýγç_ùݯÜÿÉß|ÿ¿ÿóO^ß|ùçýÃWˆO®0—íóxw—__[†Ë‚±€ž¢&¼»Åae¹´ùÕ±|ìäé_õØ}Ðõ$Ÿ½~Ó9ff/Ók“Û}D!×S 40lFÜ»ÌS¨ôÔÖײT˜Z¡ÚEt»í—o~­=éŠÙîljn÷л™¦Ù !Ê8{$„$䜸qÑæm¹ù3šYVwCV›Õ‰¼˜N†Öò)çbï%ŽþؼVW²ª0A³>ÄHi»Ù¤5µ|º½Ï3‚ Vðc‚ãxÑæ oišè'_“Á ¤K¶´`í}·ôQfuàæÆfá©” =k­ÞÔ¡…½j«ÀÒ““)´’*#· &&873¬-oHA ¤°Š–[eîáÏÈɹÁ݃”k‰×}zÁC§BæxÓ )¦ª%0Sµâ|ÏÔª»Ï(~,vçvZºGq^:ùà1R Ô÷PÀE³ó‰ÌrkÁÎÌ$J¬¦ßÀbÄVP ¦í>é#v«6åÜ£VäŠ ZyÅXì\mŒLÆEÐâÿö¦PFˆ à&¤î@[ØÎÄDL€¸»33÷DΘ{Çè`Ѩjü®‚ÄÔ ðºRƒÔdZÜ2uVÇCõù⧃viûc žAê0´€ÐqXQØhº’›«x½õëÞ‰žæ¹ˆWDBWØÝ„AW1²‡(€QjVr£f倇êád`hÃåœs›~!ÕÐÏ©äDèçÍ»—¦ˆxØ/·,fvgªbž–Zìsê°ÚŒÝúVDÎ÷çñdÔ¶OvÝ0LóyO!RÍÀÕfãî}·ú­ˆ´yjµU ùœ»žÉÜÐΧ{9<>ûö÷êä"ÒËêz“Üê|®¹Œ ìëœS'Í›“yÓ·¸íûþp8¼ysÛ†$«Õj¸J7Ÿ\¥éB¡4ófóaæàïʹB¥ÖO÷7{€óXi<×6éùlÙ #†9§>Ìc6³–Í­ùXs>ÖÃÛýaßÜq:#g0AØLáö“>}{$kÿìŽâ—u2þ¢¯7³_ÎÏÿÔÕ‘;ò?V|®ðfºÜÓ¿=ÿ*‚ê¾x¾¸ôŒçää¥/” ËÌÍ\—OX@Bfî ëÕБtB똆®ŸÎ§ïb¼~r#.óátü`uýb¸™Î·!‰Û©²\ÆÉz¼ùþùûµ_Sw½y!X?Ü¿{øÖ»Û7Ó¦ì6»›”Rž&•àãéD ÍöÙ‹áæ|œâ…VÆ_}z= +Î6NÓ8—rÆÙg€Q<Z÷]Úôý¦;].ã+•=£èhz&iU"§UTB««”úÔ©Ñ: ýõõm¾ïž§Õs¡Nçy²XÑs‡­E‹Cèc—¼ç‹NY‹šs̬L078¨ÑÇ£”O˜m>äËí¹„ˆþö¯¿»>nxN3·ÉæìZÉULÅM›š©©™-ï…%Œ-Fffbf3/ß4ÓÃþ䆦àˆÕ:ÅÏçñ²Ç³ÄÌÈ`p6rƒÂÚf·é¶„-{hs7¿ÎjÒÕ~{zzÍW¡“ÜU™‚¸ÚŒÆ–Wuû¬û(ïVÐ|ªõ¯ÿòõwîïßL3Ûû»K­Ãý‹_ÿgÿ4&^!x… K+ÃΌ܌ŒÜMîæ ¸×¢ª€€˜„™™¥”‚GÑcf¦)¬Ñc¥Ãp¢…MG¶Œ¦ º0gÝ`‹‹Ö|a킌›B ö¢ ¥bV4WCs˜›Ô±tD З÷å`ps6°s#ÕFÖŠ5èä”j5-¬bEs4Á 0ƒe‚bÑ!ô}šÕkdlà¦ÞÌ´]\Rì„ÍØK¨…QoG¥f¹0©©¢”afY]+¬‚AÄpsX ƒN v)ÔæV©ióÈj(¢-Û|¬r®v!´H©s‹¨‚1‚¥Õæªv!?¦#М )…’ ªï¦Y[K—Av>ñd Ävž‘ Sч &ÜŽ¸@ÀQùD”!-’צĬúøâýGÿ³L¼ÝÉa07ÆRZö«ã|ùÔ§8÷¾Z…z9ÞOýgß¾úÏ>Ú_*r¿ ©f<|òæWxP|ù×€ozí€Ãq…Õà|°=äS­!oÛñO1Æ©Y²À3Çq³ž g>\mžÞ„ëwûåÂŽçf'¥2#®#RRBçÐQJ!™b¨¨ÇÔõ+‹x«^1¾ª÷ß;㣯¿;ë~?Þ•|†g¥¶L¹€@ Õ5ä…(jlF ofª­©æj@i4Àü½WáñHLÔÜažK.…v®onv‚ƒä³¬=¦ä.¢q,§àÏnþði¾(ü1©ƒØ‰€…yéddô¸º^¦“fÀ &:¢>AÈ  hFž¼ÎZ ì…Ì eø·E*Õ\ÔlBYu‚»bS†6@Á"t A«We§@UŽÑూfrW…™=tQÒ¸˜]’t+‹­}±Ñp&¡$….ì̋ԑ"<‘ ´9[ѬTAZÛd^˜EbŠ”ÔØÌÝBR/×[jf¥NP™nÍä„Xç3¬,fE5”"3­˜.æ…-1’;ƒ#±ø"=q›¡ ¶ÜƒÙ£²ƒ‰`f 0s€4bƒ*L]Сköÿ‘÷&?’eÙ™ßwι÷ 6ùC•Ūj’MB«ÙÝ€¨ m-µ×ß§¥6 h£I[¤ªTC2‡ˆÌˆðÁÜÌÞpï´xæ‘Y#”«‹€ƒÂæaö†3|ßïëØÃùd¬‚žâ‰#,á¢`!Qæj2™ï §4õxŒÓàƒQ8çˆÌ >­ÖIÖ;î7¸l¢Ï‘i¹°6ÜSJÈ  ³ˆ@Á2Â)†8  0JŽ)QOp·áPï%!ÿÖŽ(¥ï–4ýUFÀ·²ÙÈ€ÆyùéÎB"BÌ€yœ¡¬¹…0´bzÀ»w·C=R²~•¯¯¶›ÝFcšæ’˜«L‰³05$]PS-æÉÇÁk5¢†Ù”½…ŸNµV$JeÄáqBFßç¦¡ð©½Øî®ov^•(öûC–ƃ¨í²‰’EÎmJœëP†±r³€Éç2!jÛ0ªe‘éqVBnûM·iÅRPÍ*º†û¾—Ì.¾júÜôl䫵ŽÇS™ÅB™Q2_ìv™R¦Ô‘‘cRä4ßÏiÍÓ}©µ“så0]÷Û—7±Õ#5ج6}îÁÔJ›Wù LX¯±Yãb»ÛìvËÎ.8&³i˜oÇÛÓé.†˜Që¢:€« bJfñ¾ zêˆ~—êì÷ÍpûmÇÛo;n¿ëóc§çó™°Eîn¸ý: î»î¬þŸ|ñr¯°o“g[ó“^?b ƒ„iYOЪ6ijšÕªËi¢K|yu1”¹8ÚõEäÜæö£ÝóHoë㾿ټk1ew8%j>ûñðX~öüv³ût´Ú½úû·å'vÿµæ¶[o;“Ç´³þB ¯¢ì'×±+4͹æ$&-¶Ë]ËémŠø‘ÆV_4ÖbŠ¡ÆÜÔwÜ4-ÔO=÷’WíAåñx(þ¸êRzØO°f•׬;¬jjçö2å¦g»3ßÍ7­JxƒœÏ³³,Ù€¥Š…9Â!I“7ýãáÁ N÷óx;ÆÕE×wì|R™]ÅÆZ+‰KßÖZÝ=\×ÇÙ춨µÁs÷ˆ óíºã€™«dÃåæâj‡ãáwµYDŽÂ$ɹ͜ۼZ§]Z¿¤lQë–º5­ž÷7%¦»éÝÛÏoµóͺ}þñõ÷~¸]_–mLYë¯ö?}wûÅ)ýý—·Ÿßí»Õz8<^®®ÿÕ¿½µ§,^£P”sp”" q"¢Æ’Œ´+Î!¨Â’%ç”8"\ë¢õG,ÖµóD8ÈÈu‰» Æ9ß1¾d7? ‚Áˆ³2Ì 4‚ƒÍI@Æ$ðªOz @X„i¾ÜYx‰¥€KÕC‰Kj¡,ç†ÁƒbAE¹š ¹!¦L.îK$aBdG¹…yDdEà ¢x¥¨žƒ&gZ-÷ž„ˆ¤°—ìr÷ªX¢›ÆÊlà  ¨Š‚À¢¬3-30…'P(;98(RÝ!j3 —ˆ½ê˜k#„$Ñ2Ùe‚‰!¤°˜0Q’ìîz2¼Qõ£ÑƒÛVKòH`u”‚Ùi,ØÏØÜ;¦ #áˆÅ+.D #_T£ñß-×Â3Ø4Âá€;à§ûû®§šðùÏ¿þê¿¿½úyúèªýì‹W‡¿;>ÿ1þõMsóؽýê±naõøô„ˈÕôò:½Nª;Þýp¿·YUÙÑs¾¥/_ßñáhwÇÓa4Ñ R¿< üìkN4Ýá‘Q ·3îŒI&Xê9ØäfmSÙbëUužØ³ÓŽ,hœr09IÉz¬ûϦҾuúùÛû‡W?ùâÝO5îÐ9’§psBJ‘ ‘@¥5­/¸-QÄ›•4P#XBbÑ ÃA¶(M—éL/"¤D”8ùaNóTç¦Ï×ÛëݦÎ÷cµÉ0jœC0¿iŠËoé‹Î©Q o1-¦WzzÍÅ_O± ˆ)ˆ(Ή–Ëz®A™5“Q˜¹…¬ÂGè„BPx(/5Šç'Þ²‹^rh|]"fyáE3ƒ”–]1„ÉÀ Ìð) yÌQ²¦Íœ²5ð4©›M¦®I"Å#BP/”RZ3g¯'É|šýDÔ&ÃP3D¨MA5”3¥†»-qH„p²È•R€”Há•RpNLNžLyÙÉ4¹¡ˆpwE´~ÅcûÍ=^•r –F V 9¦³Ñ€ER 2(äVPØZÈU”&B‘‰ƒiYTC…IÙá¦F5¼ÉÑG6c§BÈAâP¢©‘ªjÃ,Ìá˜+j%=Úã£?>ú~ÄhÊ‚–‰[¤MêW”¶$kê{ßHm–ÔX˜a‰~ Iܣ˭ˆX1 Ӏà ðDB]zWŽ‘HB³ÄØ`Eð¨“cZI^åuú®³ùï|É£o]¨Îõ4ð°0b–3æ)[E˜äÕÆ ÷Ç©*etµ¾xYñìæŠ%«šH§j(evÄ\kÃaC XÒ9æjBYÿ7¿nœÁ"a¸ #!Bõ?éèòÂ’s&ðЯvYA°ÅÈÇÀ’#Á$$I¢%jsîšÄLŦRO02órçÈÒzÜeûñŸ}ðƒys'_Lc¯sýæzs{ûÅÃ?à‹‡#ÖÇyByƒ›‘ÖuÇÒ§rU¯¸¾ùþ3‘|õeóÕ?|}üâPßÙË«.Vvz,‡ax|Äóþb•VzÌ‘ÖÑ\öÛËuã´ŸENÄÝŠÕÊ]ÛÌóŒÖgŠIŠwŠ-»jªfF56¹¿º\­®"dfû›¯¹NþÃþát|»ªmÓà®Ì5—c³K¾½}] ÷G!‰ªC;ܾ|öAñ#å9µ8ìK™8§õf§Å„¸é»‡ýqUkL<–R¦a,Z$¾íÁ  nSG‚¤³ªiîs¤ª^U+È™ðâÓŽmî¦c½ýú0O‡M¿_¯òfÒr5¦")o׎ª^µ Óp ÂX°½‰Õv'vR×pEx„•u·ëÚ®§M¿‚{™æÔHßtÜfB*ZNûGt®f±DÙªÉIäb{YƉ¸–t±Úï)pxØ6í‘IË„Ín¿ºZ[Vjs-f–87)]={6î ·Òõ-œË¦åö~?&X:Ýo¿:ÞÁf$ÂÒžžCØ–™ ‚Íã©Ú¦'Qüê~ï¹}þé«Ï_”îßÈKcÒ®`c——;:¼½E›˜±MˆeŸ°>b]6}Yóàûùƒ}ó}Ýþ K)­/¥/éõíñtÔý?NÛÕvµZßìz ?Ý+Þ§Ò<Ðwy{½Ú¼\9PÅX½¾Õ²·þxr^ûþðX7éá2ヴé·ëu^§uûl7ˆ„`)¾I_<¯qæöÔ¬êSÄŸô§ÑûG‡¹Çò?Z6<Äø"eSð2ñ‹ óOÂÏW" ‚ƒCÞwiIȺX·hѲE,uzŇA~fP0˜ æ 7,Á}Kñ`¸€¶ôj‰‘ÍÜC9¡áÅ,svË9™´”3Ip°™95\fCõª´h§àḚ̈@x™´¨O‚|‡ÚÙ̱4Ó¡êN*œ(„œ£ÄØzЉ8‰‹bT(QäP0¹À›ˆpå(Ä£$nìÑI™s0,ÎîÏ¡&"bgL cÄJi‘1W™JÐ`é4 WBáP '„X,Óíú냤øgÐÑyRîLFØG#;Z &4%}/ÿí³|=N]ûðÏž½|¤×wz7 v%Ÿ[¬š´ú7Ï♽¸»×C½NÝØÈ|ä×kº}¾K”>0ÚTß|1Ÿð› ü$•Dê—ÃêËÇæ6Æw]í¤¶iÀÆvÏs·MesœtX_îšdb!©™B&²Ç1RҨͦîQTOŠD¸¨Ø.EV¼¦ÈGÔWñˆJðˆÉBÒìs̉’p.DÅu†Wp!  .ñ•ñqHè,ë%êÓ,°.¸üžn'¿}{×ö.~Ë3ˆ˜¿ÕôøohÈ¿ Œˆó0œB$,Ì &­ç€MF,lZ¤xJ%:¯‘Þ¨¤§:òÌê3’Ô^|˾Ér¢Ì„=&vîåš:ôžê¤ÖФ¾‘^¼ ­ “¥Óp /ˆ r"r5âsYfZÒ¹:3%–¾m,·\0³ˆ¸»–:gq¡N|öRgâ`eÿæH wèó=ÔyUéyʆ¢úx¸¸ž2¤Î WP‚ZAßn6Ý® ô±M¹iDA¼Ûl¶ý&ªÆTïnß Çéêf}óâÙæz7Y¹w—¶½7uªSµ„Üåõj»Ý¬û¦ŸCk!©8‚¸ïûÝn·N>·†Ç‡±Yw—7וˌy,§i®h×iÕoò–£há8žVÝ^½þêt@+U†GX=ûPk€™Üßc`8‰ÈB§³aw¹ŽÒ{ÕüûÜ|·Ûëo÷³}·çÿFUÕÌ}q:óyýÏÌNß ñÿE^òMSv^=ß;ž6Ft&^,› çKꘓú³Í†ºôºœœÊúªï$Gâûááèc×w-o†»Û»ñH7ß«Åê•n¾×òG/õ8þïw?Ž/®®o÷ki®©_õÝ]²f‚ɺýºÇ—2õcfÙ~põìÏÊ—ä>òn½Óã×áQê\=¨ÍRâååµõ&»Ôo²¬Ø¢bÅijæ7:ÖqÐd´æv"gläm¹½Ú^¦›l9\j“x(óýÃëÝz«§Ã›_HNœf‘LŧQÙÚP#õ$"Ma%:ëÛ_­0“03G¿úÏ×—7ysÜüäo¾üôÝtu¾ÌÓ…å66H’€Y%ç¦+3…¿ßÝñ{äF„â}ªáÒîHʰHD<žŽª&DMÓ°€0 ]\^æša"’RC ;YµVñBÖŸDþ°n8ëkþÃ?þü³ÏÇ×Í'ŸüéååÅ0Õñô0îç/ß÷l>¸üþõ•úmsßàÅM~vÓµ¸7í*∠q²p "‡Eã¼ù!_:f@ Ns’”MõÌ¢_âŒØ·E»ô”OâÄÁAóe9g8“€±ht)°H­ ªê® gf aЍpÉ ÛŒájp 0/ƒA}ŠòÃÓã¢{÷ÅfF°PJ^à0[uraáåöƒ$à°y™™3`á6M£ ¡˜j*’z#ÂlÕQðàDD ·DI„$0k%ff +,8/$°€9ÈÂ‰à‚ X@ ÔdÎpR™ŸÁ „E§ £E6>>Bˆ8%6Øìªµ` 0†;BœˆànáœE"3)™I¨ÍÉ©e' ŸÌf¥Ù0¹‘”áË£s€ìpœ3ÿŒvD¿,sæ3æ¬kPÊ1ÐeÔŠ¢˜ÞûŽû‰;i×ÍŻѿ¾þÑö£ÍóËwR›?¾ù£ÿî?k¶Çîoÿ¯·ÿÓÿù½"Í=O??ÂòÍêf<èéûŸÞ}þâ#¬ÿòeã¯Ë}Ä®€ÞÄýaˆû|çCo|ôñÄó`˜—<¡Ï3ϳTê<Í–¤¦õy¥õH9¡K´î.›õOÓép{ Žc ôŽF‰­0ÐH4H³3GŠyÖ¢‰ÔAb4B/˳àÅmêÁa~vî‘d‚Rx„˜¥%)>[‰ãíþ¡mDDÇbµ>IìÎÐ9ß…ðMCü­vèW\ÌÌ̉˜iO!!Y @B0YGŸQsï>:FUÀ9M¨3Í>£*Ì)èœLŠ ®‹”X ° -‘‚4° œ(@,B4ˆÊ\™–@¸›MZÝK f&ª5k85ýÌ"•”S\´ôIO»ËëC‰PÇñ¶àŽséQ VŠê ól‘B%¼PZø5Sx›Ê0¸ÃI@9SÖÄjä͂ÄÔ Œ<àÆ!™Ïb¹ÏݶÛméòv¿:êCñžBb‰5uGb¦\ %y ÂK)ªÅ1, )*f©÷ÉÑ7 ð|Ö/.ª}¶âu ;-)@RÛ–< {ÇóžRa oª£²×ÁÇ!NF…³6ˆÆƒJXßu]Ó:Ó\Ë4MaXs^¥¦ÕÔyn#‰³Ã&šˆöÁH ÊHµÊh^Í&8Jt}Wb>ÁR—›h»Ðf [»»…,LUr&¡”E<5Ê¿ÝGô[}Aß•ýB¿&ò œ— û¬JJÑR4ô]õÊ¢¹KŸ~úE¿¡«ç›ëçë?ýÑ'³Î§qxóî-iݬ֤K^6‰p­µL5 ýš›”ÕUë8ͳš¦Ä9ç:ë<ÛT@‚ÍÍÎU‡û{–H9EĺkÜq: N)sŠ~ÇMÓ9xí»¨ÝÞïÝÐ\´»~;F÷px‡À|Bîpy¹ksÿp÷X¦úú‹ýÕFº¦+aæ±ß߇™KĪmÇ9¥Ô¶í0 %´–9Gûâúf˜‡¯ïÞxDιiš¾ïO‡ãýýÞÏ®R˹Î%…œŽÇgß#ùç_íO·¸Þáêùú0ãëÉR\>ß]\Ý€÷û½Nó÷ŸO1çZk±RMg­¥ºŽÝÉ2nDOš°Ù2¿áûf¬ô«;ûçsCü}t ßÞu¹©µžæIæ¹ëº”€êvŽÒ¯Þâ;2è~wçöž¦p®³/ êÓ €“ Œ–‰á¼jº›õêcJ\ª±®WmÓF×6›U/«ö]™ß½ïæýë¿÷rÿvþ»Ï~ö¯ÿê‡ãmúàß“«ºþhzö“¿~÷,#EË{y~õb¶GÞ¤ö±<ª:ÕàÇ7ó}”×#…§yŠz(ÝÜhÎÌ«Ó|X_^wkÜ}}BDÉ’ B´ÒÌ“áè3\Úöñ0®¤ó¦y´ùÄõëwwÃ3<ßE¾@pUèpšlN¹ÿôÕë?þäÃw·¯»Û­ §©kWZ¬ÖYÓ&Œ™ˆj­Ã¨e%ɪo§qfǪEêÚ?ú³ÝŸý»ü'öAýE{ûéýO_]|Œº÷#oVµIpµîªÖãX0'›äêêfË´]Ã49¿g+E„"lÙ·8QÓ"ÓH’„9à£K®fÌ™'ê6í\‡Ñ¢™®ÿdûÿÕŸnþ8 õË.Vö%Ñœ¯>ßþûã¹Y}±üBùøx[ß~]ïL¼ì{}(~¼Ûn¦a<ÜÜà]<ïŸÚfõr*Y$lI#b¦e"Žp$&^*”³-!‡$'ç`ŸÁe®î0"ÀDˆ…žDÄ™–H,(IÊLaP7?ÖÉ/¹¹ƒJ aas»Ã#|y*yàB0…GU‚@`€åÜ{8þù¢’ñs¿¦K^xÀ! &nÀ‰‘RnŠDMÌ‚Â@/QÕB… ˆY„I• `Kžzx 5_lLÁ`,^ò8Ž•”È9(ÜÈ3¥E¾CDŒH^- H^ŠÄ@¨Ã=*±0È-{Òa¬^"SpÛ·PÓêˆ ¢FØ=b,Q‡0'¹»QJU!D'§9Rfn„ áb”,I!L  l\§JŽˆEÄ”‚›–ŸéÎJÌœHš¦Á¯™*ÿP=Uìá@9î¦@&p@ϧÇ{ä¯lø`*ÍŒšñÓòê¯êÝå³þMàò‡ò?ÇÏŒ†¿ø‹þ#üpü>ן¨ͧ«æÛX¿ýÉé¯ÿú¸ŽùßþåÝq‘¼ûÁá]üøpø§»0?TÎi»»2Ôùõ#>øcÜN¸? ÙÙ»Ûºëå‹/>öÁž“ô)í¦yÜ6J3À(:ÇZ¥VrΞƒ¶Fk–VÅ \ڌ˗ۼ[ZöeT¸ªÒd'èÔ„ ˜û™°ÜÙ€€L@¦V£x˜ˆHMr€=ü4­„e•‰1¼Û+µÀËù}}Z5-ׇ_] Ñ·ö…tFhB@ŒÓ…Q’C2 L«™-!ÜÐ2(H˜Í=T7)ã=Ó¶}ð©ÆS?Œûê•(sET÷…Ð%Áa¡ð !”¾,ÍÆP–%©.ùGî5J;š.%OR™&DN³WÕ9 |,cƒè%‘=6í†Í¸eæò5vJÞ4›œ»¹œ$µ’§¦¨8RÓl’\@U,SÕ˜Èg1ÉJ¸ÏÔ7ëªæ…»PÝ *hާ}#ÖÄ5EajIŒ >—a> º™%%ÉÙ”+R&¡Æm¤K„¬6[ƒ¨Ódu,óìP¢hSÃÑKû¹Ö«Z;ô Ô+®×}fÇ©qÏëPDZ¡½÷¦@!Ùõm0¦r· B³†—yưÔ\õÛKoG”·óøõtúêï*ö¥¾íÚ¶ïlFÊÒµ›M²qb®Ó|d´X!9µ&}ðw—N/Éó<ÙªÛéˆ{¿eø8Û0×ëÝ:]—R8¥¦ÝºN‘d†3tF™<ºÈ¹m§yÚOε¤ß…ú›êÊß.>VU7US¯ó µ‡iš¹[µ­Dß7éÙõKá\f/Z—,܆Áªmº®³Ð‡‡£RÈÕf"ä)¡kwå4©ÕžÛÓ¡ˆHÓ¶>Tf–.wU/ÆB¹o›œ ·&/l)żš+hš´Ù¬//®›M_áµ™õzXu}ÓõH9¥$œçišÃºë»‡®ú~µê\pÒñ@tsu!†2N™åâÙåų+ Çq8©jÓ¤õf»É] )°Ž¢³´©[uW7§†t×÷×7ÏûÝêíã»`7¬Fã`:MTÊþu¡Úªju[êU˜‚ á rÓcý¤•Á¯­}|©[Î`Âÿ?¿‚PL™(w ™“ˆèïßJô;„Úô­($?ÞKþ4 GYÔâ‡4’8§–ûU¥ 6e­¶»õjnm¶2LÇMÐ=Òå|Lúa=Ý<šþ“«éx Ÿ*¥©ùÑÕŸ­Ö‡·w‰uýÁÅC)épí—»Ó¦ØÍ>íß ·¿Ø¿ùì¾¾–ïï®à)¼gª§™iÌ ¨‡ÁÕB}ªõááaÿæˆh@Ì*…d¢Ú ¾÷aÿâf#r†C³É—õ9KÝÇÍ‹Kh‰ G¯ ie}¹ûêõ}±¨pâÃJD”˜òfSç’X.w[h ¯}ßôñ³ë†õŽ_‰0H¼Ë´ks_ŽC§4Î8©[òÔsNÒ­ï å ÷„Å6Oª3Çy~.Ôˆ˜ÏpŽsƒ¡ªBœ³´¹I `´¹Y·Ý‹õó>¯ð5ùvÒà yxùñÍáøjØøÍ®×»üÉÅÍ_]þåíß}þon¿xóv{‘~ðG|ðç}lN·øòËùÝÛÛËuwÙô;ßLo_»]O©Ç $@ç=מKÔÐò žÿ€H(19¼4QKŠÁb€…p~Ö€…ÃÝ laä BÛßß–šž–ˆ{°»-þ†xê¬Þ’Ï"ÿ&Ä9Îq±:àD²ìG)8ïÐùÜàRˆý¬¿IðsS¦Å©i„-W? Œ¸…É]>N&â¡ ,òå,@^¶STƒ™‰YP#,ËQ N`{ZìZÀ‚kºƒŒC€‚]N¤ ‚W%·°€Ù H@„sÀQUá&B»€/’ÅxJÞŠ€kâ¹Hù"A6 Ed‡¤b4ÌaäËg't^ÝùSî;-ê÷'±ôpgDOÙ7ï¥ ü$OyúgªAÉHAèxý:@ÒàG >‘YZùó±}|ÜÿüWqýØ]êéíú}¤ñsmO6èéíñ8ÝI7òUš¯ìÕôý½ÐU<çáOËg?Åñgh×õÔ×õÇè_à£küà\ß~ñãÓßþÄ¿÷Aºß‡LÁ3PêÃíÛ‡!é¤ý³(aQ«ªWsa"\^Ü$÷¾Z*nÅ+|4›8º¾i›$m’ž$BᦦÓ4-Dm‚:dÕ£Äý[Õ×7ßDør.Ä¡NäØR j8`ªä ÖsJø{wxГ¤-žd ß õ%U/ÀP žÚáHPA"„ h!!‘ãELDáH GŸF:¢Ö(2˜!tIz]¼¾ '¸EðӨ§µ“Çò`)à„˜Ã'W9y aŠyñÈÀ+B) B¡ yËÃ&7©kÍ`Õ¼rÀjNöP wž3¡UG?:P)F¡–±Ž–¢¥”(všï ‡%âÄ¡Â&wÚ¬ÖO9Ë™Nç÷±1§j! ]nü•¡Ù ûéán¾ßO§ ˆ¬Ô«’¥ Î5B!išÔÕÀlPâ &vƒ Y†¢AYeÍB4EÙ{Ô:5}À”5lb=D½·Ó[Œ†±LwÍe‡MoyÖ,­ÕIÓ@軚1{¬;úê€|@*@FÌúâ›Èl#ƒ²‡°‡"`^PçùQç‡Ju•Ï\¶|•¹ Nž<Š‘FŒ3€‚‰)Õbu¶:Óºû^—Z—˜µå4ëhä“Á£Y¦²¿÷Žè— öß2…û/Ÿ“ïgêv>šf¨3ÌÓ4?»zvÕ´íñ¤mÛ=»x¹Ý^di¿|ýE×uÁ˜Wkõš³@ƒsÂf×µ}SÊTµä,íªo¸­S~ýê­™í¶kUÔ9r+â)çÔÈŒ`!é2õ]¾¹¹Ù^®îޝ«³Ø®Ö’Ûœ-6OÕ I°jW»ÍÅn½£F %XSsU-«U»^¯ž§aš±Dk€±„4œD-Ó쓇êu)•j­Ã<ä¶í×+4Ñt-‘°e"’ì©áÔ&á\¯4ÆCõ˜Š¶!1::ÂÆCŒ6<¢ËxÖÙíIüpGX˜"]&”Ö Í/ü«¶È¥@ùçWýC©{I)¹û\kI$çÿQºÄ¨ð$™ûÝÑÜ ö`^tæ”ìÑd‚›Ö9$ÚMJ»¾[µ‘éaœwµ•ƒNÃ$Üt«¨íamùJýeœúÇ£I~IÍçñôxüøúëf×TíÅn¾·iwݧo‡‡}ýiG{Ø÷uÿ𨴶‹n³™Ka-·c­å˜WÉ¡1 2§(Y‹h¥˜Ó0X\‘ÈÑ EÃ]n?Ú]¾”æq²Ó€ÍóôÉ÷Ÿ×ïÙ°Ÿü¿øÙÛM¾ôµYœÈó:ׯI()»£Ø KnÚÇa"EÛµt¦RJÓ4Û ²ÈhUu4©ª5MŠ:Í"ÌÉ<ùÂR ã=­J)8œšã›Åê’¹a윀α’l‘%­rÛ. — –¤i’wåmÜí›Ù·¸ËüîíöÍú£‰/>°¹|NëgHݦ{vyèÊÛ‡ùöþßý—¶ý0ÿ‹gýËíªÇê°›Ÿ=~þióðṳ́͗¯Ê—_ ßÿ—%AhE¤o¸íôËÚ7KN:g9‚hÉ/ZÜ„t–uì‹f“Î¥1Šx´FÄ"éü5@ãB°÷`bZæ/Äî?oÛhɶ?ƒˆ‚ØÏ…÷Sœå—‹ÅÞE±ÔÃËV~Æéž=&Ë Òò¿Ô³Œâ=(ˆ@&XèäQ—%±,p@áް8ï¨o6ԙ8â¬h}FDX0Y[÷ ¥#rDa@,{¯p ZÌæäDdÅàwrÕ¥TòàJ5| ÄZ&ö‹õY[?ßT)vO3;¿–e˜ ¤X°áÌÆ@€ÄBÏ’÷*øÔƒÒ"¼ü–5÷¾ ²oýUÁâàZôbâB¤‘ èHòã Nn0ñ Oñç§~K‡þùóO>þèÅéò«Ÿöü ǽ¾dl®ç¹âÕܰ?!yºówñƒÇÿ›ï¿ýOÃ_\ùëê ¹Âõv³ý“¦ûÓM÷<_ìV©®_¼kÞýûŸz÷Åë;©wóºâE+}Ý—uå›ÕîyÛL~ˆŽ}Ö)¦™Érz?v€“,‰fÄù½ðræpq…²Q†ÈB0‡ž …\ç 5°ÞÞtWk[×ʳ.4ÌAí&iâò:¼Ú¶­®Ç‡G•ŠŠƒÖ àš,k «±ÈÉ(…(Á ¦^U]ÃÉœÕØ=Ä‘eðÙUæ&M½¬eŠPZLb~|}zóåôÕ[<8jKLÁìÄ„ÄI!%È")Øvâ\A5,Má ”Ö"¦L«žƒ¤–r?NÕ·h ͬµX=åz«Ã­ŸîQUí×¶f¯Ü—ä P(NštÒ­*âXæC僷vÕÀŽZͪ‡¦H •àÐs+3Ðø„ù€ã§k¯—þ¼I7='5µ©¹h4?:¸—ÁOÓ<,ÎXÕf›ÑxôÎJ,¢„lF“æ¥EGh„Sú®ê£ïZ¹ÿšõû){ëéû_jŠÌ+Q01ã,'±‚Ññxïw·©…:¶ëæîòÐ ‰¼í·Û‹™†ÇÓtR-è:Y­›œ“ZCZêú”SÃÄæ°Þ4yµZÉtš´zµ²? xöâªßäf%MMÇþ̺½¸Ü^\…úþí}™æÇôMû¾}à˜´î‡Ã0 Iަ›¸M©Éî>ÍÇR†rú–Í1—ÓããC$ë¸ß^Æ&Ò4Õ <<ÜO6Õð l·[‹˜Ë<Ï3;±Ñ¦['NB ‹P0'€NÇÙu?—8•y¬åtДšýþñxïÓ€ù®0CøòŠ€x¹5Ú™öÏgI(ÓS…óô¡¼ß ½ËÅïí8ùƒ©é¾óF&–zã¼ÀÌ–‘ÿï»úU ýßì½é’eYr·Ü}ïsÎbΡ²†®Ø € Ð@”ž@¡WÒ èôÿD3I&3B"AšÄÀntuUuVŽ1Ýé {ow×}ndV£ »˜Qa™a™7î=qî¶»¯õ-zAò_uð‡0Ì ÜIXÇv;avWv’66§‹æ²ëÆ›r¥‹µ—Ý&¯×‹9îbïé,p—s?ÉJš•´å“åÔݽ~ûr÷Úh—Úe†ý¬Üå®8·éu~ssýåë!:NFYp7Žý0v*îÆ¡/b,9gkÁ(>í‘ßzU¢ƒ7N– q@$u›ÔTœ8’ßTO[<}úøãï>qòTÞ~yx¹ÉM¾L‡fìmu¹óvˆºþð„T̹¨ŒÙ†É§ä¹À ˜ÔËT4OiÄæv÷Õo?yuÒYÞ2lŠîŒ…‘ˆ¢)Š™;A­ ÏãŸ#„p®Z ‰Ÿà @llкZ‚—@h(FBG!š»ÂÝ£Â5½êß¸Æ ¾ØÙ0í÷?ùéëóößýWãa¼o2Ÿ‡OK)÷·ÛgNŸüÖ'çpÁãiL”·}Ù'D|0Å„|(e×¶ìi»««êyX(ù» þÌ]ª&χߣ~°Îé€s]~Ï&kŒ}Nªx:ùÜ“¶‡IÚ7åì•MGDs8‰9Ø¡^£o«®‡(T먖=øq¤Vrs9D³njfg¯c$p'w"'R"­Ç÷ÑfÀ¦«“ÁÔ<±»K]ý‘ÀØ¡ †*ŒP'O37Õàp*ðНòãÉjØ$H °#±³»ºƒœ ìεCîÆ©ÀÀæTÅGú8 GôŠ0׈X(Ì}r6ù¼f<ÄI1ˆæD.7usG¸8ø±Ûθ’̲«¹Ì7xIþÓºÌð4ÕÅqÄ1éq`ÄPçIá ‚†‚yËÏ3â„û=ÎOšæ%^ÿÛ·ÿõßþ»ÿcƒÕ ~|ÿÉUùÙMÃí¥´6m=P.~°éÿ½Ÿå1¾Üx;þî2}p«¬^Ý©å'ÿÓw·ÚKloyh^Mߺú85ñ~ƒ2Ü‚ ¶n"©3Ç®[­^¿øjH°„‚i6ÀÈ­pÜ4LÅY‘€ƒ„i‹}4 ÓŠõ´jœIˆƒÌyEÐ÷ Äãî©' y¥$Í”L:FÔÄàµì· äãð¾V…¾¢»ªuÞ;×BµVâ£ïè¡j%‚8ZpDÌ!°Ê»n Á¹œ+ûÒ^ØÝ …TëX¨*5nÈvµÄ”€¨»Ô5³ +î~HUwGqbÃ#»f¦É`ÓÌG!u5àÜÈutM°/S쌽ˆ{è‚dO¦oÆQ£Ñº ‹§^|HÃÞn|JeïÅÀN Z¬%œø`Sé!pýë x¤dýx€™ñd<ÎJî)Òíý&¹9Â2/×Ë“®é"3„wÓ¸÷ô6m^Noßà~‡$53¼b?Ý…‹"dçÉ®[EÓTòd¹ø³–$:¸ @ŠTšcp} o¸µØhžöfƒÓÛÒßcÜ¡¼Ðn_îóþ4´§l`.‘yg©Iо”ä¹pÆr¹Ì—ÅÇ\ú±ä-r‰7l…PKY&”%X¤ |æŠÑvÜï°jr,ˆîB®ÆÌ«î„rʺÐaw{[6 n4UDFØM“jš`¢£ùÁ0À °F4æ_ùŒˆÞ5~Nåû`¼ûúwÕ”:²ÊЛÀŒÍͬt6iÿüüâÔ]‰|Ý®x-BI«ˆ} IDAT<¶Ô-–mìäêÉ÷¹%3íǃR^®—ËeÇ>ÿÉó³ÇÁ²ÅHDÜ4]×.‡q\ŸŸ\]dË÷Û;…~ô'O>¼0+×›4 ‡œqéüt9 i Í%úíå"4—§§———p¿ßeÈ£OÉ Òˆˆ«¥qUS»ŒCα §Ã~{tÈä.Ù \~–‹yýöÕ0”4‚ѱX,ÒÄý~ç£qjs_Øc'JL{ì¶i7öN€ó°-%A >5ÃÍnìîÐÙ¨H𝗠æ9ëcŽÓ5|Í9‰ÿnÅr_»ã2)ZªÛ'¤’¿V«ø×ß¿j!ßürÇhØzŠ1¢dq°y ´$ ‰msšëÅêÑ _Æ©-÷Ó&òÅru‚%»o&JÝÆ¡àú6ÜÇáÜJ¶6ž\œ¬dÙµ1ø‰ÜL÷ŸO×ã Ã'øøé3û“=CÒfÔa›ÑTu^Ÿ¯Z•>4'kœivpNÉÚŽ9+>ݪyΦ\ÄŠ;ªJ‘Rºª¾ ž|ôáÇŸœ=YZ;5m+«òò¾Ù~å¯Þl†A>yüˆW©Ø8ô‘•ƒ9JIš&¡[Å–‰S?ši#z|ö¯Îþ½nž¬ä¹ø†W•‘|kÔÞÜ÷ÒÐØx¯’³‰»§£·Ä.ÎÀ‘æLRW ˜}ýäÈ,ÕlR!í‚tZaq ªR4*X‰@ºét£;[ðuØš¤•PV·¯ìþÏç¿þ›¿ÿôñ§a˜Êýò/þÓËÿëßýq¾¸x|ÕŒùe(SP’ö=îvôr¯7yL§6îú‹¸î°Ò1‘M;p#wuõ×j#zשã"z§Îôwã”ZÕjêëi ä¨?ø0@`#"³ò€“wp‚W5¼5l¥öÕ¼†‰{ÝÁÇéœ[_KŽ^z¨NKæ„.§úvÀyŽBѼr&¸¹Y}Z;†ÌÖçsr«593"Ê 0‘±VÔ,!ªN(?>=)QíP"”RœŽ&c@àNv¯:KÔýÜîΠ£<±J’ªeÜˬ¬«"8róúžä ÌpvÌ ˆ™¼Ð蘨:¬ pf§z‘à™¨iTƒ³`p˜8‘ûü»©Áf$TgID Ì’P¸7ïO«é öñÁ@E)€ŽS ŽØ“õ[äS}«RB’%:“ó¾)áZGvüoŸ§ßÞÄwž‡·C.xñ®o~0À¶©,唚èêDANÎNOC¹û'‡íSÂ凸ÑêƒËVÏ¿ú|—¯¯Õ¯%_´ËË“uÄ)M%_cµ ‰«¶Ð4ÐZI#lyÚ%È%À@h‘7ÆXæ“ R"§bå€Ñ³Á†¦PŒÒjSȹh |® •3WÑ|lHûq†4ŸìuªÖY„&ªÀ›K :îâÂï Bó ´r«uïXüÿa~(H ÌÄxḠƒÙóáVM3 ¸°™«Ã+úÉ3Y …›Ï2'æùÛ“8àdL>*1s*nLΦ^……ä˜K}¸; 5M€Â ¨Á ÞÁç{l TPj‚&ùJCW]Ç‹ÆK?íûäÛÛ^úf7 Ûm¹sî*ð g¤`Ðrà†«Ýh޳øÔ?ˆwoºÃ}N/îtÚo±mÛKõ½8óû¾oÚÓEXF# ÙÊ„ ÛrŒ™ÜœXÙ¼XÙÓ(Å©e:ÝÚºbËC8•óþÙi¿“°ìÖíZÚÆÈûÍ 1&4¤)«ÂU=ik–¹§ÃÈ!†q,o_øýïo®Ÿ^bÿfl FCrͺ{k„ƘÌFeOªVR]ß×737ía\4¿ý<ÿ‡“zgg¦Nâ24«Øv!r1Vçb(ÊîcÇ",[dÞù¦ËÃ)¯§Ý½yµÿ_ÿ—ÿûø7?è’O7×ÿõ‡_¾xµÿÖ¯]µÏ†)¾V/šNÆß¼.¯ÞLw;öA:•<ê²¢nEËÆK‰8Îú/PõÏT}•;Ìêê+ó(°òúkÖ+Å{ Q;Òö ô ün–9Gg¹ÕÙË_{2†ª×š=EóÏ×Âã¨ÝuñÙdä:Ÿ•^¥1õòFsJ,øèe˜©>8’HŽ*;­´QS5=æ â0Ä}í> ¯à ª>e2÷BnseèVÓ] $•–À(9H™*˜É™@®óü‰Ìê5™ÂlË"sÔùÈgùeEñ’[ž± Çq”º×½ÅóW×ê…b²`6ùSó_Êܵâ?jp…Û¼RœCWm¦5êÊ`Í[ï•C×4¢,/Ïâ-Â<²«4 F|NïÔš®ìðÊ3þV[ …–GpùQO+ßk>zÚ ÷åíVÓë=LÑ'–­[‹ýíǸÛNKØOîóË./‡·éÙÙù·ò)¥å—ÿù͇í‡O?þC+/ÆÛ?ýqóùëÞ¢-…y1€Æd¡v%…‡MŸïÑÏ•CÎ({ø.!%H„ü(Þp'óÚ˘ §ú›zÎÌÎgÞê$¥¨a+ÎJ>g Öçó¹…7kÏê±Þ0€`£°\‹ ž§Œ6ÿS“jôãù  £ˆßëšè{C<"I!7Q5¬Ì  ÎàLáæjn•ò¯†Ìœk•UÝknLfÈð\;pF1`„M5¸Èjì—r™“¤Á †Lä”aäF B¨] ­£/¡¢°¢¦V›ÀÎT’ïYKC]¢UòÎ=VoÊ4ŒÃáó›ô:çÄÐE#‘‰P(XÖRòyƒÕÉi{Ö¶§Û±É‡¹OÞŠ C(CÂ!ù8”¾/½*±§ÔÐ8j†+r±þ~Ú5"âËô¶·²±©GFlÛeâlYÕÝ´‘›Á3#j²Í9(±ÂG—L¬TKÞ†‘êà¼Ë%ŒiPÚMãd™Á™Åâ‚B ScžlJãH…\PheÈ `RR·œkµˆ³,¬;‹'ëv=$OE§cÂ)–‚ó‚LI3JXva±nÛsæÕ~Ñ›E¤çåµ÷Í£¨]X …Iû›þæUÿúK{¾Ã® ¬»“e=P>ä ÛÖ"´xQGQÏõâ›áb…'ýðñÜœ{Gc´Ÿ_Î<®zS‘Úäs‚„ЊÉT²ÚÀÄNî#Ø (ýeÜonöÁV' ƒχqsHipöèl)2{—# Ýy£“s+И“¥!ÇeÓ Še"Y^,š¥P«Ê#·Flm8$xÑѬt‹®N8{âbÙ,º¨ÄíV¥Yt¡kf^ŸŸžžŸõSê÷»q3ž/Ú&4!žŸŸzÀ cf]7Ý"„r(4âª=99‘Eœª'E‹^÷x‚ª~Ùù­õŹÊîf ]¨ÀÍQ€âä†VñyR³TÜɼæBîb~|¹¾ÏB$‡[QdöbZ*ÊÁç22Ì0a‡£" ª™ÃÎLóÀɽ ïˆ\gB‡Ã V£“ªÊÞ•ygá³¹•B£ÈT̳›‘·`Ö0 Ù‚;Á\¹¦È€™£Ç#cžv+Ó±`®ÄAsªür¯@?òj…o‘û‡Ùƒ6‹f #u¡Åßugt ‚2î[àØàÉ}Ï~Çx9¥›éÕvùäûˆMÓ2Ò}ÂÝÎÛÓFâa1B€·„·|­ãåOÀýæâO6Ò ÜC ‹ÿ'ñrü^Ýìèg›Ã´«Ÿàwhp‡Ãkjû Ó‚·k7ïR#)5<‚\Aa$ÚLã}¶E1ÈBb#rDG†8=Æn§Ë…O¢(d¤@f22F–YjÉ2r€ªxä S °i™ÒO Ló\³žôúžá¿î|PÇññ«3M›@©aD"MŒ!„ÈBÙ‹» CȈ!m8H(D+Å ^ŠCXPçbŽâ™ÔKU³âD6¹ƒ¤@r]Þ˜ÙÌ?ñ³gVh¶V¾O½³gU"ˆ\lˆ™‹W"бÏ‚Ã3006šCnÃÔF_¶¼„sBñv—àNˆ/R)ð·mPŽT¦¼Ç¾†Es¶ˆ‹nuæã8iŸ ¤%À‘­Ï~?Ù8ÑØëxðQ`nzv5hôÔFN%”pS6*Ü‹Z Ð@À,ÎÊD ER°+hæ&S“JuN„ÂH.ÉaUÜëÆ$” h?(Ò Á&$E‰ˆwô¢!rìÕ6% ‰x \‚ÈR™,ñ}(à ‘Ï´([•´ÛRÓ[NYÇÃɨu‚©Dð‰ˆZî Û4-†É½x£Òh4Båî&‹·›´Zœjöùp3ÝÝâænGL¾mвs ÖДœ̊CNv&PP‡âW_Íb†ªa%{ç[ýEWMvä¹\ÒbOĈ,ÙTÀ0†‰à±% äÅ0îqØC"šc?öåõ‹Û1OSÆâì]ƒ%Q{³Œ­.–‹…!rÅf³ë˸:=U·—o^å2ˆ½»};L±åÐI¼\´Î´äÀ)ͧP\mßÞ+lKæFZ¢“3 ­ÚæìtÝMÓî®™zb·'Õ\³ÅbQÈ]IÇ‚LËÓ+ZRWÔH ‹\œÑ.CÚÖÝu,EMÓä‰Lr[ÛÎÇ2nöÛÛÄæyòÍfæÔ4“‘ÂrJYIëÉ^Ñ­¤‹™pDǬꣶñ¸æ¶¯U>ôÿ—CÇjÞ Ç¼×j&ª¦‹_Úñ¯ë’æÏþ °YDä5»åx7¦1EC#.-‡–C±¢•·!œksÊZ’˜çd°%Y °7Rհ؆íçû©Ñ‘y³ëwŸÝœ¾\_•uXwë>¤}·”O~ãÓ'¿ùäöl{ÏoN/Ú‹îâî·‹7÷yÖûGϺ«Ît½ºþY¿y±Ó}i… KAÃÝ26ùÑù©ypWµÄìb,‰‚Ncö<ÁŒ¨0AHdr)wÛÍþÅþ“7«géI§]éÓe8]—}zñU¸ÃòìòöpÀBVÝEkâÓ8Æ2ÁËä9L½çÁ82ˆCŒM·P3Uƒë:ž6½œ' ÉÕšâ”<ssjÒ¨Z’™5M p2ÓRj(ƒPƒkû1âô]‡Ô˜Èi²W¥[ÆÕ§œ#.½½ˆg‘EÛ|­×ר¼$˜²ó®Do“¬ܰZJáI·^]¸ysè¸ÉÔ^ýà£'¿ñôó¯?ÞnÊÎF×7Ûþ³ˆå©L9O;Û³ãá> ܈˜Zöl˜qsirŒÒv&:Õn–Ö–¨Cg¼5áøs-NV“‹„Ôif08µ„@îVQg †¸ƒ-8;NõIQ?p÷JôžùÕvœJÕ¥z½­xS½û¬8ã£Yºú#ˆH\1ç=Ú\UÔ8½gK˜Oa¢ /©EÙQñèL²ÏîîjVñþnVKÏ){âV”*É©„&>Üãl®ØŒÕ¤á5>U@`rØüêdd˜j8br–yìX×tFÑ£ÚÙ ¦ ±©ÁÜNdÅÝ<7‰0óG \ªÄ±X‚ËÑÅe°AçÀ\-ïºVf ˜{1óš¦õÞÍÿáosŸÏBqŸ¿RÆ>»ÊæÍ˨p@´\À)†¼{iþgý&òâŸ=º¼\/ûû­N§°ºÏe¿ÝnDÁù3V8$\\tûÍØß`å°-ö7øÎGx{íù¾ûòpÀo=åòÏÏVð¦ùrïä|×ŲwËþ@ØElE' H`垌F»-î È‘àS Leþmpž,$(¦dZ™—“SªB­ñ?ì`®Çb ˜ÜúnƒA# ”¬ wiÒÕâ0 ÉŠÄ…ªLÃÔu@ljnâhBÙAƒûTŒ#Ä$*[«^òÛ[§JÒ.ntûww8äbŽiÂõµ–‡µ@L†£C 1sÇž©Dê1qP“Õ:˜DX"9j\Í þš<"ûÔn¥ý ·¿Å„Ág@„ˆ\eSÚ×ÙÑñâjIˆÝ¼LèbÌÉr*ž{σõw‚RpzFQÖ·?NoôU|zzzrê§ç¾- 8“bZQ³\6¦>¦ñ[9kÒD è7û×w›O=ºZ\:Ó´‡û3š(AˆV\RžÆM\h*Mv0Ãlè‡;{ÝŠm{ºlì¬-¥Ä}f§››;7޹±‰„›õÅcUç”Æ”7Û©d3#7æ®Ç”zÓ1`×ö‡a¼îw¯5Æ®¤aóØç<"¥A ª÷˜Z Sh6µ¬½Cå˜TÃŽqË»7Ñé˜&}$]~!SïôË=N¾Y½ùË!(|Óvþ=Œq?wøêÑhñwš¤}ãvÂëŸ#¿¡ºHkDô<‹˜53Õ>ó0æþ3ÕÛQB܉1Šsí6éÆq¦wçß¿œÚåÛ·oÇÛë§Ož´m‰9Òâq©®$Œ¥89 C±,qšFSZ/Ï—ž µožÿëßû7Ÿ½|þå°M‹³>L𭕆4ÏKGK6ºB¢,¶û[’šgmFVÙc¦ÅŽ”m`†£qn¹aJ‹G×ÜúdñÛçŸ.¶Ü‡e\Ýc»µMbJ'­-ã>ûˆÂý'ggW®Ï>XýÉ_þÙÝÙçO.x½ûÝùýíËŸy7ÿþSúN¾³ºËýíÎWßùþ‡Ä2ütÚÿôÞÆNK¸(Ÿ^½ÈÛÓËÇoÖãä­” œ•æ` ‰Ì‹+ײƒÙÈ\‹Õb‚. 9èqB@ˆv®"ƒÂ.žçKîäÌÄ®ä ¦Å‘L~´t“ e¯<Ÿt!r£ÈÑù8e™-Iæ õùæ6óy½¶|˜EÜÉ”Ýà&îg'’ØÉ{Ê=ТJ,ÌÂÜT¶›™ TÓ"‘ÌKBg"“Êɨ膇‰H¿Ô@Ä”çÆ†ÖK…K]ð¹YQ©’jV¨ÊçY´Ñ\_Í×gs/ Ò#ÈpVÍ•Jy¨DˆÅÆ2ê±WÍUó¥Â€S­ãZq…züMÌ""2Óäuîɘ8âȦsr7+®iÙˆyéb5žÇ4¶àç ©¿ºrÈòLS³‡WR`&Àf"æï½ÍRÂÁµÇÖ°¡(e,Þ`ü¡›[úÎúÙ÷¾ýƒËݸÓíîv«± yÑžâ»ÿòÑçãõ–Ç&Œ7xœðÉÕâŠW'íùoÿ²¿ÃÿjÃë¼(x¶ÆUû›ÔñB4~î~{.Ó£05à¹Æ1ÒŽû»)O“OcV£T[™§ž`€>Ac8ì 4€àn2®›4%|çûøøÛßúüîúp`†ÝÂî „A†’áp.›6„¨†¤%çÔg3Àuìî~4ßqm¥*Hæ) Œ Õ¤ë*ìsÐ*‘¤ ̹„H"Vj—B˜ª÷®Ó„ ºn±^7ͪ],DK§ÒS@1të¸^õe» §ˆx…ÒPÏ‘ÉîIä^‡‘eB[Æ¢•Àfª­"‚”<gÑnn>üßµ+m_ ÁM8šD +³ˆd.ÂFÚ>)Šg#!æ‘lÇUk…W ÷.«tƒo†—”x²qÀÁ$ ‘|ƒ ,±% # Âb±:å“CêKQ‰C(ÅÆ”öš¶€@˜¢s4ö@¨&lßXÅooý»ú4~w¼—Ë €Ø™@äáÈÏ!w£jq&‡—–¡ƒìsL5³Ð¾)M‹Ç–DF8HˆŒÀÝÙŸ~ô„#ËS™8pÓ4¹=;ãއ≠™¢m–Ë®iû!²‹ ,chÏ//nîoÛÃ[º~üäÉÕéUàxsw›&MIQXSö"ãÎòHü?ÿ—gÓœ´L5–Ý\ÁΦÈSÑdZPRM3.SõRJ)jGõþè sbõ*‡g7ó ú¦)Ä_uºˆð_3ùÕ'W_Ð_?ÃùÛoç¯Ú¿ôwÝÎã.¢÷D?WqÛù5䯹 Nö}r¨”ƒƒ–2•"MÛrCƒŒ–›××oûóɚˮYþ‹ñÛåæÕ0Ýïïʯv~{úȯÖËÕòÆÃ-õÛ~,c;^^/Þ6g»R¾?\ë÷~—»f9M’ó°Ö§e•Ý|¶÷}¸úµ‹>MãT¶‡7w»~êíôÃu¼óq ;l(µgâ*q²´~t*ÇKi× Ih'7ÝZJ©[·ÝÓè Û÷;-¶Œq½ºj¦0ÚaØoJoíÚö/³rqÒ>ýìßlþlÛÝÒ§íùÙÅã;Ym§¡˜ó! gË%kIjÅ)Ábd¦Ys.fÌ( ÎxÄíIäSî_çICƒ‹HxjY×ÂFLÙs*]Ó8;1;¡bÍÌæ G! IDATÜj\Ïûý'§Eè8x×øbeK²ÇŸx{.Š¥Ðg iïSÉ>¤)¶MSzßÞi|"‹'—rµN:±î7»7÷ù:^ÉôXé’3ÒvŸO.?n¦}þÅö/n^½xî†8'Aë;­÷)ßc0ÐùÙj¿Õb™È¨"ØÜÈD\³Üœœg‘­S/ù}å%‡¹U¿£Ô:yž¡ñ5=Èæ$¡‡ Á<«†ÍN†Ê|›Ÿ9p5bÁ³ZC‡Ì]ç„"âYÆê³£p3ƒ‡ºÉT`ÃÈß]kQa`™£:Œ N¢óýAIÇ)“30³õ\†°ªÍ  D7">Âî|6Fù¼¾å@úÖåå"¿¼Ý '8™`¿·_¼¹æaƒó‚ïu—'bØy;Yë.h‰þvOÁÖç=[át g`ux3Ž/‹õ:ídøÙF3VëvØGÙhÍþj!í‡m”‘ È =^\žµÙýͶ{¼Æ‡ÍòlµÞ¦©ä‘tD™m¨–!Ž1䤵ìq##” \ªü5ǃTŽT×{¸ÃL¤ÌBN tž ÕqG$æ„ÆmÆ qaƒ8¥#R¶b <4Ò­Z*%D î%õV,ª«#Ù^¨j²“#( "ÊlÔ0:§à”É"0¢"ú¬øÌ>·iödÕѱ‘Xñ„Bž`0„$ÂJš³S1ʆŒ0S.‰ÔHLÈZöN|!h#“ŸuA@\±®d*¹_ª± S 1»6z2Znº¦-Áñ=òˆÃVa®=6L“Öi\…RΠʆ3ù`ù€q@¡Ây‚S$‹•(L‡€Ü¨Nõ¨²/™H @ne4˜!85F\Å»lh˜ÙÙI¬@8ò¹ ©QD³¤–$¤¸ ËÐÄ8ƲÏ#´å%Eb/üs153Xqƒ+TAÃ4¼kp4\\ Ì ¸R³× MÌSäƒ)¦lIˆÜÙ€Á€^1ªäÃ*® 7bEÐââÁU¹Çä`vÄàj&n¥ÎÆÌ;¹"ú¦Û?FE4?þçà­Dä3 rÆ™¼§ÇswŒãTÇM! /yì{¶# ( 4ˆ‘$ G&Áõ›V”â¥[¶«““؈e‹%¸°jÎ¥Šq³œl{Ÿ§©hÎnCJ6E$.—î>Þݧ››=ßÜ\O—.Æ©s½ñâã¨9Aˆx8hN ©¨BóœäV¯yг*½…T™ˆòýýÎÎIÊLD¥TEÇ1#ïAó÷R…ý·?þ«"úeý^¿êŠèo?ìªíìŸßoU ív„¦?:L B14A‚˜‘ª„—Ýb±úðÑÓÓ§ÍOƾl²^ž¬Ï>¸ºúãýÑöõ‹'ëÕÅ‹ûôêæÍëéúùãñÉêâ¬l¶ég%QjÎ8¤KÌryÒ=½¼XŸŸß–Ýý«ð…z|zq²Ø¿yM6 ]WËÕÉòÙ“'mví>f‡äa·%·¢€L1e+ÅÔ¡Ç&árðÆä*U "(‚„ðàžÝ‚ÉZ !°333y\3W°:דK‰Í½0%)a~0ràдB‚HÔFžò$qpa6” è#‡»³ƒÈX¸Ä€yGhÈy!/L ZóÑæ£œŒÈÍCUzHNc88`l‰hKÃqÎSñ©XNð¸1E÷ެ!#0BghpklVµYK*d–L½{X²“šB1â`»ÖåâüÌ]wt¿Ã¦ÇÞ2œµØ>FMcFuR‹ÔLZú< ¥À!E\—JÌDp&SÒŠ©„8cјÀnÄJab.œXÔ¡àl¦U‹-’ºO>d†¸ªSt fAB` . ­Ãºn!¡I »B”\³»* ¥S©Èg6©è|í%ƒn^g÷ZP`ž­ö2‹B£JaW¸ˆ4jFZ›ë†)OÙ2›²‰º%-æî”|6¸Šy1u%b·zéöo¬ˆÊ7©¡¾±=ã¿ÒÇ3Ó/ZƒVÚë¬O÷YoDPu­  æyôáný¡Š>ÀbçPˆáŒÕIpv«É¸ƒ¡xÛ»¨qaVå”Q%¦í7ž³çÉÒTƱ¤ mKy*ûÍ]Öl©É–_=ß\¿9¨jÎêŽqD™8ͬ²‹޵ÐÛÏ€eX®K_pÀY[ìÁÁò>Èé=Aš?윿ßÝÌÿ–ûÿ—{œüM*µ¿=Éãï¶¿Ü;ëûv>ˆâèëY¹ï $óãNôÙó@óÍ›DÎ$€œYBiŠL®ÀDÓ–GJ«§¸M÷?Ü|þÕó¿ÿÛ¿ýk¿u¾øöëÏöù>ûâÞØáü;¿ö;ù“ÃË7/öãîÉ']ÛÄÍÝu‡éÑ>l>X/ºÓ+ éËûáÇ{VqæV_üáç?ú‹—Ý·»Íiÿ›Ï> g).é:ßtWݪ»$‹‡ý[Æ…a‘z»…4±¬bÛ(kÒ2é4ä±OX¯¹HéUň»R¯Ûýý£“ØX"°ÛÞ^üx·»~ îÿ|Xд«@çi°íaÓ·™“#…œU«êà Æʦ //  jÎãå³õå:\,h%B'jœÄS˜&«Ù·âjI3Ežs0 "&2·÷õ³…„l"G1ôáñÉåo´¿•N?ìO.éDÚ.Ù$dàÁ¬P×.ÏΞìïä _E;ÜìûíËtâÁ’>àÕÍæíxZ¦/^p¶½½ìóðæùŸÚqŸ¥G×-Úõ©qÜnŸ>y²öºÛ=:9vù("ŽÉ$v &üì½Û¯$G’æ÷™™{Däí\êÉâ­›­¾LÏu5Ú´Â`ì³ö]¢¤½Ò‹$@£ia1³½£¾±›MɺKžÌŒw73=xDž,6Ù£ØÂp0 â PÌ“•·pw3û¾ßWO*|Œßœçä6ÅrNñ.TÃåùá>'ßP¸º»Wp6Ø ÇøTN˜scÂçZ¨=À¨ÜgµÙTæø1¶n~K##~MšåîfÅÈe&0‘Mñ]læfKÊ_;¾×ê‡bȈÄéôs|÷}E\µóÄéž¼E T„ã¼n×’’ªxÏ4Õ~?„œ=¬('kûŒØ÷ñõ‰¦Ã’׿7×[!"w \ˆÈkû»Æ0@æÓ[4)% ¯õ½©;DüZkÒ3j½œýÎðZ¢ë1%qþBeš) @É| ÛuhM¥ã\&ŸŽŽ‹÷ß}óìÍÇo}ðøçñÿúÙ/Wñ|ù¯®óÿ=\nWë°Y4g‡_éí¿ºEqìÛògºq_ÜÿÍËíåCò—I>þ5®Ö—o>~§ùìÙ§û2^¶Nt0'‡£&æZÌT NX· ‘aÙ]>yüÆòdùhQ´^Ýß|r½¿±È]iš³MÓÅ…EØ’sÅ­(¸¨æ1¹;#T¿M0fwØ&|öd—;yÓš&ÄH\P+>8:F+àP7¢ Í¥d«Xm*®´yÒìï´ÔôÍ@A êÃ0îvv±i\¤m‚¬ÚšèhD€@(2 ¡`|Jи-A v ˆäNH$R-yõ¢QÌWKŒÎc¢zñWNJ»·äÔ›!s‰,ICÉ(Õi!˜-œ¯@ rT%eÅxÓÂ%º2#ÎàÚ¿—h™Ò²ƒí}¿co·ÌËp‡»L€;/ 1œ¼®ÕE{÷yQ ÈÑ8#©›AÍjEJ†É Ù6Íœ’ç5­X½dâBÍ( ±ÚÄä,PvSŠ‰Øˆ3¡µØÚ ŽàUѱxaÓÒï ¹ŒP ÄEvôÉ“7‰|@ÊÐ «SÜÙåG•ˆC ™¿`+DNÆ`%? IˆÍ­&WC<Ù­!§8Æ’r !. êûá~Ü6f˜xæV€7J‰;;‚¹dq¶©y÷ÕQø õÔÿ³ ¿·Çò»sQôl8šB}“ÝÔû2=@ŒSVžÖˆ¹4m/áT+/ ãÀ w¬Á¡"Þ-š.FbÏ9›ÂŠ¥TúrFRß²;¥’E(¶ÝXÒý>¹£[9CÇÊb­õƒhLzÚ <"lÙ™f&6ffw5Ï!Ä©Ù1OÌŽïÌDm:A þ(ŠBßiÆòu}O~W_Ðï: úªçùµt¾Õ=0‹'ÄÄÝö/¸ûiÆÕë&W/j^þ/þå·þÍõÏ.Ö+xûîwÎ~ðë¿~ëWÿˆ^äW7û¾´ßîn3Éã^ùßZžýÁ£v\®Ó¢ùy7þÇþæg÷Ÿí«Õ“Ýóöùsj7ÍÏöúXÂhÍ2îö–¢oÏìtŸÓö-,×kŽW¸é÷í¸á"ùþ°ß÷‡dŪkV—ŽÎPܳ$ËE윇!÷}rOÏÞ–e”v#aÝÊÅêèìógwOï>ÝÒNcôž¸h$Š"Ì@*ÅKaâ]‹›EÓNd%ÍE{õöù{gñlWk_HÙs0GÎ^„˜ÁEË0P1p1˜±"L<Û#ñ☇S§d I‚ˆÐ¤ö‰?þÏV?ünóèên¹¤Å§»ÛeÖÝz½\m—»ƒw±]S³Ž‹õ ÅhΚØîöCÿy_Ü.‰ï÷Cj¤äœ>ýÌÆþvÿÊ >ÿÞ:£G—Wm ‘ÊþîpG[2ÓtÍÜV¢KèV£eª,÷ 6åÉL>˜©ß$Së´…ñ‰M`*˜¸-­žxñ#èˆmð“ŒÅûÂ굇”èãÙþKâÏħŒvfT9±Ÿ‡{U^#ó{{6íÙ¼Ç9ØdZ¤éã4­¦ª¯|s¾ 7©Ã°Ó¼ 'MŽHÍÛuáe@+Ô¨ŸŒ!.•›ƒåküÏÿÝßüðú[Ë?oþ§ïâÝrX§î=éþËÕö?>yu{³ßŽ¿÷âòììQøÑõmÄø>ö|^Îma5ÀhÁMàFJ'\0Ì<ª›y¨›—Á¨ª]I‹• À`2x¶4–1`/¸`apa!Ã3@AVQZÊ(†]Mƒ Þ8ð.¸À n€8™S®Ôm{°ÙVÞ5Êç+Þ˜Ì\] †âÈ^‚õÌ ¥¦œB {¾t¼ëØY!¨ø¨Ô…A³@È™ ³Ãˆ­Ð™PZø¡÷㎠ÐÈb–À1”‰‰ˆÉ\Í1­”uб÷q€)„DŒÉ™2úâÅì\'Š\ÛJ3–Vwª®¤%d„)±Í ³~Íá ÏnÝ„(%’6ÄbL624iyÉ`Ó1§:Þk°Ü¬–X.‡C3æñÎyt)0nõòàB5š*"wšè€¡0Ÿ„ 1ºªš1ÃUR`0#Ï du/ž Jø@Ú{N(5؇‰´†ö’;B$T#ï ZK¯ Oÿ;žð¾ê$ÇÌ¿×ûŸ çNÖGÕ\äÙ– UëhȬؑ‡ÒHs;îÓ•À3eÏY•i§½Û) ˜E$Ž‚Ñ¬†&¡NK€ƒ]èû 4™Òš‡é'—Í-äù0;­},ˆŒÌLˆ……)R)‡€/ÎNë¿'öãkR—}]ߓ߷Úí÷›ôûPåM9ruÊ?À󡤗0tŽaô5ý,ËÅ’´ˆ£“f¹\um×H"KÜl⣗×O¯ÓóÕãÝŸþðâßþÛÿ:òÝØ?‡ggëÇë?<ûþî­O>þôÿü«}z8,®6l›¼ï‡nX\­Û÷ o‡mÜ »á¢œ÷Cɯ,ãðâ°xœÞ[½¹¿|_6/å®ÿ_ygýdHŠm|õù¸ýìpx¶k„º&¬Ï»§ûáðj{àC‘rØíû;µ$H)-c×­ÚÆ4ô}o’´³˜=;±c-fÊy%yEy5 Èéün[>¹}þb¼)ç‘CRÊÑD\Ž\0j”@ðÆÉä%,B³¤–˸ˆ-7MZŒš% %͇’÷æ·âÐ6ÚB(n”Š?,4Àq²qT:¹7‘³Ä]¸\®/ÆUwCË>âÝ‹ Ÿoûkø½Ûûf×oóËöñ*lÎ.nGÚ]_w·áñU¢|ùö¿ùÜyÍä×”(ž‡76ï<>?ÓQ¯÷·Ã! ÅC¿}÷í·„×)ñ°ÝšfC( GœHfܤ„ˆÌ&h‚QÍf|ßäã c~L Ö‡ hª£ ô`~ÓI!Á¦lG"vŸTv§2¦“‘‰¼6œ!;:þí¸Ô÷ƒ+‡ç6Y]Ù 1dó€æÂ‰f·åÉì}>&•×+ú’Òè¸+ÁÙÍ™ˆäT3ÁîõôÇî4½¯µ6bo˜J$€ÖÜ×JÖbNƦOgR–‰ìåG¤ÅDòžßþÍݱ pQÃÌiÞRk=s¬²t:5Άzªó“ y¸äžÔªÜûæãGéø½#¸êQG§4ÅÛÂQ…° ¨ ÍÒT†ðêúþßý/¿öŸ£\ê¾ýݳwÎoâ³gãuüä}¼ìíå¦_„>ì Ö« ­»«?Zÿà­ægÏúOöO¹ýè)>ý9ü—vqÀÂhlÅV kFêÁŒAD¤BD’Æ tÛ¿Øïž~ôk° £!¬kâ-í|,ã¡`Ÿ1½ÕàWªŠ9¼aÑZÉO«ãO©À©# #¦$H¸bR%Rq´ÀyÓ.ìÐ&2«ZýW a hºÞâ óõBUuÔ=ð”$µÛ$ØhMNA¬iµÉÌAå¢ g L>ö5¿ŽÑ°GGC rƒÁó‡8Æ C« }rÝV"eÍj&ʵ›ƒBx- ƒBmÞ8ÄÑ-\:¢ólg Џ²Ø•0gtP?0J$0 ¼z “¢.(-¬ŠÜ‚R-Z2JBq* ¼‰‹ÈÔ<n¤äu«"«ÞC&"‰ˆ¬X&§à¨9DĪ2؈œC'x"œ}2\ CìÈÙJB“Ždgža-eôÒgÝBfP…²â.¶¬ ßõvë¶uÛ“%èdǬ†Dò¬y®ˆfh”Wµ–bŠ59˜L¦ñéÕKs˜4 æPI½.¥´Asbrìó!ù˜ëܲ®~p‡]ÍÉ9 ðà,5O‚‰ÄÀ¿…5§_Ñãÿ*Åï÷þG•Ñ‹Q£-ˆ^O“þzÅ‹ÕémŒ³UýÁú`vä±ÌÆœªŽs 5Um¥äÚa3‡é4gåÊõâYÀ`$Þ F‡BYDÚXÌŒk°¹1È9 àâÅ©øŒƒ«–[w' å,È€B&a=<ó‡†ë—œø}Äß«jîëúž|µ?çëQ£}Õóüú|D_Ï󔯟èÔÖ®Ÿ3OŸ8ÕÞù‘íÄL‚0V«…[GKAš(!4¡[…YCöz¿{ùö{«ÿü_|?rIå…qy!÷ÀxñÁòìëëÿ\ŸàÑwß§íým·Úø9ëEÖsÿäîWᆛÃ{×ý-ˆßܼYî›7xÓÜÞ K/o»óû_ïÆ—*î6çqÓóp³?ûIyòaww}ˆMÚ³9Éýó½õŠÅQvŒ@”³¥Qi(9ª)¦ŠñPî‡ûµt˳Mv“4ÄfEY†±ø¡@å†GÛ__bf´ã8:%3·Æ‰(C1¨¡!qÍž-¸ÄØumÓŦËÍpèIÜBZœñ£ËÍ›ùlµÖ~ŒíÁl?¦»ñ¾¤ÐH+Ä.fU‘+Lv"a†•‡ºv::º³fJë6JÂx{èy?¦[‘¥V¥_Ùa“‡PXxM«q(ÃÍ+ô9DÆÂlÝa¹ïά3:˜oûÏ´ÓÕùJVF¡œ¯ _KjW‹…Âóþî0ìï·=å(©ÁÛï\½uy†’û/—륬šná¹Ëã(Ì„0K*ˆH˜É}Чlþ9¯OtJL¦p3†ØC åAÇÁÊé`jN 8¨wK 9Ms¤%×k!‹%ä† Hë4˜ÝˆÔŒØKP`r°çšMU«îŒº`<& .º¶•ßåEF4„E u%6lêÉNNŠéÜiŽèBD"Äq“КçdNŒÀÌLª>Ù̈ÑkéÞš@+dˆÁ¦ÔJ~+È•‡½‡Ý8j®w Êb©55)*¸UገQ±óÓòPË›×I> ”AW˜ عq'wvD€YZ–%pVüÜøŠ*À{ö.p—ý†±ƒra2£¢Þ;Š•PZB€Ë£—.ÄŒ¦ © ÅK¡'2K1dE&¨Á*ãÒ5\ÕÝaìD*¤îÉ ‘Tœ R#"fg Õ4eæ‰|„gV1Dòè€;» ´¡X`¹˜!›Dc@R˜@d‚”™‘ª. ýïL¶}+¥¿Ê [¤ÞGE1X%ƒÔ]SÂ/ª¯ÃdîìÖ>»RƒjHD@d¨S,Hmps‡…’·‡óQ“¢( à’:#b0QbHDB=‡`£:'¿óŒè«Nr_uòþ=Ý2úúWª—c3S5U#ðä`u•Êó×õÙN‘šS[«Ã¡`ðÒ´…ŒÀ,L$\4ƒh i`fáh…†±‘.6’sÎ}vfdËØHȦ° #˜«U†MÑìǦ¨»6,MÓ0Ñ0 ê8D&…kͬ|Í\;ûIæŸÇ;œNÕþßê¾B]ö»ª×Ïýw­¾º2ùzˆ¿ëíëzž˜Ò¾¢/V\õÿN½z¢Z÷š(â(DŽQ"SÊCÅ Z,©7E:2–ó³«%wrؽyvÖúý?ûá·þâ/þü~<×g›…PLzŸó(ç´ï4»Å]÷è*<±¥-aóÙþótw÷¨\Déܱc½u=“îrs54XzçÑ#z–_=¿»žŸå—ë+Y\É;o_~ò³íЬî×t ï…ly^ìó}‡¼í·û„°AŒ`Cp‰ÔˆD£»  IDATÐo,}ÕlV+?ìR8Œ¬‹Gsu’ÐÄ®k‰|lÄ õl‡1ݦQÅ%évØ­WEÁ@‰ÉC$.™óX‚„Ų[vËBðP$a¥¼áÅ·ÞkG*ã}·¿z~€÷Þ;F‰D—¢6hÅ©¦±ÔrèaúË|Ì=7/ ¦]W‹xµÜÙõõzxÞl_ØÍЌ͚¹Eß®íêíóü¨Ùµ›¼‚¼{~üñGý"uºzÔ¥¶úqÁë@‹Ølž½Ú¿¸5øH±¹¸\¯/Ît12üã_ØßÝ]^¾„2ò~wp馩…pµÈ@$Lb“kž1ùÔ”*\iêHÕÚ ÆE2œkôâ±&¬@÷ã9H´¢áÌMA K V¨×ÄÌ3³c¸Ïƒàнš|b&Øe‡åäê¶yѳ‰“5‰ætÒœ¹Rµõ’YwDp£Rò\ó(´bdžgn‰ SEáKèi®»4±&QW#7ÏØ ª ñ’Ç×XhSçš­Wµº›}S~,‡fåv_¦î3v¨Z'“ÍùK•­<÷Îj!ê@EÉM**8ê(ºÆ@Ù\Ýù¤ärv·ßȰߦ3ü‡SÑÃ(íÁç,Ƥ÷2ŸÐî(Bn0`ïêPG4ýa· ‹¥ô?ûß±õÿüîùã±ùàý÷ë6tMŸä^W´xç|©ËÃr‹íýo~ùôúúÓ?ù7ß¿øöùëó‹Åùný6e¡¾ú÷?ùðן?MK×Ý=Ê!IK(Ò==`ð(ð ( „¡÷£CnJ†ˆ˜ÀU0W7ÓZq‹P$<˜UñœÁÌÄœÔY«¨:ñæ³÷Xh½^µ ¦žkm­B.Q8:(»ÃœL¡Èàšà'n ¢RŠ™’›Ðˆ{RŸ’5 (oÆRJ#­¨¼ñÑÛFƒQcØ` av6CK=%Ûì›E©<9§)©›3;Ù܊ήõ$V¯v''g@ ¹CnÌb,ÂS tf+F¨œF`$ß;:³ŠšYQX28™s/ð¦€(tL HkÔš†…ƒ3› AlÒ”Y ¸.ê¦Z#™ªÄ—8Y27WWv&ž‚ÒÌ.Ì 8 ×c0Ü`æêH(‰TÈÈȹT TÌÔJFeâdÈf¥Gd$P l&F®n Ø C'`r_ˆÉä€a@Ê(†â0'whå"LÇ%7¤sZ‘*n¶‰è:Qû nXˆ¸8›"À³p¶R‘~ “¢æ¦fßš&Bj€k §¬쮂°:„L@ `f ¡NQêÑYUÝ!Â"RJùZN´_ïý¿L æ¿EÅÄ$'¿+D˜zu.üPOñÔúœ`¯SkÈT'&M-ÎqP:Y7§[M5Ãk *jY‡<Ï|ð@uÇŸzœf^&¡ÓÑD?õß&¨#)ÓtÄrGJö ‚øÍwé ª­/pù~Ÿ×7åq~ï;ë×ô<ëu7æ1ƘÒb(ª!ÈT ûÔÓÚõpU!5"‘½äƒ¸-WËØŠ‚•„™Ìs.Ïî^í)¾¼ùì½ û~ò"$Îy?‚¥xß®šÍ✕†û!PŒMs¿.WýúúfÇͦiâjÇëýn9ŽOû~øè;o¿wõׇ_èòÀg]ë±Ù6÷»ÃÀî-ÇnMÒ»2Xß®ZiH]S Ƒͬï•,uQ3b îž³×î<ìnnzsÿ§«wÏ.–O×e>y´}Öõ/ÚÃŽs_úW/nðÜÖ|9K¢«‹Å&h;>º8kX¢ûþ“C‚nÓ>æx†Õ‹_¼zcÙŒ;Û}~Ú,Ûu­Oéz{GËæÍÇg´=rhdû&·Û&ÃÝŒfûe=,ª‡Ð¸«ªM|3–ÚML:“ňˆøX*¸tÌ»˜ ‡Žæa8LæV¨ž(ƒN¦#nÎ+ea4Íu¥«Úº-%‹3jêÓdy0õÙôró‡AÌÔÖ®ãZޏ©“ºØ-¨ìAÛý€«5TõÕÙKÇ:P”iÐ4÷ž@ö’{°+se¤œŒ’"MÕ%™Õ3)™gVEâ\IÚ\é®ndN"ÂDÄnŠš*ö”(×rô8)š) Ví T‹./Sz©3K<ºš|Þùld:R€©™bžJÕ3ˆ”È)€Ù¾2xð¸NnþYÇ]R÷^wr’)ªˆ\qP[ Ívؽ…µ—>ž·ùå_áÿxµû³Ç?ý×ð?ùîýËçßUzW·Ÿß†ºÞÉ…­¶‡áö¿Où—?õúÞmñ½^¾õÏ¿ÿ¾ÿ³;ßïqöHîÆöeÂ㞊µaܧѴ˜áØs(Õ¿ÈVwA.H •6HàhðÒL­h8c4éãw_>>ËvPö»í¸3Œ°ä%©@µ“¦”ˆáê°aÚ¬»å¦ÝnïFcÇ 'pä°ˆÍ:˜§Ã® Ü•É1¡.`& 8x*¥¤ì!pQw TšˆØRß; HÁ p¿<Ú‚7ðŠõú{¾{q8$mèUï%6Qš¤¥èàH†4"åTŠØT 9;\ݵƒm.‰möâ=¬ 5ç–HÕ•ˆœØa\³Ã`ÆlDà6ŠF¶–ЈF2uÛ/‰€MsƘlËeGÔ+{üpÎê¶×ÒÀS@Ø–*óË@ééDN)Œìæ5QJ\­‰b®ëQ!+:ÅÅ35…&ƒev Æ™,PºÖdsRPAåï»y6°›0ˆŒ /s* sN$j”ÍÊý°o`,žP¬ô eFø¨ZÁ\¼ôv§LÌb U-ÅÍ݉™cd‰±ãFpÎî0PuX‚@5ìyJ²vðQCɳã”ÙÈÕÕ\+¤ÐQjÌbŒî+^2 H8°PôÒ€ƒñ½1CàÌaLÃqÂpz¶›lߌ5í·ÏèõõϦžªyôbœ8SëÕA•þv’§ðúãµõGú«<‚+6šB4…9£’æ lG¤,!*¾4äÁ¿ÑÖºýÖ‚ÿHT˜¾WÓD3Žø W¥³šquoS•BG¥ ²l»¥ÄHaºŽ›e‰ëØ´jß¹|÷fûKÄýûO³å\²Æ¬ÅˆL™¬Çp¥lÊž_É/ž¿x+,^ós¶ůšO/Wïæû·xõè‚-šËrow/öühÁÝÅùå“Íæ±np¶Â¶ÇiUZ}Í,÷>È ‡³Ò@ƒŒbÓhÈZÔFŠ:êl´ánÃ@ ”Rbn‚3röI- 稽î,ÃJj¼MÊ£á@eGŒM· /7ˆMON\<;Œ„0ìBaÑvËår±Úô9mw{îû7Ö›Cw8´‡¼-dkÊiDoið2º'pU:K œÅ 07u57™NÉGš2æÿN 4Œa¼'Jw-~:~dƒ/»6ÝÍe¾]çÛ8Ü¥þPú¢cËÒv6A.bYÑAr…ÜÃç7¯lvy,/®Wyi‡,†Jý]–r!Bëņñàc1dM·»»Gâ²&ŠiÖ’s*iæYšuÄ (Q¨¡J§—JAÔ¯˜¸Î5ÿ‚‰ge›…(:jGÛàG«Í‹žNÕ‹[Mú©¦«_òéý¬`¶Ú ¦£+º>9Þû¼i§OŒáF4å¸:_Ëô ¡ö©ÎùÒÍ¥ÔÊ6ÍêÏ©I  Mš¦ZNà³]Ô«®§îD~¢?¶úüX+UKOE½¿aø’u¤*ÜhÚ¸Ž÷$›ÒSIgÊÅ\ уñ‹ƒó‰~è?‘8 ¼J“~sWú&Œ‰èTcø€à橸à 7e'Ÿb[È (ŒQ1dß-€Kíšäa,·÷<ÿòûïÿñò¾õ¸Ûíõ7ëŸâ}Æ£°øÕ¡ï oÇáî³ý>Ží4àé³›¿ýù_ýá?ßnŸ ÄØíýzØI[ºNÉ9·¡I.!dÓÑÕªw×ÓÃk )‡Ö¹¶b‰ ò6¨,P¦E{v¹Þ<^—>»52–=rEn€]@•âˆw,‘\ËÏà)›‰ Å­x!'ó?<€˜` ,ÂjTà™cŒ%çJ>!"1"CóäŽuƒ*c®NndŒåÂó•é ¸V, DÁä^¼8’ÑÁ‘¦È…êøëçZ÷ æ`w£i¥!vƒËÌø'°Oue€˜aż§â>ZÚ+‘˜Ð q$!2ï ­£1's-”ˆ{rc§àÑ”d ÄâÆÄ…(¸TS+ŸæÌáÓ6 œˆÝÌŠ»V‘­Y} ÈÔa 7ñŠÛ7Lé5Ô .€g ‘E3a ޺ߧmv˰5rcJj…au.L\WL«¸¸‘h$NnN– ƒ[¢SÇ Wc˜±U¼¹(ÌFÏI‘\1zÀYNÕó| ¦«6ÌiQtÀ&ï‘ÒÜ«QÌ+–׉ˆŒ„,:-©Ò¨ S…3˜Ìà ò0ëu‘Ã*"úÒëËçFómüË"ÍBp FïÕÝȈtªLè5!Ìlçð+Ò¢0Ÿ¨“yj:ãcÎY K7žÐ_ß„¾0ÓÿûGbÿtûGrc¢SøD­ŽŽËG­™ùÁ㘫*ÑÄîìÆ„a·oÔÎÖ¬b Á€”û±¼ýè·Î69?{ù‹ýzÓ¯.´ÿLmdf6W'!;´ñæQðØbpu~!†’žï)A_-w·»Ožéáã>úæûôöf}Õ=¹¼öêéO_üôoßxôø»ßþç?ø—äÝðòS}±·ýܾò±¡µ|éO–qý¬ßq`6Ñ\Ì™‚‡@ Ч}}ðƘYJÓ¦F#J¯j@X¶ÒêˆASb5fOðÞy +BŒ]Óv j–Y¨p0+jžMKð…ïn¯ChšØ-רnwwi¿i‰.=§rfüHºX°&hF530…€àn"³4R@¹f·R'À•¨V|ÕTÚ:Ä̵"›5p>j^PκG"ËÃ=å{Æ’sΖ‹;+qicjÛ,’ ]lÛÕY±Ã6«\^^ÈEh»ñóŸ|*IcmìÖËÒW¡i±C7ÅHTü£§O†Žƃ%ܵш5çªèÌ!p¯QBÕ„ùÀ2£Ó/ä¼ÚÍ/  éÄO¯' »1(¸ë4©ø¸)–•¦ÑÃj™‰"`sååpø±–@¥ËÍX¸ª=ó C7/žR(§²#y¡î½ü€S{mÞ^ãÜæuB2‡Î ™ò|Ê!…‚s{‹0'2åVšæM£Úª‡˜_ßmöbLø» š "P¨yÌ'w;-?â€ç"ÇæP]øä74«ID~”)ÐCÑ8«Y¾°™úñIO^¦ª¹`‘¨S¿ONŒLß´1у­T…˜óGº×éK5‘È€ÀC¯¤Aôj‘$íìcÏÏÈ~²úõîùj¡|µ‰iÿâ©-RÿÃõæv·‹Ü=Uþ鶤5ʇ‚ç7øùslû¿»LmD³¶Ö°TY¹šÙ8ê`–IwªE€ÎO:¶ÓH‹¦g‹ ˆðH,ÌL)@®…À!š:'μÔXuü 6 (ÆÌ¦&®SËF ´Zl8¸&w®à$ÓÑjh)g'5¸Á‹"Amp 03u¸ E4ÈHX8’5- ‘§T’œ¬ö¥ò-†qaãù"ã\©M^{ÆVŠõ½Q*l¹²/i¶Ð|yWy`=O¶{T]õø×¿50Ù$¢ss&g"¢Hž#ìÝ9o™×ÌAŒÝÝ•… œà˜‘™k¡âžÉF‚‹,Õ¥çÄ„RqÄd.DBÎsn¬š°¢þã`€ëI2j vr˜'URw†` ¯Rçi0OÓ}:M:êìSb­«¶{0MìîÅ%JÞ°/P7#Îf¥"v"àª+p+è-ìd¤…°x±D÷h`÷`.Ž@:¥¢é¤ZVšŠV”œxÞQ5¦(ûu“OðÒõ{¯Lfä4  f‚¹ƒ\ ÌÕ‰ÀÅ-:˜-Xf"v&'‚ Uúö±xÂôüÆœ»ý·ÿ݃ý¦™Ì„²×E=ý%öcöjò×õËþÿ6)Žñ×í´kN]¹ ±Ô¼üÏÝì¯ýœïðOUÑ?Î[ý\q™çà2ÓëÃÏ#,‡>¥ :¬8ÈÓr¹Ø´‹uÓœwËu³è¨)ªIÓ'Ï?¿8ï~öó¿íûýæró×ÿ×Oþâ¿ùcM±]…whu¼°îjµ:[â9JìÞi«©êÎ Ãðüó}?Ƨ·AÝ¡ú¦Óh"Ë ¹«Ã'rÒÜÓ<Î ¦¨ƒNºk•+KN³?gʱ¥ hmÕŽN4OÁâÚ­›K¦ã–púL¹·•±…Y|8ˆ0…Þ:Õœ(:úiçUeöÔx­rÙÝj8g-ꌪŸ|M6¿@ÿæ­¹ôš,Äçl,z}†Tÿ¡>ñàOþ6`€'Œ£ç>·k´--Ьr3>Ëo6ßzÿ¼½ÐÒúõåÅíõ÷O¨-ʸNvnM#±4«¾Ã8|Œ`ckQ ""’Ž vQÏV@_tR7ÁK™"u&üÉôJxþ NŸ»{@lˆÚر äPS-ép8è}ü¾ÈN¢6à& Û…àΦ,à+P$pQRq PŸ÷FȰTrЮ×BZPfÃ1\ˆš ±A1I*êâÎpf(\QŠLJJ¥@Hý¾fÔauò2I&úÒ”ÒÄŒUá&V 5+ìÙK¡Qi, L‰§kÃý(¹Q‡?È/je4óAPý@ª9—5¯Β@¤ÀX¥ìì~ß„A¸Ý­”}1#Ötít£~—ýàŒ\ ¨ ˜ÀÀΛ:Qs%?VoÔP'L`Ad„Œ G`W†š±:«Á²×µ SdÕ—_šNìBt nmmÉ^,}.FV@Y¨ø” E¬Nî(ä–% abw6ƒÜ^Ÿƒ˜]AˆæVDÙC´Ž hXžv7d‚:†Œyb¯ÂÜJMWˆÅbrØ„‚©M+s¸ÕõŠªtm‡ÖÅ^LÀ®9È@e6ŠWkÜd¢Éá”Úüš/ö›²´ý=¹7§i?Šù­õß<ˆ~ÉØ‘ãuÝÁC/ÿT_wLÏÃC ùëúºS¼ÝŒ¹Å´ùyyç˜}¹óÏYY÷OÑ?ÚŠÈàZuT+:_+‡ªÇLê„ßC­Š ˆÁâë¦Y6qšŽyɱ¡ Ü÷»_}þñó›gg«Ððå'¿|ùéOîÞù“oý‚y´ñÞ,†fE`Ê‚TÒ’BÜ¥r»ßŽ×Ûf«„Ò yÞ7; ËAÇûCÿIswØÊ·—ëDZ-ûÒ°7MRšQ_¾qñîw”Ã=1ôsÐýõýMêVïì•ÔsR•ˆ@D†<&£‘¨ä±X.0H©½-VŠ!6Œ¬¦Q” AˆÉÜ´,!72Dnš6È0X.žP±‘¸àµGÞ•[xÑ5›;§W}/ÙQ>X9ìÓ°-v]†;+‡¢sc7xÚlV^H‹hÈy¤4S¸!VX33'ÀLÑÑk±•4ï¯XTeËþvv÷äñ ý¨IE÷ ¥¤üìÅ6í/»ÕåJ%|ïQßxïjñxÕý£xõÁÕ[«x~3æDzþèRi?xVGPu¯3nÑ Ú ¢I³XAÑ2¢(©òÜ)ýØÝ‰B¥NÓ |™7T‘¦¤ gx%w[õ2Lvš¹Ÿg^jù¸#ÃTùx^ÿâ¢ç0”BY©PæpƒóŠž¼ v¤†Ð×Ëáõ‰ÏÉÊüÚ¢.SëD”žãjüÜÜåšæ*õSóy:䕬 p™io“BÒ* Ï@Õ¤ 0!À'ÎIóìˆw8Â^ Zµ"bwší:•F¨Üs€Âôœ‰O‡'ïàCeX·`ò“d¡Â;M©²èTRˆ(ÖD©šÅåsýohçþÁ·Tçt¢<+íANJ@˜ejMŸ­/ð8\8Ä@ËØ¢d†a¯8쇡tר¬Âf¹¢3Þs&ÕQÝ%`\p<‹ÄdPÕ¢½»€aµEà„1«ïÕ¢cÑ\ Gpä6B ă‹õ`®š#œÌÈ«[ަ@eAêÑWÙ3!À pBrÉÞX¢ÖˆÌad  ˜&*JZÀå¸ny…ßÐd™ ¥£Þ–øA–Fp$2Cí¡ø|…S…=*¬æ¨p->ÛN°23ÃhØ“ù p£xi¸C…“X¥ x Ó IÂ2/I2×à¡¿*Ñ0ZEÐ2" ‚àPG'šB8˜È&? ƒ˜&% ŒÔ¦ÅÂaZ‰ú Gdi͉œÔÙQÔMaF!²›¸ñÔžPÒÀÈAÜ#y‚1‚ÌÉ+É p³T×`À‚°VŒ…!:Ÿ•êÈŽâžœöæ“ÅË­R÷*lZ¼©Áµ‹A4ÅÚ»U 1¹3Ïçk7r¢bpPD ÔÈê©ËE2õ~±’lšÛ¿®v¶,f3äLüØSÍÃa®,dBù¬LsóÊžðÖ˜'9S»œ¡yýxtuI%ŸM'ÍAÀȉ8€.€€:#òcCë¡UQû‰q~õašDMY!'*Œêà®â>«›ð¾5˜žƒ»Nj„ÚßÊsy%^TÎ[9Õ„Ï­À:Ö£©û]väî•íD'¹Cõ}uE9ù8NS§h U[Q%²kØN óru$œ×Ù˜ô®$òyÏ}ðoN]H;nâ@M—*sš,Â¥—•¤„ÁP4튈 õsûѯöãGÀÇ7ø.ð½Kô¥ßÀß^\*Ÿ=MwOÑ‘vÆ@Ãí(ë àK[]˜uŒ …vg¿˜6@Äó9¥WLÔKTÉðQˆèåÈø¿"úß•Dè#ÕæÏ;[×qÍ¡Xñä©MŽqHçóþÌÇÙÇÑ|„íè6¦”Òy]YÒ4–¥ÞÝ*ÆñÏúÛW¿¿þÍïÆtp¯ùñáéöÃÝíÓÇa¹ÄpusÅǧÝÒ˜ù‡Ïã‹·û7‰÷çï¦ÈwygÆ9îìðÍò·Ÿûǯ~õå—ùDZ|½_ÿ:•õêíþÝ¿†~zSÎ]Æ«ŠOj>_ýf—¿»}üú±–^K„‘Û0 ˜,oµ´Z †»Ãàr)B+TjÕ²,ƒæ÷”ºª *£’ SAdVš&·q?_^Ÿß”û¸î·ã±BãŒÏÞÝ\üüz³5]Mó›ýAÛöˆoþòP×%cÑíö¿àZ‚Û]LGãj)¸3.fA¬°B«&ø˜ î`^Ö¼”ÓŠù™¯ Z#À¬Õ† ¾¤m<˜+¶ðĬe·ÅVÅ`È^·л_|>\øÙÛyœTž~X¶‡™õþ?|ÏO.¯í›»º|xÿí£n>³‹ÝûìÎ}—¦ý8û|a颸Ó(É‹__^k††^ýÙLçNÐÌ~| ö”Bê‡hwµÍOÛ¾LšZ-c{R½!ž+[2ñŠ2‡‘\Õ Uö °f9ÝòÝgq9Pbc´_:"Oü?ü%&¼p pŠúDsÈ4sÍó._=Ô8ã] 50oÓ‡§9W³¥Ñèµ}Hé™NîMBØkÒ£›ðÉõ‘"âé65½$Ô¶:è®;(q§ —> Fvƒ÷Ñ3õ®E“£ªS.µ€Ô:¦ìe,wŽ[O@ñ¤‘¡è«¾ŠˆˆŽ…àO¤®õÅ8ÅWÜ$¾Jåt,ŠEû9íTRTŒuH˜œ(†5rik™L°‘ºbyÿ~™…#ø€³oá×à÷Ãö÷­^Çú¶àüóãt6Ì?ócžñíß=äG Ÿí¬ë0×!ëz¾´àÍEºÁîq]«´›’¯©,ÅŒîîb‡!’ÑÙ ˆ–Ø3ÕŠ •ˆT¶"D’<ʶJ™Ðfa^¨\ò!¯Ç\Jx‚[”¼¦7ãx. 絪ãå“Á=%’T”µ–&„‚CK#Éd>î TrÑ–#GªHEÝÞ×xËŠJÂÝ9MŒâN£M+Ýa$‹ŽÁY™çZ2BˆÂ’C T¡"+°úXôž ¦êœ­nÁêÒX§°6eIý\¥6’Šˆ•=o¶ ô„²Ò"y&÷U÷Œ[ò@®Ý$ YB XÛC}@½]Õè͵ìêßb„9’4ÀvÐ^<f!¡5"h@¨v,>6!Pe´Šhô™S*‰ÏЕ ]JŽ!X…$0hp"iÝrÖ3ЂU O0“Ü iÄŽ˜Gì.Çë9í&OQÕ€¬õ±ú,ðÀl¸®kòJ¼ F™ÓÖБ8Ö8döm©5‡µÂ Vtk± ;½`Ìú Žý #¬U®§2ØÁ š»¶éÖœ^AµËæhêHQš›gDIEND®B`‚GoFigure2-v0.9.0/Resources/fig/Myapp2.png0000644000175000017500000000124311667757442017771 0ustar mathieumathieu‰PNG  IHDR szzôsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÙ;Kö\ctEXtCommentCreated with GIMPWþIDATXíWQ²ƒ0\Þô^æfÀÍÈÉx6Š1&Q›™Žm£²°ËŠ$€£³Ø»Û¯×çÍÅJ„·àw"Û×”R÷¢œ3Ìì' BÁ Ú5p‚\ìK8 €” ˲ÌSÐ*i¦ª[‰Áâ$ÀK– &`æwˆÁËrö`æ(cÆH L|)õ3€ ˆ ç| .ߛǺÀ: =›Ö€Õ5†”›*Éï¨?çÜÔÃ'žà¤î”Ì ï‚*ÕÉÆd XüÄÍQÎÉÒž¹¬ÿ—²:ˆ¾Õ²FWL‰pYø²—ý’®‹rvÌf­ö ~f:9‰qÚŠõÖÞÈ¢oX9ôS ^ÐÙÊNpvæ²ênUïlStTw-Æò¿§¯’£×;û$}ñ)Rí»ß›8bÖ5Rj‚ÚÚ·±w{ ‰ŠAoyïZ~¦úÆÑT,ÙÐZžûx$+•(Ç– cöWSÖã ´:ddç?JkaÖ”aþ¨ivÄÌû÷6óœóÁZ9÷ÓÛ>p¼ ¡föRÍŠ?¯)AE»Á{ÜOh=Y•VKnÛ1$ËxpèR ªßI_6!™Ù&ºÚzã *â˜!·  ~ºzøË>æý–güþð^$Œ;²žî‚òv$FÃùº½þξ)?=›š2IEND®B`‚GoFigure2-v0.9.0/Resources/fig/C_M_L.png0000755000175000017500000000700311667757442017535 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA± üa AiCCPICC Profilex–wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû¥ò&" pHYs  :èÝ™ÞXIDAT8Ý”]l“eÇO;p‹0Aׄñe¹à†@¦L‰Î`Є %l€&ˆˆWº “9]Iˆ¥Í6ùš ¨a#È Ý÷‘e Z6V˜²LØfÖµ[ûãY—µÝÞ&Ìxç¹yÏ{žs~ÏyÏ¿§"ÿk«¯çÙ©~ >Z"99z<žÅãg--ÙÝåt2Ÿêl<<ñgÕkZ_w¥¸S>ž:øÄ¶8æÎëERÖ@wW<êœ{TÁ¢ÒåÄÄòÖà[¢53NK#æâœ£ùžÔ÷^4Õ‹¤o±wʈ ‡ûˇÇ6HOË5Á¯“ÄeO´±ãéÓüø·šgÀý22v­:w­^ÉÞú­ˆYìU7ìÒêÒ©lÿÇyòïFë:+,deu5wœÎˆ¯ôÀÎÏp$èys‡`],$íbÌ3ɾ“¥æHPÐ ïhàf3¯(hŸW 3Ùšl,Ú?ƒß ž™B›Aø©*grMM¸bíxI u.—&—bW1†‚瑯„„#ÂýD%樠Æepù²¦@…òò"~ç ¼¬¶êzä,N qæ8$SÍó[aÇÍí îûôú1øÂ… D™løÔ2­uÞÚÊKµµÜ¸ww,u}ãzäs!þH<{âc88Oµ•a¸Ñ}}!öÕ«ø*+9®6Õ:v;KkjpÜS®kXË‚¢””… ƒN ¹¹cðøx¸ÕͰðÊFòóÙ:ùò»êÜÖèíÜõÇ7ÜðÙ'B#ß”R$Í᡽ŸK5Ü´ÙØɉê×µ-ÉøÍrßîðE¢4þ]Ó/”[n5ù5ó¢‚4A$vöÅY=«Š?¥û¶† ´_è¥3=oyí&M½ hVz4©TJ“’—$?³êm~®¹8ÐÛ.õûEZÛTaV¦iûqyjîsÓçaoZØ {18?zq[ú…) ºOb†ŠŠ 5U2Eª«¥ë‘N²7,tJ ¹Dt:uÕ°S§ø®¼œk&Æq Vë ::žü'4^í©¶Bçp0+ÚY´Øc·iÎÓd"IEND®B`‚GoFigure2-v0.9.0/Resources/fig/UseDatabase.png0000755000175000017500000000141511667757442021006 0ustar mathieumathieu‰PNG  IHDRÄ´l;sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚåh ’IDAT8Ë­•±KaÆßE9Mr ¡Fœ‹ âZ\ÜR!ƒCôî0£ÐYˆƒˆ]Ä,÷ ‚tÔ‚‹ƒtTšhDÈ ±\0ÆrIȼ’˜ª1Ií3¾ßñãùÞç}¿ÉÄOZÑÎȨ›1Œõ i2›Lˆçuå=P€Œa°32ê¶ ~ ú\y/´>RWþ´*½®4‚. Áo)iWU¸ÒÈ©¡ë|£}ISÂ'¨·×®oJÉgàƒ®×j¹\ÇqxxxÀu]*¥ GÇGðô_:Ízjè:ߥ¤z‰D¤P(àõzñù|¨ªÊ}þž‹ã ö3û¸Šû踕 L)IßÞ’½ºÂ²,zzzÐ4 ¿ß¦iôõõQ,I&“LOO£´š¾¡ëØ™ Ùl!þ^4×u)—ËhšÆðð0ªª¢´3RŠ¢°¾¾Žßï@EQðx<ضÍÉÉ óóóO=n¼½½M¹\ÆqlÛ¦P(Ïç±,‹ÕÕU&&&ØØØ #hš´êÚ¶m,ËbllŒb±H:&—˱¹¹YûfjjŠËËËÖÈ-Ç0tƒµµ5|>ù|¾6rÝÝÝ8ŽC*•âðððiŽ›Á¥)IýHøàúúºÖ†J¥‚mÛÄãqÂá0§§§O+=›Lˆ i6„ê†NW°‹™™¼^/½½½¨ªJ©T"‰DXXX`||ü1Øçýsçò«D>nÝÀÀsssD£Q–––PUÇCgg'Žã°¸¸Èää$‰Dâ%¸^uZÕÞÞ ‘N§¹»»`ee€P(ÄÙÙÙ뎛­øîî.ýýýÄb1¥R‰››ÎÏÏÙÚÚ"cJÙü¯orK·m¦?Ñ~YeùòÕ}IEND®B`‚GoFigure2-v0.9.0/Resources/fig/zx.png0000644000175000017500000000071011667757442017260 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA± üatIMEØ "rnlIDATHKµ”½NÃ0…o… TÄO Q`BÌì]òôQ¢îݳVÉÚ¥Rai†ŠÒ©S_‹+'i”Æ¡‘Žòcç»ÇÇ7i½<¿}}ÿµ¨™Ã½œ›SâõzݨœKbjgàC¶…:|^þyâû¼BÃõ,Œ…·ÀÚmÑõÈóøµßgEj5ºHÕªjq¬€Ðûpht‹‚ðÑæ¥2aR<Ã?€ ›§£€Û½¢€»b¾yØ*IX1u±+ªÓé'ûþdKx–e¼g ±ä(Jž7b¢Çñ¬W3Õn­Pµ‡á\9±@I²²p^ÈÛÚqíOº¬MýŠq8.ÎS}|rý&©×c¨PÏÑQäßQ`y(†¦çB~Åx0tš¯ªbIEND®B`‚GoFigure2-v0.9.0/Resources/fig/mouse-cursor.png0000755000175000017500000000043011667757442021264 0ustar mathieumathieu‰PNG  IHDRÄ´l;sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ4ßJ˜IDAT8ËÍ”Q€ CWÃu€û8Pý‘D#†m‘h?ùxéJ7´Zd…6Y¤GpL™1e.qLR¼ði^¸*c\ýyV¸©¸¹nZ¸«Ç¸{Afð`¸À°Õ—ã3LD¤Õ‚V úûÈyÐ@I^\Žœ~w„Înûø}ô¥­˜Fh=ô1e’¼MôŒGÒfÜïf¬Õ%¼b­á²™IEND®B`‚GoFigure2-v0.9.0/Resources/fig/VolumeRenderingIcon.png0000644000175000017500000000347411667757442022547 0ustar mathieumathieu‰PNG  IHDR×c,ÏgAMA± üa pHYs  ÒÝ~ütIMEØ ʳ°aËIDATHK­V P”×¾i›Ô˜ÆT¢­š4M2švœhM3 ¦"I‡(ÔÒÀ"RÇá±avÙeY`ŸÿòØ˲ ëò~³ò\ ¢¢Ikb¨ +ˆ±N¬}¤­~ý§dÔµÓþ3wþ™û8ß9ß=ç;÷‰À×É÷É×|ø;¹ýÄSä›Ì¿k’Ü ÙLÜÞðáþtõó<žœûtêˆãÃîé›×_XK¾õä ò¯³³ì<üàpß@ž§½y&l=YãKȪŸ½ùæKïS'Údš åªCóšœ §"Ç>’'2dËwoøÁÎd­7!ßeÎl!dõr6œ#÷N¼û*ùíÝ3™´3lªs@t¤}×®¨-¾Ñ5±ŠÊqÈ,ÌpD&6Ù"…ƒµEœ.ŠæÇ r¼7¯]·,ð¿õzÅ>¿}[¬TùgG¬Í(,û¢1°K¦U4Šø<:JÝ8(Ý1˜­Cà)O@ „Íâ¤é=D釨ÓŽŒÌ6Ôe©/—„Ì¡Ed#J‚ÞÅ[Jo¦Îõ’ìp‹ê{åºáÛÆâ!TØO¢ÎÒ £é7(2 ¡²öê«ÐRé€Ôp ¥ªF|@} qV;iæ?ÉÄöQVu·OXÔ¦ZëûÌ>T«™ÅWéb_µŠ¸ýšÛ°?7Íz¼YjBKA*T5¨‘—A[vŦ#i°¡®¼­šãS¡ŽW‚¥qÉdfVpµc9°ûd9e²IˆPoï—e²Z]Ú‹ùêi SQ:y™(WØPk¨G7›ƒöˆh˜@)ù"­eÑô>ýØMb¹[èðp#«2òÚLùµgÌú.è5½°h[ ÏkC©õ8,Ê*ØUV4Ht0¥PPH¬…ŒþÿOÀÌa&z:‚•a»¶o2H+‡„EŸÑh}Z#õ¡´¤ùj'ò$ÍÅÜÉáFü_€—<éjx÷Õñã`ö1ý—ô»Œ*¨æh-'Og'%mÿ!ýæúolü MV5£'ŽIEND®B`‚GoFigure2-v0.9.0/Resources/fig/ContourEditing.png0000644000175000017500000000262211667757442021560 0ustar mathieumathieu‰PNG  IHDRÄ´l;sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ JŠÞB"tEXtCommentCreated with GIMP on a Mac‡¨wCäIDAT8Ë}•ylTUÆ÷½7K·étZ(R(e¥©-‹X «„pc#B"1$ ÿ˜˜BBPŒÄŒb$ "1Dj(e­,PJKYÚÒaÚi;õ-×?fiS‚_rs_Þyï{ß=ç{ç ¥$)å#—eI¢º ÀÔ©å @gçW®t+[—¾¤0 ZêÂ0­Ñ1¤‰D!À® ¤”`ĬêšÕ¢¸8WVR­eI¬ÿQ>zÍß´5siIõ3?íþþh××;åõêIò#Ø«uuvÄCQÓ’¨JBÙH<è Ñö l„"ºÒM».Vo¸ï~lþÂ*çónå Ïêy/÷T¬õ¿hàŠÖÍÓš‚ª 3úC:í]ƒ²©ñ¿LÀé ¸´P-ÈË4ý}!Ówù¶Ý¥IG(+ONÈÏ2*'çjgU³)fª3*^ãæµ€Ð.^êÊQU%Ðz«úæûz›?¢™q“Ì¡(Ó½nÊçM¡²j’ðæ:E9®Hÿ«éŽuþt½}yA·VPöV0Q¿Çîí¡¹ãH¦H¹âv×»öœŽùÂq{Í’Ç©®( 2Qã:j–ý¡ÂÞõ ññúZùîÆåô—® 4nýlwú¹tŽ Çd 8ƒáX"ðbõÆßxlƒWpåJr .þ u,¦N+K¿¤¤Ž<Í›+²Ý2Q¤D“?ï##œMàžEBð:üٞϚÚ-ú4¯Ó4BAIeùÙvÄ`„ûñõô'óüpÇ›ýl%c<…¸b„º9Ühã k ¯<7×fSÖ¼~o…¤xU@©ËAcC;û]• g$2e&OõƲrÑ‚2\@kqæüžÉªÚ÷ŒÊª"!¥…aJfLt£‰dËB°jå“¢+b7-õTËY9Á-²3léµx¢¤hðwhnÆïS8äËeo.˜­)˜¨ªÆ7?69€˜’jèž<'ëWWie%y;sÛ¨«o—g¯ùd4b3,tï‡òà†Â‰NÁo¹nÖ,ÿ@«š(Éo\7+®b` ‚Ûå ;¡µ;(¯Ý ãJ·îŒFl±,û¿{Ÿ??DðËw¨ïèeîÛÛXô„—òŠBaÏv`6‘˜2"•†‘s/…ž@”š:å[½ØŠÝú'[ÖÙR±ã‡в ^„´P P“"X–ý´¶ ‹Û‡sÁ‹¡ÃB^zGÞy‹Þ¾."-×x¹~¿mÂÐcfÜdÇ@bâÓ¼ôÜf>kha-/ £&pæü·ìÏÎæÖ¤›e–Ýñò²µëœ%)j›»‰ œ£¯·¡ÚÄ+é»É9øüº«\á¶™Ù@˜ç.9)Ï<2ô5»3ÏùO ¤ÇTA+º\. ƒÇãñ Ó鈉‰‘”JåÃÁ²_pêb·è79(=ø;⟒Gæ… ® ¢T* ÀívAII ÑÑÑ’$I÷ŒNÞ#VºV"C•¼(Q:w®^Fôz= ¨T*L&7nÜÀét’‘‘AZZš¤P,Ë›bÕ)­i¥5B!^+:!NŸùBX­ÖKB155%ÆÆÆÄâ ‹ºº:ÑÚÚ*¼^ïcÕÆ‹¶«mî&uk8#]7±«ÃñÎϲÉmfxhÙ3ÇæˆHRRwñfñá…B‘ÔÐЀV«E§ÓI«ºB–ýtfhºÒNÇÕ&Ú†,¼|`{¶„0ôÃyšî'qÿanm;J“=ž“u—(*x5é§¶6 Ájµv-i¼˜¸°¹Ç™pºÈKßÀœ¬` ·¼Ì4ª*¡Š|–½o”óÞ55NÒã|Ó”õØ÷„ë);VIVV---dffJÒÍÛwV|ýÖ€ŒCå\ŠmɇÇDÐüŸ8˨ÍO¸d§õ›z:Mnfv'Ä3ÃÛ‘×9[sŠòòOÐjµ—-K¾²ã?U[V´Â7ÂGqq1”‚ïŒ L¿1ÛÞÂ_Î?IÎ=Îä]‰¤{9qè2¸:ÙµJã2 €Àkª«$°‹h0¼&€†ý``ø4üãûýˆße`ààF§¸ƒ¼²&?;«.ƒl°‚¼¼Á&`ü\ 2dà{¨Áï¿CÄ~üe`àd:SF”G”APPÀ—ÁŽ<66vn&fF1`l]üýÄå0ÀÈÈÀÀ 4 ÀðþÁÀÂ𘙕••—Á6øÃÇïÙ™s ±²SÄ``*¦i¨" ¿Ø*9˜/¾ýføõã3÷ïßß2‚"‹Á6øÎÝû'쿽fä{äj¡ÿ :˜€³2A,àæËÛç ^=bxÿáÓ)\. p?xøxƃk§8þ2° æab`xó1ˆò9Y!b߀aýüúI†kW.=øû÷ï.\Øàß¿ïÙµkײï.0üùýh7+$L9¡ @ÕŽbøöâÃéã'WÆó®’ €˜ ‘ÃÈðèñÓœõ«–žz{í0ç·ïþüýÎu K@AñòÕ;†c»¶3¼»w†ÁÎËaNUyZ‘žò!`¢Âf0@Á³433Óû·n»ü´¤ßÐÐ NJ^…‰‡Ÿá/0°?}xÇðüÑ=†sgN¾¹yáâq Vv‹ŒLAåLfïù3”b¼ôæ§Gȸrww—l ÌtÞéÓ§M”ÄDE ™Y˜ùß¾}÷úöÝ{ÇܰªŸáÿûX·çŠez¢O30ˆˆ3¬Œ:r5ùÐ3`þy+„l°€€ƒ££#Ø&á›7o[ðíf¶Tò03D˜x0.‘õaf0×d`”bX~ðRæÑçÀüôd&@ÃøãÇ ×¯_‡»˜……RŒb Béû_†û·þO¸·õý†S7 ûCÂr;½^ ‰ÍÜÀ⤠€˜`nÞ¼ †Ÿ?‚#„±VPøA,X²{ûŸ¤;ÛÞ20œºÅÀðæCÖ"ãYži uÄ‚¬éÁƒ ÏŸ?FØ_PùŒÕà‡@, 5˜¤lÙú‡ÉƒáÍ, v&æ_<_^ýøû¤ €ÀaŒËu¸\<šA1ðä:F†,m3ÖÖÝ÷ÿŸòêoüïÿÿ#­*S€J¼H¼¤õ)IEND®B`‚GoFigure2-v0.9.0/Resources/fig/LookupTable.png0000644000175000017500000000073711667757442021051 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA± üa pHYs  ÒÝ~ütIMEØ 8qnIDATHKíÔO(aÇñÇÁJÉÁlŠÜH‘ §Í‰EdÝ(œÖ†M[ÊŸÛº¸c—µÄ™ÜŒâêß…¸Œï[ó2MLÍb/l}zwšß>=ó¼¯Èÿ''Xª”øöˆ˜éˆm”uèA7ºÐŽ4 !T ˆ"1Sùb.‹Äß‹Þ0$ùò(–õŒ;\ã'ØÃ&ÖÆыN4£eb½е“'Éà‚¸©\á GHÛ¡«¬ vh„µa´¡! .ð ¾äG§®à®çíà1ïà­/+6íàCÖ”]ñëâwƒU+tÅ:X·bš{¾+¾ç!ÅÙã Ö/ïW{ìž Ýã¬Z¡æXqV¼ëcÜJ·€XÞS¡+v÷Xmß/ÏÙcì·¬çXmiü„[ÜàÇp¶#Êõ$ô–6øÞ„”~²¥Õߟ33‡¢˜ÁÆ1ˆ>„a à ÊT¡Åb\‡PNŽÐ¿û'oñ·…ãý/IEND®B`‚GoFigure2-v0.9.0/Resources/fig/document-open.png0000755000175000017500000000353311667757442021405 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA¯È7ŠébKGDùC» pHYsHHFÉk> vpAgÜÅéXSIDAT8Ë•ËoœWÆçûÎ\퉸v­xìºn’Ær $F©*Q¢\‰¤zB°DQRY",º`Aÿ„X²bªM¤¡md;عԱß&®g<ãñ\¾™o¾Ë¹°‘ŠEé‘Îâ=Ïûè9Gï+øáuˆbÒiÉððaž_ý5NØÀ k-Æ÷Â…™?LMM½xíÚ½sçÎߤL,,--­]¼x‰ùùY¬µŒŽŽR(˜œ<Åûïÿ ÉT޼ÄÈî_ÐÂÉdjòòåËoLNž”/~çÊÎÎΕ……ÅõO>¹5Ûjy7Â0ü¸ÇJ©ÿ*=!ì Ë–O>ŸŸxõÕKår寿þZuaañöââÂ? ïªï·—•RÞƒc;Å G³i´qgΜýv:æÿahh¡¡Áóç¿9ãy확••wggç?¾wïî»Î‹¥t©•Š8&äpÿøôôÙ¯ð%Ëõ0=}ƽrå'/;vâ§k!T}åˆ×QÃa„žÝõ³fækù驓LJºW JZ¦Ù1x¥æÇT[Š—Ÿï£'-p]—õõ VVÔdO&õã /Œ¼ýÌÓ™¡ñ¡ž‘•Jd~ûáé_.<Êýîý§.}º©Äž_¡ÜˆØïb#HH—tJÒ›Irk¥A½XàGN‚›avv>(¶fåéヿzkæÄ ?màx¾õ³÷ÞË9wrO¯6$ýYÉs£½LJá:8ŽƒÁ!•„r[ñÙê2¾?Ž£ܼycG)5/ßoå$ô;à½IøîÛS™(VÇ¥µ¤Ò :„ b‘¼b'I³c ‚¯^anîÖ°!µ×Ø<3ÌYAGA ¡Ú¯ésøP––mÁXPbÝ5´dÒYjÀ÷#ÖVWÌÒâíÀ©Êz¹ZØmZz¥ C, ˆ5ãJ”u ª D®;Z!dÒ.-“¤Ö𘻳xCߟþæ¨Ó|xc­Ö( ¡²„ :¡BJ‰±]·ÚtcxA;?ê6‰4Û[[¬ÊcÙÁ·~óqûMÙP¹­B¥m²="ÔY0*"•ÍÒŒº®aÜunþ·‘% {¨Ÿ{?cSÆ–n×lóÁ–4©±âv©æŸíé X uÁz=$ ….„W€  ²Ž r÷_u*YKkù£ ° ¯Tß-UëÊæ{´ëˆë²é˜‘ÞO÷ú² ²iI"áâc!>xh‘€µ B!F‡ÄÛ·þ ”$Ï›û{µš”Œüý¾ás†ÞÃÖM³ÙI±iz9é“K ²IA*•À•)œ” °Õ@{1‘'S-EfïþÇ€/IÔö›Qe¯ Wç(ˆ,Ö5h!SãH:ª…ôc\’r"m‘•çÎå~iýë[÷ºcÓ»—Kù‡Ëx¹X2ôö âŽÀ µF;è$ÄR „D8c3mPÛÞxaðHާúްôà‹ÀÚcaŠÏm¬ 6vˆ}@`¬‹Q µÀj0)p$¸\ ûÛÆ<(+Z+[Ô—?5ºtû&°ß]}_‘86öÊ/®fŸùÞDuÒ½ S!´‰ÛûDÍ’½r¨¼ízs{i×x¥½Ø¯íÙön™hgÝüócÇ‚þAG8ôÊÑó?ÿ=‰á ¾á¿ÔVÞvC{Šª½ûy않{ELP¨Ð9`ôä’“ýŸSâŽóUb¢*°wÀúË }€ÿÙú=çű%tEXtcreate-date2009-11-15T16:08:44-07:00v–ÎG%tEXtdate:create2010-02-20T23:24:48-07:00+ùã%tEXtdate:modify2010-01-11T09:19:17-07:00 …&¯5tEXtLicensehttp://creativecommons.org/licenses/LGPL/2.1/;Á´%tEXtmodify-date2009-11-15T16:08:44-07:00)'¸stEXtSoftwareAdobe ImageReadyqÉe< tEXtSourceNuvola¬O5ñ4tEXtSource_URLhttp://www.icon-king.com/projects/nuvola/v=´RIEND®B`‚GoFigure2-v0.9.0/Resources/fig/xyz.png0000644000175000017500000000067411667757442017462 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA± üatIMEØ "rn`IDATHKµ”¿NÃ0ƯB *â_a Lˆ™½/ÐG å)ºô `eA*JÇ.Q™è’W`㸳¸Ô1Žs…`éd+¶÷å;Û­ÛÀ§ àã Í´ø€8§»€yž7Ñ! ´·Ã`èv‘ƒ“¿d™'áé&¯ ËïÀµá÷£Q¯úÓ Ø…ÚpV²¯V1o¶Ó·ôW©|L|›ÍÌ_<økÅn‚×éS<÷ÿ`¤6#özˆ”´TŸÇ®bVÊV¼/x×ï—3œ¡óùú`7Qa…@—KD{!@J ÓÚ›éõXÀ¬ø‡ß`Ù¨éKŠ}GIÔr¯ªN… Õ±WUÁó+‹7ÏVë.è;ƒ¿<‰LÃ<©³®IEND®B`‚GoFigure2-v0.9.0/Resources/fig/PosteriorView.png0000755000175000017500000000642711667757442021456 0ustar mathieumathieu‰PNG  IHDRÄ´l;gAMA± üa AiCCPICC Profilex–wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû¥ò&" pHYs  šœlIDAT8Ý“ßKSaÇ¿ï9gg?tnËg’騤‹t’:/Ä /Ý…7BA]x±° ZIBH7Þy™yÝÈh! Á Ç´›•åimg?ÎÛ{6‡s;Sê¦çáyžïçy<ðÑãNíO]ã×£9š.ÍÑÝènt%´’ô=ô©ód^ÑÓ}º`ósó'ðè§YÊBø|2+¡¤Y¥ªÒìjÞs‹ã·ÇY£"¬ô¯ Æc|†ýäl&+S£©3•NY£«Ç”F¤É‰|+É©aú±Žg ½¯{—è(J3½{ÞëÝî%~†W¹•>HOKãE›+õþ—»–¿ìÜÚ¹Ór¥åšP!GäIõµ–ëÏ ÖìÞ3í#íÑ&‚˜IW(rÿ°ñX=G¢*"O ü*\èžú¹v¬é·b[¶ 2°8-è¹×S蜺ÁÙW¶(¥d{c{PI°VþŽè†Âe)8õâåAÎȰ uÓ¬›Ålãê¯U®ímÛå·r_+i»h .…x¹¶:8D¿FÇ\qW€n6m´¯Æöcޤœ´•ê¸Ü±916ñhså\èˆÖÇ<51ÄcʺÁNÐdjB†fÂ’$7œ3k—Ö’T樾cö¬®Î÷‡‡Oä¬ 0¹Ýkǰ{8ç‡}€ d HÅýë9ñO^ß›¾—ìýª?QTX5ÛMÍ©ýy“£²ñ¿ˆŠ-Èv:ä° KÍd×QdëÕͿțoÁíœÜ|F!šWƒ¤}·Èõ$òøóP"|ògá5dJrOðÎó\[Ó8…à™ .í?=’úYóp¨WYÒ£‘¥YY–HÒGœžÔ ó7bìëqˆÿð/)ÎZsª‘IEND®B`‚GoFigure2-v0.9.0/Resources/fig/EyeIcon.png0000755000175000017500000000731611667757442020166 0ustar mathieumathieu‰PNG  IHDRóÿagAMA±Ž|ûQ“ =iCCPiccxÚSgTSé=÷ÞôBKˆ€”KoR RB‹€Ti¢’¡„@숨Àˆ¢"‚qÀѱ"Š…A±÷y(ãà(6TÞÞ}³æ½7oö¯½ö9gïœ}>F`°Dš…ªdJòˆ<6.'w T €@˜- ‰ôàûñðìˆøàÍm@n؆á8üPÊä $ ¦‹ÄÙB¤2r22 ì¤t™%[€j;e’OvÒ$÷¶(S*@£@&ʉÐX—£‹°`(Ê‘ˆs°›`’¡Ì”`ï€)d`¢ SöÀGEð3(Œ”¯xÒW\!ÎSð²d‹å’”Tn!´Ä\]¹x 87C¬PØ„ „é¹çeeÊÒÅ“3€FvD€Î÷ã9;¸:;Û8Ú:|µ¨ÿü‹ˆ‹ÿ—?¯Â„ÓõEû³¼¬î¶ñ‹–´ e €Öý/šÉÕB€æ«_ÍÃáûñðT…Bæfg—››k+ m…©_õùŸ _õ³åûñðß׃ûŠ“Ê àƒ ³2²”r<[&Šq›?ñß.üówL‹'‹åb©PŒGKĹi ÎË’Š$ I–—Hÿ“‰³ì˜¼k`Õ~öB[P»Êì—. °è€%ìäwß‚©Ñ1ƒ“w0ù›ÿh Ù’€… •òœÉ€4P6hƒ>ƒØ€#¸€;x̆Pˆ‚8XBH…LC.,…UP%°¶Bì†Z¨‡F8-pθ×à<€^€ç0 o`A2ÂDXˆ6b€˜"Öˆ#ÂEf!~H0Ä!‰H "E”ÈRd5R‚”#UÈ^¤ù9ŽœE.!=È=¤F~C> Ê@Ù¨j†Ú¡\Ô B£Ðùh ºÍG Ñ h%ZƒB›Ñ³èôÚ‹>GÇ0Àè3Äl0.ÆÃB±x,“c˱b¬«Á±6¬»õb#Ø{‰À"à‚;!0— $,",'”ªÍ„ Ba”ð™È$ê­‰nD>1–˜BÌ%+ˆuÄcÄóÄ[Äâ‰Ä!™“\H¤8Ri ©”´“ÔD:Cê!õ“ÆÈd²6ÙšìA% È ry;ùù4ù:y€üŽB§P)þ”xŠ”R@© ¤œ¢\§ RÆ©jTSª5”*¢.¦–Qk©mÔ«Ôê8MfNó EÑÒh«h•´FÚyÚCÚ+:nDw¥‡Ó%ô•ôJúaúEzý=CƒaÅà1JÆÆ~ÆÆ=Æ+&“iÆôbÆ3Ì Ìzæ9æcæ;–Š­ _E¤²B¥Z¥YåºÊ Uªª©ª·êÕ|Õ Õ£ªWUGÔ¨jfj<5ÚrµjµãjwÔÆÔYêê¡ê™ê¥êÕ/©i5Ì4ü4D…û4Îiô³0–1‹Ç²V³jYçYlÛœÍg§±KØß±»Ù£šš34£5ó4«5Ojör0އÏÉà”qŽpns>LÑ›â=Ej¨kh¨4ÜkØm8ndn4רÀ¨Éè‘1͘kœl¼Å¸ÝxÔÄÀ$Äd©IƒÉ}Sª)×4Õt›i§é[3s³³µf-fCæZæ|ó|óó‡L O‹E57-I–\Ët˖׬P+'«T«j««Ö¨µ³µÄz§uÏ4â4×iÒi5ÓîØ0l¼mrllúl9¶Á¶¶-¶/ìLìâí6ÙuÚ}¶w²Ï°¯µà á0Û¡À¡Íá7G+G¡cµãÍéÌéþÓWLoþr†õ ñŒ]3î:±œBœÖ:µ;}rvq–;7:»˜¸$ºìp¹Ãesø¥Ü‹®DW×®'\ß»9»)ÜŽ¸ýênãžî~Ð}h¦ùLñÌÚ™ýF½½³ðY‰³öÌêõ4ôxÖx>ñ2öyÕy z[z§yò~ácï#÷9æó–çÆ[Æ;ã‹ùøûvûiøÍõ«ò{ìoäŸâßà?à°$àL 10(pSà¾_ȯçÎv™½lvG#(2¨*èI°U°<¸- ™²9äáÓ9Ò9-¡ÊÝú(Ìy‰¶ˆ†Åârñ`²GryòPŠGÊæ”áTÏÔŠÔ OR%y™˜¶;ímzhúþô‰Œ˜Œ¦LJfbæq©†4]Ú‘¥Ÿ•—Õ#³–Éz¹-ÚºhT$¯ËF²çg·*Ø ™¢Ki¡\£ìË™•Só.7:÷hžzž4¯k±Õâõ‹óýó¿]BX"\Ò¾Ôp骥}˼—í]Ž,OZÞ¾ÂxEን+¬¢­J_õS}AyÁëÕ1«Û õ Wö¯ XÓP¤R$/º³Ö}íîu„u’uÝ맯߾þs±¨ør‰}IEÉÇRaéåo¾©üfbCò†î2ç²]I¥ooòÜt \½<¿¼sÈææ-ø–â-¯·.Üz©bFÅîm´mÊm½•Á•­ÛM¶oÜþ±*µêVµOuÓÝëw¼Ý)Úy}—×®ÆÝz»KvØ#ÙswoÀÞæ³šŠ}¤}9ûžÖF×v~Ëý¶¾N§®¤îÓ~éþÞ:ê]êëê,k@” Ç]ûÎ÷»ÖF›Æ½Mœ¦’ÃpXyøÙ÷‰ßß>t¤ý(÷hã¦?ì8Æ:VÜŒ4/nmImémkí9>ûx{›{Û±mÜÂðDõIÍ“e§h§ OMœÎ?=vFvfälÊÙþö…íÎÅž»ÙÞÑ}>èüÅ þÎuzwž¾èqñÄ%·KÇ/s/·\q¾ÒÜåÔuì'§ŸŽu;w7_u¹ÚzÍõZ[ÏÌžS×=¯Ÿ½á{ãÂMþÍ+·æÜê¹=÷öÝ; wzïŠîÝ˸÷ò~Îýñ+?R{TñX÷qÍÏ–?7õ:÷žìóíëzùäA¿°ÿù?²ÿñq ð)óiÅ Á`ýãЉaÿákÏæ=x.{>>Rô‹ú/;^X¼øáW¯_»FcG^Ê_NüVúJûÕþ×3^·…=~“ùfümñ;íwÞsßw~ˆù08žû‘ü±ò“å§¶ÏAŸNdNLü˜óü%c3¢ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDùC» pHYs  šœ vpAg\Æ­ÃzIDAT8Ë“ÁKqÇ?;»Öj»î®QšF*±t#Ñe÷PXɦ]æâ!!Ø»ˆÙ¹µ?À”òë`k‡Š!h¢‚¼Í‚ÇŠUi0ê ,BFáh³ ÎN»]feSêÐ<~÷y/¿ç©T*T¥(J;0„Ý'M±È?ä©E¹LÕ4W¥ÃBˆµ¿E´šÝÍn˜.äå>@*• «. ½w’¢(!`´Bˆ¹½€G€^-Ȳw§說fküÑ€©Zˆ'•JÅ…YY–{ÇÑLÓì°, Çqhhh ©©iÕï÷§UUs·ÑÜMw=ey X,jŸ×¾r>y“+×®sûù:Þo‹H_ÞpÔÉÓÖÖ¦×ÕÕ F"€ŒëÉ–×0ŒöB¡ðÖëõúûî<¦ÿbœžFÞçmv^Àjï§îÈi ËZ‡Ïç»\.—3õõõ0šL&³0ì8Nxvv–Ö¦FÎ4Kèï>Ñ•ÏYz@gsOë9Ä“WH’³,KßÜÜÐEÆÇÇ ƒ8T¸õDæ)º®³ºðŒ!ðù|½!fffj!«€)Sº®ç …}§ü|7 ºâX–ÅáãQœŠ¢‘2@€ééilÛŽ•J¥Œ"[51Fõ±±±ØÃ>–"̾ÆV–6àdý÷¯J”J%lÛÆ0 &&&hiiõÔÞÂÈÈÈÝ¡¡¡ô1^|,óÓ†³ÇàÞ¥xw¶m399I>ŸOÿp?R{"‘Hwwwööö†Ëå2;;;8ŽÃöö6¹\Ž………ÌúúzFUÕì>@­LÓŒW*•ØÊÊJx~~Þ4 #äTUÝÚwÿ«ß 6´{j”ê%tEXtcreate-date2009-11-28T17:18:28-07:001‘²,%tEXtdate:create2010-02-22T15:47:37-07:00Ò4Í%tEXtdate:modify2010-01-11T08:42:49-07:00A{ݦ5tEXtLicensehttp://creativecommons.org/licenses/LGPL/2.1/;Á´%tEXtmodify-date2009-11-28T14:31:30-07:00ˆÖt$tEXtSourceCrystal Projectëãä‹'tEXtSource_URLhttp://everaldo.com/crystal/¥‘“[IEND®B`‚GoFigure2-v0.9.0/Resources/fig/VolumeRendering1.png0000644000175000017500000000354311667757442022014 0ustar mathieumathieu‰PNG  IHDR+vgAMA± üa pHYs  ÒÝ~ütIMEØ 9 Á)òIDATHK}•yPÔçÇ޶M£$©æÐÚ•Ô5• Èá5*F<Q¹-‚‘®\ÊÊå²Èá²Àî.Ë®ì‚Àr r_r¤$“T[DZGÚéûéJ§N§Óéïï|¾ßçyŸïó.èÜþ¿ôká „E‹_–X|OxÝâ»Â_-ºy ûLÂÓþûÂÒw-„%‹ }#|k¾kñækÂÛÖV‚ö½cÂôw>ýýŸžÿ§¿^9-®¨èœ] 4„†c<NWò%>K áþQ'Z7¯ãŽ÷|=¼šÀdà~FÏùÒ-»A÷~gÚ7®¦oÛÆO{Pxµ”]µ¸øÜÆ'ª‘…útÿí›ÞÚ³VxWHF©gÖ¨b.Á‡>;hµ]aÝjîíØ„.ç&¥åmD]ëÅ[<‰²Ð€>§„Á´†B¼QæUâ~¶QZãs•º³A’Q¸g• üà ðžà(úŠ2u?sùñÌífÂÞ— èÍðGk㪰õkÅæˆžMÇêØÒóùa2óÛ˜J Ã)%ôR#ò²–â;ßg© ¼±ßZX>W6? G=ÉPq.sáÞóÆõ«©[ûCú=¶q:¢{/5áçˆý õÏÇÑKƒ{LŠÊ»\Í5 2Q¬hû®·X¶ï}á; aÙKáë†RtÓhu]LfÆó™ï.Ænaüä´é¸Åõ“—®bÀs'MÖ–´îv$ûB»NqéÄÁ¯‘³ëušL?áMŵh›ôó«­ß– }²ë45õPÔù˜æ¶!Æëjª*§TÕÅñ´iD7˜ˆ8IãW¢]³ŠFëÕtž 2¾šÞ•„]4¼Ð×õÖëuG[´rû MÏDv~í•3¶Â›‚æZ)%%mäšžÐ4ò zîA¦é92¿b[Ôêªf¦;Sg~ƒZó¹meI·ó ¢³ð‰ixQ­øRß08«*)Ù£¬jÌIl7Wr{®ñ–ôc!?®ˆ¬l¹eÔhÚé7™hëC¢™Â-u†&\ÔE|¬ÔŒ6´²jFÒ.2t]I8‡gò{#Ùqn/sèFEŸÒm·ŽúíE•r¿ý“‚kiöuZ­ÎÐQ’z)ÙQ¸Pý ÷ô_òIÜ2¯P]È¢>>…ž¤x†/ÇR–«e‡¿[wµùÜâHLƒÅæê¼\æÃ6äïA¹¤Œ”–Š"Õ1ó8~?ØuÕ KAxKP7Œ&™dSÀ1I­”Ff¡ O¡B\ŒXÒŠkpå8¾ÉÖCJœý›H-e¼ª˜ÏÃ1ÈÕ,=Q™wi6ýÌð×l—oÏ'T­lÁ_<ÁF¯.œ‚îqšãzÙÞ‡­W[”±Õ]a(Åþ°»#œÎtœ3…º²…j¥‘±­ÇÖý¹º$Ïi™ X¼ÏïgÕs\<Öà~âÕŠm@§ðààߌ—çSÜŽË9t¬€ON™<µkVb\»­«+‡}Ííò¬d·¿Ž+׌Åyy.ÿézž&àzŲÛÓH´³HrÛi–—3“Çìé½ô;H›í:j­V¡³\‰Ár9ÝNÖ„‡ár²ï°[Fù¥`«µæ¥õoǯœ_IkFRx™¬©¢ŸŒª¨*;h—1‘ƨ×N&90ut+÷=™>ãAë%§"ë ŠÖ4'œúàçg$jÉkIO¾MRZ;²ÚŸ£®éá¦y¾¢Ë4GEÓ—H­\MYÅ]âóñLád„¦® Ìzù&ó<ÿ·ãWÎ3b+È‘s=Îüd˜©G(©"¶d†Øô{Dgô#ºù9QeÙù³\ÌûÛ7R×™a³ýÿ€_ üÿus÷Å5ï=IEND®B`‚GoFigure2-v0.9.0/Resources/fig/system-quit.png0000755000175000017500000000255111667757442021133 0ustar mathieumathieu‰PNG  IHDRÄ´l;sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ7ìD éIDAT8Ë••_ˆÝÅÇ?çÌü~÷ïî&KwcÄFâ¦Í6m…V-MK ‚Y|QE(->D æ! yÐôÁôAû¢ød ‹¾ö¥>âJÚB@HB©š5lvÓÙe³{ÿüîÜû»÷Îï7}¸÷nòêaÎÌœóåÌw¾‡‘+O?Í/Îã(ªþúÍ7÷”¦§#UEŒA¬eä«1Èh_u0DòØ\\l|å•% 38 ?þÍüü‡Qµº_T1Æ ªÛ`Ƙøpè3\ *—»«—//<òÒKϘ§ ôÛS§ÎǺõ:Þ9ñ­¾ÕÂ7›ø$¡Ÿ$ô |³I–$ƒýá™o4ðIBwsÓìzøáý2ŽK½rå‚Ý·kמN½þPEc$ˆŒ! +B36ÆäãÓÛØ ³¸ˆZ»MÇ=•KòÅabrò©]pÚ.¯¯—Zkkv¬R‘ JP%]y8Ê÷ßÏîè7›¬\½ ÎmƒÞK‹‰c¹}áB´b« îöm »w“‚UɽÇõûì¨T Ó€ Ù$c´Ó¡zÏcª*&Ïé­¬„ è5›„Nœ#8G¯V£rè¿zï=tj IÓp–a''ùÉɓ̼ú*Ͱ­Æ9L§Cøê+òÕU„‹„N‡à¡Ýç˜zòI~zô( LïÝKpn»â8MÉÓ”B¹Ì×_§?>Žm·ÑõuÒ÷ß§d#`úýAr’©2ûüóÔ>ù„;gÏ¢Þ €ÿæÖNÂß¹ƒŠ°ó™g°Ý.þÿaBFTˆÉ@‡À~k‹™^@€~£Áò[o»Tˆ ÎVWiÎÏ0¶oîêgЬ¡ãel9&ê=¹sdÎñÀáÃ|ûÁäõ:êéâ"…jóó„ ´ÝÆ_¼H¾µÀøÑç¢ÅŒ•0Å["ï ÎQ(•ZŸ~Ф)!˧Oc£ˆ(ŠPïÉ®ÿ—î¥K”ææˆöý)DH¹ˆf9°EÀ ©è×ëŒÌNMÑM¤PÕASt»äkkøFƒ¦ÈþýƒàÍ ´\DŠ1&í¨(vDE­FýÒ%î;vŒ¬^‡$!lnâ¿þÿùç°¾!#<ú3Š33ôþùw´RÆÄé]à¨ß'Oðžk'N01;Ë÷Nœ »¼<ЦsX@^±Àä_Î ¤}sÿŸ+H±ˆDk-Ð"`‡<Òí’\¾Ì·gÎ@ì}í5¾¿°@oϼµôâ˜Þܸq“Ê£2{ûÏ#ˆU F)ŒoT‰µºtü8ê=÷½ü2ÓGŽ0½²B¿ÕB‹EŒµäµ-Zú#Ý?BwŽ#ª B¬B hµRÁ³Ýï¹yü8_ÎÎ’œ?@T­b¬%o;Zï¾ÃƒÐ=w)Y1[(J°ëiZÿùƒÖ7––¦-0Òk׸17G ”§§±½.y½–,fÇR. C€, ¦:.·ÖÖný ÚæbíÇúéäÁÇŸhµ;H–Eb"‹"lc#‹ôzhž£cUt¼Š”KH©„”ŠH© 3?”•[5ÿÜ¿?{±K2”íÎ?Äúâï=q´01QüeHh$Ë‘<ßöCð ™*ׯ]ÿßï—n¼“VÊÿÀµûÂ]‹Ãù»ZÚ@Èþm˜@9–ʉ#IEND®B`‚GoFigure2-v0.9.0/Resources/axes.qrc0000644000175000017500000000331411667757442017016 0ustar mathieumathieu fig/splash.png fig/splash2.png fig/cube.png fig/2D_VIEWS_INFOS.png fig/LeftView.png fig/C_M_L.png fig/PosteriorView.png fig/DorsalView.png fig/Myapp2.png fig/camera-photo.png fig/mouse-cursor.png fig/xy.png fig/video.png fig/scalarbar.png fig/4views.png fig/UseDatabase.png fig/document-open.png fig/Hand.png fig/LookupTable.png fig/system-quit.png fig/VolumeRendering1.png fig/xyz.png fig/zx.png fig/yz.png fig/TableWidget.png fig/zoom.png fig/navigation.png fig/Distance.png fig/Angle.png fig/Box3DPicking.png fig/EyeIcon.png fig/BlankIcon.png fig/PlaneSelection.png fig/MeshEditing.png fig/ObjectPicking.png fig/ContourEditing.png fig/TrackView.png fig/LineageView.png fig/synchronize.png widget/arrow_up.png widget/arrow_down.png fig/transferFunction.png fig/C_M_L_Border.png GoFigure2-v0.9.0/Resources/widget/0000755000175000017500000000000011667757442016631 5ustar mathieumathieuGoFigure2-v0.9.0/Resources/widget/arrow_up.png0000644000175000017500000000427311667757442021203 0ustar mathieumathieu‰PNG  IHDRddpâ•TsRGB®Îé pHYs  šœtIMEÛ 5'àOÁãMIDATxÚíÜÍn;`ÛÇ“6m3!t…ÈÝ#±a;Äæ>A5åEî p߀¹eƒͤ?lŠHÒD‰DSš‰ïÊ‘Çc{ÇŸ#„Ήׯ_7‡ÃatzzÚúôéÓ­1T«¹6)ʶ~èžË‘rqqBP†£gÏž/c1–1¢n·ÛúòåKtyyYCž}ËÑ¡›[¨ òj†œ®,Q0!ííí-e…–…qttýüù³0†ª^˜–ETéK ¦ÔÅÿMFá)LZû »Ýn½R©,eÙ–ñíÛ·èû÷ï™%ô­­­\ ž®t‹†ª  i¥Ã°¸Ü›j2ʲ®¥À20ÎÎÎ2ÛÛÛVª•7á³MY&”¼Ô¶*p#¯óMlQT5e(°Èš±J ]ÇÛ sój ?Qø9cl©(°(ŒÓÓÓ[a˜j†mtØF‰Í$Ñ„¹L( F‘%›´dS¼yçæÕ“UÖpCuá)¯ˆç5ʪj ¸ŠaS¸mSíûu5EÚbt+pÃæÓnó>ù“Ÿ7¹”÷w-6Ãv˜«úäÛzù\…r“=_à:FÞ,}Ñ(¦Ô&£0ÆÂ«««úýû÷­÷|ë¦TU”ËËËp6›Yoš€Û`T«ÕRaØv^”¢CbŒ1šN§Ú \y(`Âèõz­v»­Å0mHX'FݧÜ4ŸÉû›@‰Â#ÅtÕLGGGÑÉÉIi"Ãò¦k¼¼N¾) ƺ¾¾Î\àÊCI4Çã±cgggm7m¶)ÈvËô7ñëù Óž©ub¬ E¾òÈ_§”*QB©,‡‡‡#xóæMs<Gý~¿ÇqÔét2{{{) yk§ «F‘Ï)¥™,ý~?DÍÓ׋/Fô÷ïß­~¿ÅqÅqœÁ¨Õj™û2äGW0T#)ݪ¯8ü%„¤Å:!6J©ñ²@­VCãñ8õž8Ž›ãcŒ(¥MxðàÁ?Nçq»ÝÎ`Ôëõ…ì)FÑH)r!Ìô?*• ºººJý®^¯"„êA4!I’3ߪÓh4”âk„L”¸€±h‚ü:!mmm¡Éd’AI’ä/ŒJ­ˆºwïžr+v¾jGa‘«|ëÆW|UÏÅGñ|6›Í_ãÏg³J’$õÈϧÓ)J’$uL§S43û¾R[Iƒ @F#SD>éÑmv? y¡\ SMÑ-¥ˆ5E5¼£u»d!h ƒÔl!ÛÛÛ¨Ñh¤>ýòÁ1t÷fð?6/"Ê„Q4RĈ¯­óˆ$Ic,!b ƒy ›ƒ<|ø0“†äÎ×¢6cQ(b “S™ø\No?~üH§,ñk*T;Íå:!ßݪÃ(ºœ½îfJ_º«Œ<…É_å!öG’$™o˜àï‡ÔZùͺ›)mw…¸€qÓy Gá?#Iï !¼­@Tw²ª^×M~nºM³Œ(bŠÒm²¹t,Þ§"/¯hAT‘aÚa®C±YŽp©©¶™.f‰'ALÓ„(ŠÀ4Í€¡à4Æžç+œjWnŠ*Àm¾åÏÉ”Åà _ù ‡Áå¥/Õù±]KQyé GF Ï€ø¾¦i‚eY)vð(ªKu v%jò0TÚ\ùH†r †¿Ï0 ¾/›ÿ’õÖnŸ¢(VñB$Š¢½)C•Ïÿ…"ÙWe™ž«PQ4°Jçï炌F#èt:)†bYVò! ŸÊ@Š"ëW eU ê`m3CàöšÉdò@ò)êõ:t:$2F­VKÎ ÃHÎYÚâ>j¨&¾­Jc¯‚ÁŸóÝUÆ‚ “É|ß§A,Ë‚»wï¦0 «|Ž=Æ(q—¹ª(ªy7NC윇àq¦Ó)„a˜zo«ßïÿ͇LÇ0›Í`ooO8!&ûÆS•ŒÇ*øþ6QÊÀÀ|„0Œ ’Ã÷}Ç™÷î÷û`½zõê/Ó4Ÿ?¶ø'çó9Ôëué€h’‡‚ÿv[(«`°”…â8N!ð0 c:f>Ë`0pŽÿ±^¿~ݲm Q‹Ôj5åÝ&TzÂ("ˆM£¬Š!ë5aáû>¸®Kb ƒáƒ>YçççŽeYn³Ùl@{4¥P<ÏË ÈFßy(2ˆM¡¬ §'#øõëWæ³;ƒÁ`xïÞ½wîÜùd]^^º.C‰ã˜DaÝ]Ü]•UrQÖ‰Á|ßÏ`üþý;óYžŸ/‘ ‚QFk<·g³Y ‡| iYêñ]ÅPáQâ8vÃ0l]__·ã8VFQ™L\¥Œîí¶1”AÊ‹/ÜF£áÖëõÖ÷ïßÛ „"Û^´n”]Â(puuåž¹¶m+¡P w^ää¥%•×î*FaU”¼o>ŽÕ±†*J‘Ý!UÂX D…_#.Ú%ÎûæI[»†±4H”" ½¨mQ…,:ðà KÛÆX D%/U©N§¨tw‹F^ÇØ6ÆÊ «D ¥:J—E‰Jt°¨‚`eŒÃÃCçä䤌R@ÊjSdéL5}©DG™mFÙ¥lEe9Y¶»P´¤ ¥‚P(×××B*EšÏ[Äû¨pdP;B0†ïû™÷xôè‘óìÙ³Ò1JÁ(†a´~üø‘A¡*^tAPц›z\´CD´°ÄxßT§ÓqNOO‡½^¯tŒµ€ð(ÿMÛ?Çüóìj­"3ÂTºËÃÊ[zeÓ媦i:'''ÃÝn·tŒµ0”—/_–eµ Ã8À \y(E»¹" Ñns~uOÃ0 çùóçÃÃÃÃív{øþý{gõ¶6€‹‹ ØÛÛÛ¶É®0 Sû—MW"Ñ6O¼W ƒˆ0ŽŽŽ>v»ÝᇜuÕÙZATVyYϫȈ\vYßvxž—AÙ&ÆÚAŠ ™Å• üD—àlaÂb±¨ÆF@ðªcQ<{Ì_¤B]À"d±XT cc « È.Í»®‰óí‡çyày^fк-Œ‚`”ýý}rÓ’÷T¸a§ÚQt°x•06² ЍÍ5äÔO¾«ËRåR0¶R÷¾øÈQ¹V_"€w¢k]¶Ž±5 Å÷ýöt:M¡ðé„úü¢k5pOÊó¼Jbl£4Öh4jÏçó nSD?oDÍæRsUDÁíõzN·ÛýfÛ¶suuåÞJ%Žc7Š¢Ìž/–¾Øä#¾ Y4­Ž¯Õ`m1S™è¨C‘íùâ{P¢6D´èÄ£T£2 xÚ^„‚‚Eìò2ß÷E‹c•èˆ* oPQ¯ f+‰Q9"(Ô´:!’ÿÓCe1* R¥h©:FeAÖ² •)eW0*RÊ.aìÈ*(»†±3  ÞóEçôôt§0þIÛõhw®IEND®B`‚GoFigure2-v0.9.0/Resources/myappico.ico0000644000175000017500000000206611667757442017667 0ustar mathieumathieu(& èN( €€€€€€€€€€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò‡ÿÿÿÿÿ("Ïÿÿÿÿÿÿ 3ÿñÿñÿòÿñÿÿÿòÿñÿñÿòÏñÿñòr?ñÿ/ÿÿÿò /ÿñ0?ÿñÿ!?ÿññ3"'ÿÿñÿÿüƒ?ÿÿñÿÿÿÿ( @€€€€€€€€€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿs"#7ßÿÿÿÿÿÿÿÿÿÿ‚""""'Ïÿÿÿÿÿÿÿÿø2/ÿÿò3?ÿÿÿÿÿÿÿÿ÷'ˆròÿó3ÏÿÿÿÿÿÿÿÿÏÿñÿÿ3=ÿÿÿÿÿÿÿÿÿÿÿ'ÿÿ#7ÿÿÿÿÿÿÿÿÿÿÿý/ÿò3ÿÿÿÿÿÿÿÿÿÿÿò‚ÿÿ3?ÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ#8ÿÿÿÿÿÿÿÿÿÿÿò/ÿó7ÿÿÿÿÿÿÿÿÿÿÿÿ‚ÿò3ÿÿÿÿÿÿÿÿÿÿÿÿ"ÿò3ÿÿÿÿÿÿÿÿÿ/"‚ÿÿ#ÿÿÿÿÿÿÿÿÿø""ÿÿ#=ÿÿÿÿÿÿÿÿ"/ÿòÿÿó?ÿÿÿÿÿÿÿòÿÿ"7ÿÿÿÿÿÿÿ(/òÿÿ3ÿÿÿÿÿÿÿ"ÿÿÿÿÿÿ#ÿÿÿÿÿÿòÂÿÿÿÿÿ"ÿÿÿÿÿÿÿÒñÿñÿ"ÿÿÿÿÿÿÿÃñÿ"ÿÿÿó?ñÿ'ÿÿø/1ñÿÿÿò(ÿÿˆwqƒ'1wÿÿ.ÿÿÿÿñs3/31ÿÿÿÿñwqƒ32ñ3ÿ÷ÿÿÿñ÷33ñÿÿÿ-ÿÿÿñÿs3"7"2ÿÿÿÿÿÿÿø2""#28ÿÿÿÿwxˆÿÿøqÿÿÿÿÿÿÿñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿGoFigure2-v0.9.0/Resources/GoFigure2.desktop.in0000644000175000017500000000051211667757442021135 0ustar mathieumathieu[Desktop Entry] Type=Application Terminal=false Version=@GOFIGURE2_VERSION@ Name=GoFigure2 GenericName=Data Viewer Comment=Visualization and Analysis of 3D+t bio-images TryExec=gofigure Exec=gofigure & Categories=Education;Science;DataVisualization;ImageProcessing;MedicalSoftware Icon=gofigure2 MimeType=application/x-gofigure2; GoFigure2-v0.9.0/Resources/myapp.rc0000644000175000017500000000007711667757442017026 0ustar mathieumathieuIDI_ICON1 ICON DISCARDABLE "myappico.ico" GoFigure2-v0.9.0/Resources/myapp.icns0000644000175000017500000000653311667757442017361 0ustar mathieumathieuicns [is32àÿÿùº·®Îý‚ÿþÿ ìs¸·Ñÿ±£åºøÿþ€ÿëšÿ¶áåk2Búÿÿþþè…üœj@[} R®öÿþÿõˆ¿­}p4G#+_ïÿÿöåȽÄÀ^æÿüŸ·¾Åî×[âÿùu¿À ªÈmQ8,êÿû·Éÿß®¾ïß`*ìÿùwÕÚù´•éïÿo¥úþú£ÿÿ좫Óÿè6+Yîÿþÿöüü÷ÉÄÛŽU'Œíÿþ€ÿýÿÑSd'nÇÿþÿÿýÿÿþÿ«yÉ»ÿþüþþ‚ÿþýÿ€þ…ÿþýþüüþýþ€ÿþÿó}ma›þ‚ÿ;þÿÿþÿÛon§ÿ®¥ß°öÿþÿþÿ×0ÿyÃñ`d–m¤øÿÿþýÒùA|]@5Lvc–2@îÿön“ÿ³s˜ÿñ°'çÿó«µîPÎøÿÔGÁùþöVÿÿÙ:K¦ÿÿ˜:bóÿþþéøûóÏÑÓØ–%€èÿþ€ÿþÿñ°¨ˆ;|mËÿþÿÿûÿÿþþϳùÿÿûþþ‰ÿþþ†ÿ€þýþýþ€ÿ þÿó}naœþ÷ý€ÿ þÿÿþÿÛpnª€ÿ§{êÿýÿþÿ×0ÿ}ÍÐup„þÿÿþýÒü1Q²€bîÿþÿì@\£ ÚÿÿèÈ~‹£*àÿúNn}ŒàÅhÛÿô…€>R–tO7æÿön“ÿ´p™öÞašûþó«µîNÎõÿiÙÿýöVÿÿØCZ£ÿâCÆÿýþéøûò¹ºÏ‹Z9[ßÿþ€ÿ ýÿÖ^l$,XÈøû€ÿ ûÿÿþÿ¦wɼõÿþ„ÿþý‚ÿüûþ„ÿþýþüüýþÿs8mkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùùùùùùùùùùùùùùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùùùùùùùùùùùùùùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿil32W…€•ÿ…€„ÿ…€†ÿ‚€€À‚ÿÀ†€†ÿ€€†ÿÀ€ƒ€€€À…ÿ€€ÿ‚€ÿÿ€€€€„ÿ€€ÿ‚€ÿ‚€ÿ€€ƒÿ„ÿ€€ÿ‚€À€ÿƒ€ÿ€ƒÿ€€‚ÿ‚€ÿ„€‚ÿÀ‚ÿ€€ÀÀ€À€‡€‚ÿÿ…€ÿÀÿ€€ÿ€€…ÿÀÿ…€€ÿ€€ÿÿ€€ÿ‚€€ÿ€‹ÿ€€ÿÿ€€ÿ‚€€ÿŒÿ€ÿÿ€€ÿ€€€ÿŠÿ€ƒÿ€ÿ‹ÿƒÿ€€ƒÿ€‹ÿÀÿÿÿÿ‚€€ÿ€€Œÿ€‚ÿ‚€ÿ€€ÿ€ÿ‚ÿ€€‘ÿÀÿ€€ÿÿÀÿ€€”ÿ€ÿ€€À”ÿÀ€ÿ€€”ÿÿ€€”ÿ€ÿ€€À’ÿÀÿ€€”ÿÿ€€“ÿ€ÿ€€ÿÿ€€‚ÿ€€ÿ€€ÀÀ€ÿ€ÿ€€ÿÀ€ƒÿ€€ÿÀ‡€’ÿ€€€€€‹ÿ…•ÿ…„ÿ…†ÿ€€€À‚ÿÀ€…†ÿ†ÿÀˆ€À…ÿÿ‚ÿÿƒ€…€„ÿÿ‚ÿ‚€ÿ€ƒÿ€ƒÿÿ€€À‚€ÿ€€€ÿ€ƒÿ‚ÿ‚€ÿ€€‚ÿÀ‚ÿÀÀ€€À€€€€€‚ÿ€‚ÿ…ÿÀ€ÿ€ÿ…ÿ€€Àÿ…€ÿ€€ÿÿÿ‚€ÿ€€‹ÿ€ÿÿÿ‚€ÿ€€‹ÿ€ÿÿÿ€ÿ€€Šÿ€€ƒÿÿ€€‹ÿ€€ƒÿƒÿ€€‹ÿ€À€ÿÿ€ÿÿ‚€ÿ€€Œÿ€€‚ÿ‚ÿ€ÿ€€ÿ€‚ÿ€€‘ÿÀ€ÿ€€ÿ€ÿ€€À€ÿ€€”ÿ€€€ÿ€€À”ÿÀ€€ÿ€€”ÿ€€ÿ€€”ÿ€ÿ€€À’ÿ€À€ÿ€€“ÿ€ÿ€€“ÿ€€ÿ€ÿÿ€‚ÿ€€Œÿ€€ÀÀ€€ÿ€€ÿ€€ÿÀ€€ƒÿ€ÿÀˆ€’ÿ…€Šÿ…•ÿ…„ÿ…†ÿ€€€À‚ÿÀ€…†ÿ†ÿÀˆÀ…ÿÿ‚ÿÿ€…€€„ÿÿ‚ÿ€ÿ€ƒÿ„ÿÿ€€À‚ÿƒÿ€ƒÿ‚ÿ€ÿ„‚ÿÀ‚ÿÀÀ€€À€‚€‚ÿ‚ÿ…ÿÀÿÿ…ÿÀÿ…€ÿÿÿÿ‚€ÿ€Œÿÿÿÿ‚€ÿŒÿÿÿÿ€ÿŠÿÿƒÿÿ‹ÿƒÿƒÿ‹ÿÀÿÿÿÿ‚€ÿŒÿ€‚ÿ‚ÿ€€ÿ€ÿ‚ÿ‘ÿÀÿ€ÿÿÀÿ€”ÿ€ÿ€À”ÿÀ€ÿ€”ÿÿ€”ÿ€ÿ€À’ÿÀÿ€”ÿÿ€“ÿ€ÿ€€’ÿ€‚ÿ€ÿ€€ÀÀ€ÿ€ÿ€ŽÿÀ€ƒÿÿÀ‡€“ÿ€ƒ€‹ÿl8mkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿicnV BðGoFigure2-v0.9.0/Resources/BugEntry.txt.in0000644000175000017500000000203011667757442020246 0ustar mathieumathieuPlease send this email at: gofigure2-developers@lists.sourceforge.net >>> IMPORTANT: a precise description of the steps to reproduce the bug is important. >>> IMPORTANT: if the bug is non-trivial or if it doesn't always occur, please let us know and try to describe it. >>> IMPORTANT: let us know if the dataset you are using is public. Many bugs result from a corrupted dataset. ------------------------------------------ * System information: GoFigure2 Version: @GOFIGURE2_VERSION@ OS: @OS@ OS Version:(ubuntu 10.04, xp sp2, lion, etc.) !!!!! write flavor here !!!!! ------------------------------------------ * severity: (Minor, Medium, Major) !!!!! write severity here !!!!! ------------------------------------------ * description: !!!!! describe the bug here !!!!! ------------------------------------------ * how to reproduce it: !!!!! describe steps here !!!!! !!!!! 1-click on this button to open this image !!!!! !!!!! 2-click on this button to do that !!!!! !!!!! 3-click on the image to do that !!!!! !!!!! 4- that happens.. !!!!! GoFigure2-v0.9.0/GOFIGURE2CPackOptions.cmake.in0000644000175000017500000000502311667757442020552 0ustar mathieumathieuIF( CPACK_GENERATOR MATCHES "NSIS" ) # set the install/unistall icon used for the installer itself # There is a bug in NSI that does not handle full unix paths properly. # NOT WORKING # The icon file (.ico) for the generated install program # SET(CPACK_NSIS_MUI_ICON "@GOFIGURE2_SOURCE_DIR@/Resources\\myappico.ico") # The icon file (.ico) for the generated uninstall program. # We use the default one! # SET(CPACK_NSIS_MUI_UNIICON "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeLogo.ico") # A branding image that will be displayed inside the installer. # We use the default one! # SET(CPACK_PACKAGE_ICON "@CMake_SOURCE_DIR@/Resources/fig\\splash.png") SET( CPACK_NSIS_COMPRESSOR "/SOLID lzma" ) # # tell cpack to create links to the doc files # SET(CPACK_NSIS_MENU_LINKS # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-gui.html" "cmake-gui Help" # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html" "CMake Help" # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-properties.html" # "CMake Properties and Variables Help" # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/ctest.html" "CTest Help" # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-modules.html" "CMake Modules Help" # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-commands.html" "CMake Commands Help" # "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cpack.html" "CPack Help" # "http://www.cmake.org" "CMake Web Site" # ) SET( CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\gofigure.exe" ) SET( CPACK_NSIS_DISPLAY_NAME "GoFigure2 @GOFIGURE2_VERSION@ a cross-platform application for microscope image visualization and analysis" ) SET( CPACK_NSIS_PACKAGE_NAME "GoFigure2" ) SET( CPACK_NSIS_HELP_LINK "http://gofigure2.sourceforge.net" ) SET( CPACK_NSIS_URL_INFO_ABOUT "http://gofigure2.sourceforge.net" ) SET( CPACK_NSIS_CONTACT "@CPACK_PACKAGE_CONTACT@" ) SET( CPACK_NSIS_MODIFY_PATH ON ) ENDIF( CPACK_GENERATOR MATCHES "NSIS" ) IF( CPACK_GENERATOR MATCHES "RPM" ) SET( CPACK_RPM_PACKAGE_ARCHITECTURE "@CPACK_SYSTEM_NAME@" ) SET( CPACK_RPM_PACKAGE_LICENSE "BSD" ) # SET( CPACK_RPM_PACKAGE_REQUIRES "" ) ENDIF( CPACK_GENERATOR MATCHES "RPM" ) ## Debian package - variables to be set. # IF( CPACK_GENERATOR MATCHES "DEB" ) # SET( CPACK_DEBIAN_PACKAGE_ARCHITECTURE @CPACK_SYSTEM_NAME@ ) # SET( CPACK_DEBIAN_PACKAGE_DEPENDS "" ) # SET( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "" ) #ENDIF( CPACK_GENERATOR MATCHES "DEB" ) GoFigure2-v0.9.0/GoFigure2Config.cmake.in0000644000175000017500000000364211667757442017727 0ustar mathieumathieu# # This file is configured by GoFigure2, to load # GoFigure2's settings for an external project. # ################# # GoFigure2 ################# set(GOFIGURE2_MAJOR_VERSION "@GOFIGURE2_MAJOR_VERSION@") set(GOFIGURE2_MINOR_VERSION "@GOFIGURE2_MINOR_VERSION@") set(GOFIGURE2_WC_REVISION "@GOFIGURE2_WC_REVISION@") set(GOFIGURE2_VERSION "@GOFIGURE2_VERSION@") # source code set(GOFIGURE2_SOURCE_DIR "@GOFIGURE2_SOURCE_DIR@") # build information # would "LIBS_STYLE" make more sense? set(BUILD_SHARED_LIBS "@BUILD_SHARED_LIBS@") set(LIBS_STYLE "@LIBS_STYLE@") # Add include directories needed to use gofigure2. include_directories(BEFORE "@GOFIGURE2_INCLUDE_DIRS@") # Add link directories needed to use gofigure2. link_directories("@GOFIGURE2_LIBRARY_DIRS@") ##################### # External libraries ##################### ###### # The Visualization Toolkit ###### # source set(VTK_DIR "@VTK_DIR@") # version set(VTK_MAJOR_VERSION "@VTK_MAJOR_VERSION@") set(VTK_MINOR_VERSION "@VTK_MINOR_VERSION@") ###### # The Insight Toolkit ###### # source set(ITK_DIR "@ITK_DIR@") # version set(ITK_VERSION_MAJOR "@ITK_VERSION_MAJOR@") set(ITK_VERSION_MINOR "@ITK_VERSION_MINOR@") ###### # QT ###### # source set(QT_QMAKE_EXECUTABLE "@QT_QMAKE_EXECUTABLE@") # version set(QT_VERSION_MAJOR "@QT_VERSION_MAJOR@") set(QT_VERSION_MINOR "@QT_VERSION_MINOR@") set(QT_VERSION_PATCH "@QT_VERSION_PATCH@") ###### # BOOST ###### # source set(BOOST_DIR "@Boost_INCLUDE_DIRS@") # version set(Boost_MAJOR_VERSION "@Boost_MAJOR_VERSION@") set(Boost_MINOR_VERSION "@Boost_MINOR_VERSION@") set(Boost_SUBMINOR_VERSION "@Boost_SUBMINOR_VERSION@") ###### # MySQL ###### # libs set(MYSQL_LIBRARIES "@MYSQL_LIBRARIES@") set(MYSQL_EXTRA_LIBRARIES "@MYSQL_EXTRA_LIBRARIES@") # includes set(MYSQL_INCLUDE_DIR "@MYSQL_INCLUDE_DIR@") ####### # Video ####### set(ENABLE_VIDEO_RECORD_FFMPEG "@ENABLE_VIDEO_RECORD_FFMPEG@") set(ENABLE_VIDEO_RECORD_AVI "@ENABLE_VIDEO_RECORD_AVI@") GoFigure2-v0.9.0/Documentation/0000755000175000017500000000000011667757442016205 5ustar mathieumathieuGoFigure2-v0.9.0/Documentation/CMakeLists.txt0000644000175000017500000000003411667757442020742 0ustar mathieumathieuADD_SUBDIRECTORY( Doxygen ) GoFigure2-v0.9.0/Documentation/Doxygen/0000755000175000017500000000000011667757442017622 5ustar mathieumathieuGoFigure2-v0.9.0/Documentation/Doxygen/DoxygenStyle.css0000644000175000017500000002142211667757442022773 0ustar mathieumathieuBODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } BODY,TD { font-size: 90%; } H1 { text-align: center; font-size: 160%; } H2 { font-size: 120%; } H3 { font-size: 100%; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.navtab { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } TD.navtab { font-size: 70%; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace, fixed; font-size: 95%; } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #e8eef2; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } TD.tiny { font-size: 75%; } a { color: #1A41A8; } a:visited { color: #2A3798; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } TH.dirtab { background: #e8eef2; font-weight: bold; } HR { height: 1px; border: none; border-top: 1px solid black; } /* Style for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 4px; background-color: #eef3f5; border-width: 1px; border-style: solid; border-color: #dedeee; -moz-border-radius: 8px 8px 8px 8px; } .memname { white-space: nowrap; font-weight: bold; } .memdoc{ padding-left: 10px; } .memproto { background-color: #d5e1e8; width: 100%; border-width: 1px; border-style: solid; border-color: #84b0c7; font-weight: bold; -moz-border-radius: 8px 8px 8px 8px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; font-style: italic; white-space: nowrap; } /* End Styling for detailed member documentation */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin:0.5em; } .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } GoFigure2-v0.9.0/Documentation/Doxygen/MainPage.dox0000644000175000017500000000123711667757442022022 0ustar mathieumathieu/** * * \mainpage GoFigure2 * * \section intro Introduction * * GoFigure2 is an open-source, cross-platform application for visualizing, * processing and analyzing of multidimensional microscopy data. * * Users can visualize, segment and track cells through time, detect * cell-division and ultimately generate lineages. * * \section homepage Home Page * * The Home Page of GoFigure2 can be found at : * * http://gofigure2.sourceforge.net * * \section howto How to use this documentation * * This documentation describes the API of the Toolkit. The Modules * link presents a hierarchy of classes organized according to their * functionality. */ GoFigure2-v0.9.0/Documentation/Doxygen/Images/0000755000175000017500000000000011667757442021027 5ustar mathieumathieuGoFigure2-v0.9.0/Documentation/Doxygen/Images/QGoConnectServerPage.png0000644000175000017500000004167211667757442025533 0ustar mathieumathieu‰PNG  IHDRü„\AèsBITÛáOàtEXtSoftwaregnome-screenshotï¿> IDATxœíÝwxÕþ?ðÏlM%›lzï! ÍÐCï+÷¢ø•¦ô^¼JÑ ^Qi‚¢ÀA%´P‚`@j $RIOHÝ6óûc`o IH ›æýz||vÏœ9sf²¼÷ì™ÙYæaqU1lÚ篊=_½Wõ)£ýáÿÞlbðÎ?:£W`ßýv¦27éç•ø§Bø¿7O™ð.e”³wP‹üâr­Ž­ge‰X¤´2#"Ûf&DôÍwßó¹Ï<,.â?#¯Ìp}€ç‘_\^ð°,ñÂñzÖj×Ó¦™9ŸûD”[T{bÿÏ+'HˆÈÄ.€ˆ8ŽÓ×ÎéèqyJLLJL ÿØ3"Â3"B_gãáÔgÝxŠ‚‡yE¥7/èÙÿõ7ë§ÖOJ+<ýkó6=ˆÈ¦™)_ÈG½dØ´ÏGŒ™œšSRmn'O* …BADEEE[cGEEQJŠ' QU }¶Ê4.•F{óÒ‰®½‡(›™æW>µ¾²™ió6=n^:Ñ®ë>Ÿmš™x›ö¹„¯QChÇÄD-YBD£ïÝÛ¶­;QЇG7¯””n‹¾¡”"¢­‹·ŽY<¦ÖÕˆˆèü•ëÅKm¬­Ú´äKNŸ½\©V»8Úx7â&ˆˆa±Xdj"·UZ»»8ɤ’§®{-ñVvnƒM‹ ÿúoˆß–©\ngkíëå&‰žsêÆ0DDŽ6:¶¾ikocy“ˆaªç³>ô«7äA)[·FEÍ&J¹çÑ-"…î{Ò©îc#-ŠX¼8Å3¥¨¨ˆÿ(ðäêDt>.ᣑáþîÊ«ÉÙ«~¹Ò¦EóÓç®l|¯ŸÒÊôØ…»¿¹èïÕX› "–å*Tڜ²‹73žMôõö¶jf^Ǻñ7néØ1Ô56>}ë‘¡~õÜiul^qù_ Qgn¶ @îƒA‰øÔ'b‡þÁãÑÀžôuž,áW¬–ÏBÿÉù™SÛ¶¥¤¤PJJ·1‹¶¦XymÛFÝþ¾°jÃÔ<½Sí­ bñbý㘔˜˜S4&"‚<•¤ÄÄðgqSø÷Œô¡Üß³WµL£Õ‰ÊŠfL@DW“¨4:w«0§]'“JÊ'F¶ìÔ­¬BsùÖ?7›È.N¶–ë~kÚ¼ÆM°gffîåíyôâ]3ÉëÝ}\¬í¬Lò ‹=ƒ+ÕÚKIY¦rIˆ·ý°ˆ@"Ús;%«ÈÆÒÔÂLVZ®ÎÌ+!"–˜@OÛ'+Ÿ¼–^u_XÎÂLf&—Q~q¹L&/*.©q+Ç.§ˆÙÊçÜGýGM>l{w Ÿþù>>è«ÆýôÏ÷õî^5¦z>×:§¯áQ—ܧ½·‰L²bJO–åD"†ˆr ËÎ%f¹ºº”=,ønaäÝŒÂÜ¢r;k3™T̲\zîòJ:{=½CˆëÂѯÝÉѱ¬¯«ÂÂdÄâ_•Ö6 SÃë-ÔÇþ—Oþ©ZXRñ害n®.w3 ‰H&Ïz£}Y…¦gÛÿ}3@n"ÏÌ-!¢0§/¦õÎ.,Û}2±¶ÊzîÊ5³úðÓ;ü†2rKùýzrEŽáqA°Dú¹Ÿ²Ÿþù¾°–¡üýÛÀ߯ީžÏµ#÷ 1[câqc<ÇĤÄ0÷O }R¿™5’ËärK›_ŸÑ;$ÐÃÖÌDZXRwûÁŽ£×===Ä"QQ)séf¦·³µ·‹µŽeïdþ|"Qnªpvµùê·Ë©Š»…y´ðuÐhu¹%ÇÎßUXY“¨ú%hz÷èËY—o=Øwú–ƒ£³¹…yzzÙ–qÿìØ)ÔíZrö/'GôáëÛÛ*¿x?ÐË6ÈÓÎËYan*½›QT[e=™ÄÝÁŠã¸‡eªÄ”¼ŽÄ{{yåÔ¸"C¤Ò5æ>‚0U»N¿e‹~€ß²EHm%ú«½–˜Þ#?1frjöß~Jeш ý㘊ˆ ”˜˜­)1‹Ç,&¢±K˜n)£Ç|¿U_gÉÎÄFÝAx¥”—Wd=È.-/gu¬D"¶´´tqrJ¥D¤ÑhRÓ3+**4 C"¹£ƒBaED,Ë=ÈÉ),,R«Õ #2‘Ë›5³tt´Uùž/éö²2þ–àŒX,’ɤÍ,-ìm%’Gcšœœ¼ìœ\ËZZ˜›™™e=È‹D-[‘V«½—’VZVÆqœL& ¨£r• #‘ˆÍÍÍ\œMLäul¥QöÎÊÜäÈÁ=Ãßø¿äŒüz®ba*ÿãXTßÊËÝ«G£eÏûé)'rãââ–œúG -"¢ˆˆˆ˜”˜”˜ÅÝ<ºyvÛZµN:ALLM¼¼<ªò¯±Dâåé^ã"bÈÑÁÞÑÁ¾æ¥UøùÖ|}M[;¥­R_îà`§_*‹}|<«®RGåº7TÛŠ² püHÿAA)[ï{ïä”PßÈ­¹¡V­ZͤUk¢fÇPŠç)ò$ÏÑÜ"ψ1Uî°Y×êðü*5ºÞ‡;¸Çµy…•ÅSë—¦ß<Û{à°J®Z>?šÞ¹›Y`°ÞÀó23‘I%âãѿֳ~Ïþ¯k´ºò*WîsýozCu€YY…ÊÆÊ|ÐÐ7êY_¥Ñ–U¨þ^ÆPC/ÙcÉ/*}žÕù’æ–y{œn¤.À‹«¹ež„ˆ¢V¼QŸgì΀e¤§}³9·í„>€€ ô¡ßÔ8ŽËÌÌÔét,Ëâ¢)hbý¦Æqœ·oFF†Z­ÖéªYÀ úMŠã8–eÍÌÌZ…µNKK«¬¬Ôjµ,Ë>}M€Æ€Ðoj|Äïܹóµðééé••*~ªÇØýA»õöÛ#‰hĈgNŸvssãïÍ+á= ¡ßÔøI|™‰åóÖršBß8dR3…ÒcÞ‡_ršòÅ8¤2s K‡²’Âyó7îܹ³s—.iii˜ßCÃHß8dRK[¹©mYEÞ¬¹Ë ã}hHãHäææ +¥ŸHlZVV8iÒ{ï@ÀHß8´Z•F])•[H$rN«-W3Ž0ÞCè‡ZSRTœ£.+P«ÊXVͲ*b¹·ß~›ˆFŒñç>÷M†á÷ Q` iUY^ö‚ü$¥««[›ôŒtN§ÓéFŒADa­ÛdffjµZܤFúơ֖åß9õÕ¾è¸Ý¿üý÷Óm‚ÒÒÓLär¹ÜÄÔÔD©Tra°#}ãÐjÕ¿ý¶!(¨ù°!¤RÓ ›~r÷ð”I¥fff–––ææær¹\,czBß8bÏÄØX[ýùç™ @oûÌÌœ¸¸«jµF&“™šš˜™™™˜˜H$$>4.„~SãsÜV©ÌÌH777‹‹›4.„~Sc&!!¡´¬Ô¢Y³fy¹¹]:·ÕrêØ³g³²¤¤Ü×h4¸H ¡ßÔ†±jfinffiiiiaÙ¼y@aaþ¿ç¼ãììXQQáæî®ÕâGµÀPúMŠa‘H$•JMMMMMMMLär¹<>>~ô¨7®Æ©¨(/,,`Bâ€à’ͦÆÏÔó±Î_œÓªeËY qNŽŽr¹§pÀ@úFPõBL±X,—ˆ‘Ëålj%™TŠÐAèÃ0‰D$Éd2z<ÿƒËóÀ@úÆÇ0ŒX,Öß[ q†ƒÐQ ë  àêAèHSLïD>¼gϯ7oÞ,++S(­Zµ?n\PPPlºžB[´$¢óçñw6~ÎjØ%"š3göÈ·ß–H$DôÝ÷߯Zµš/¿vµî***V¯Ysôè±ÂÂBSSS7W×^½zM˜0ž_ªÑh~رãÐÁC÷RRˆÈÃý¿~£F–I¥U;PŸÕwU*•6kÖÌËËkHdä!‘õœ°jèQÕoŽˆÌÌÌ|||Þ;¦W¯^õY÷9Õ}H^ † }ŽãæÏ_pðÐ!"²¶Vøùùåååýþûq??¿*ô_d?ÿüóèQ£ˆˆeÙŸþ¹þ+~¼ô“‘———D"N¾sG"•ò ¥Ñh&LœtñâE"òôôä8îÖ­Û·nÝþãôéo¿ýVŸû âââle¥ÈÈȸxñâÅ‹cNúò‹Ï ÷Ë_..Î66ÊÔÔÔøøø¹ïý{Ïî_|}} ´-½:iý©ÕjþJ­ç׈Mp6ôÙ½›OüÙ³g5J,QbbbAA!_!66vÓæÍ‰‰78Ž œ4qbÇŽùEü€nÚÔ©wïÞ=qò¤¹¹ù´iSÿ9lXÝ‹T*ÕÆ_>r8;;G©T4hÊ”ÉÒÇ)våJܦ͛®^½VYYéìì<{ÖÌ^½zéGŽË>]¾ìÓåTË ºŽjuìE5W¯^]ùù)))¥¥¥¦¦¦-Z´˜5kf`óæµ@‰D’žžqúÌ™n]»þqútFF¦D"Ñjµüžvïѳ¤¤dùòO@DûX°`¡B¡8qüw©TzâÄ "zgìØÙ³gQyyùõë×ùfرãâÅ‹‰díš5]ºt&¢Sü1sæ¬+Wâ¶oÛ6nܸ§ýak0zÔ¨#FètºÜùÙÊ•Çߵ맷ÞQ÷^×vTŸz øÍegg÷ê݇eÙ«W¯ñ¡_ÇŠ Ÿ­\™˜xC«Õº¸¸tìØqÁüyô´×LUuÒ:á÷qòäI7o&ÅÆÆ¾óÎØ¬¬¬½{£"""Ö­]CD]ºvS©T«¾ü¢W¯^ jjÊäÉMù^†Óß³çW"êÔ©ã;cÇò‰ODAAA;w"¢ØØØÉS¦^¾|E¡PX[[_¹7yÊÔØØØª-|½iSÜÕ«&&&ùùùŸ|òŸôôŒºM›>cËwßåääz{{}»eË‚… ùú.\xçÝwÿü3–eY??¿ÂÂÂ[·oQhh(_ÁÅÅ944Tÿ´šÚªÕg/ôRÓÒ”J¥Ÿ¯¯Z­Ž0abiiim°gÏD´k×.ýÿ{õêÉ/’Ëå$"~ìI#©oŸ>|@ð³+ç/\øóÏØÒÒR33³öíÛó58HD½{õ⟈ºuíÊ·}øpm©±Xt0úÐÁÐÐP–e7mÞ\µNóæÍØ¿}ÛV"ÒétWâ®Ô±èÂ… çÎcfÇÿݳ{÷Ž?ÑáÃGîܹCD6lÔjµžžžGGÿüÓ®S1'ù{?îøopô¨Q?îøAÿ´šÚªÕg/ôÂ_{íô§¢öþöË/?ïÝû?¾¶ئuk¿?ÿŒ=}úLlìÙÿÖaaú¥ÿüç0":{ö\^^žZ­Ž=KDü; <˜ˆ®_¿>iòäN»Œ=úÂ… ü¢”û÷‰((øo3lÁÁÁD”ššV[gê¯u›Öôø¯_÷^×vTŸz –}º<´EËwÞGD]ºtîôø£U+fffÑØ±c~þiWÌÉ6¬'¢º_3ÕÔvHëÓˆ‹‹ËáèC{vï7îÝvíÚÙÙÙ©ÕêSüADG%¢¾}úȤ҆6EDžžžžžž–Íš=ÏŸ „ÃàsúTû艉7ˆ¨G÷þ,eîñññ ‰UëôèÞ]"‘¸»»óO˪Œõž\t=/ßèð7Þ¬ÚHBB‚OüõëD9x°B¡ "©Tª_÷yÔg/ôÔjͧ˗_ºx©¨¸Xÿäܼ¼:ÚóÍ7?þxé¿ßŸã¸7G¼©Q«õ‹üýCBB®_¿~èP´‡§Gyy¹««KXX+~é¼Þ÷ñöÚà`bb¢V«½r%nâ¤ÉQQ{Ý\]kü»ðOYî™…^µöŸa¯Ÿº ?§_TT”––{öàÁƒ|"×±bûöíccc7oþ&:úpPPàÈ!þþרö×Lµ^ÕvHëÓÈ€þý-,,ˆˆ?Ï1 ÿmÛ·;ö{Ï=NŸ>CD $¢ghjÿ¾¨:Ž$@5† }ŸÄÄÄ‹/¾3vì³µ`aaNDú©¡ª·Ÿ|r¿T,W;Kljj¦lܯ@ýûý÷ããã%‰Ÿ¯¯L.§§åìàAƒV­Z]RRbii9hàÀß~û­êÒvýúõýû÷óÃöþýûë‰Åâ7ß|óÍ7߬¨¨ØàÀÒ¥Ÿh4š ç/¸¹ºzzzܺu;éfRÕ¦øéiwçßÍK/‘——×3ïõSWáçô‰héÒO~þå—µë¾âC¿ŽW}ùÅž=¿^¾r9!!ñðá#GŽݵóÇú¼fôj;¤õiD¡°ªºhÐàAÛ¶o?sæÌÑ£G+**œÛ´nM_á j  A ;½3lØëDtúô™íÛÿ«vÝLJ:sæO" $¢'c´Z­N§;q2†ˆ‚ƒŸýªžà`"ÒétsçÎáç ¶ný~Ü»ïð3ס!!D´oÿââb"Òh4iééüŠü Ÿ`­CÕ´7nÜ ¢±cÇìÞýËÂóë³S&&&C‡!¢¡C‡˜˜˜T[:`@ssó›IIÑч‰hÐã¹"Z½z ?¡ajjÚ¡C¾Pn"§Çï ‡ÑOøüqúôï¿'¢þýúUm_«Õ©«xjou:ÝÖmÛNŸ9CDC"#ë³×5Õú(þóDAAÁSW¼}ûöÈ‘o¯úòË]»vÇq ‰‰u¿fª©í6¨^ó€ŸÊÊÊ/¾\ED àwäš9dpäÖq”ô ;Òÿç°a—/]>xèÐÊÏ?ß²e‹£“S~~~vvöäÉ“:wî4iâÄÉS¦ÆÇÇ÷0a˜¬¬,‘H4q„gÞ\»víÚµkwáÂ…±cßñññ‰˜û÷SU*Õ§N™˜˜L™2yÂÄI÷îÝëÓ·Ÿ§§gFFÆ[o˜2y2ùx{'ݺµqã×Ç~?.‹k›Ö¯±ZƒöÂ×ÇçfRÒ¶­ÛNÿq:/?¿žû5{Ö¬ñãÆóŸlª155пÿ/»wWTTz{{ëmùî»-ß}çââÜ̲1¾……U£F:sú̥˗ß7ÞËË‹eÙ””" =zTÕö?[¹ò³•+õOëørÀ¶íÛ£öíOOOçßS{öìùæ›oÔg¯k<ªO=PÛ¶oßà`qq1.·S§NOÝÖÛ#GÙØØ8::fggó%ÞÞÞ­ÃÂêxÍTÛhm‡ÔZ¡¨#zƒX³v]~~>ÿ˜/¬û5\c;üß®äáÃÚ6P•aGú"‘hùòOW¬XÞ¾}{­N—””¤ÑhzôèÁ_ÝѱcÇÖ·nVXXXPPЪUË ë××v±c}0 ³aýWï¾óŽ‹‹sJJJFFf@@À´©Sù¸l׮ݖo¿íر£H$ºuë–•••Ÿ¯¿âG}àïÏr\bb"?!P£«5h/–-[Är˱«W}YÏý’J¥ÖÖŠ/"¤Ç§èïÃ|"š1}z»¶mËÊÊ“nÝ’H$;vüö›Í6ÖÖD$“J¿ùfóœ9³›dffò©Ñ®]»­ß'—ËëÙ«j222“’’ÄbqÛ6m>^²dÕ—_ègÞêÞëêSTFFf|||ff¦££ãÇÿç“¥O]qذ× EòíÛÅÅÅÞÞÞ}ôa›Ö­ë~ÍTSÛ!mP#zúÑ}`óæúùúgk  þ˜éS&­]¿± ¿®³jð"+))éÚ-‚ã¸cGØÙÙ=C 1§NÍœ9K&“ý¸c‡ŸŸÁ¿âF‘‘žöÍæÍ¸÷ÎËmþü£FÑjµ=zt¶Ä'¢ˆnÝÞ›;·²²rÖìÙu|i^ørÇËíÀÁƒb±¸]»v æ×ë´pmFŽ|{äÈ·«WðÂBè¿ÜžzÛ5€ª0½ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú"iPí 5P?àô0¸ ?¯þõú} n`àÒ°ÐoÐû ¼h0§ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚ІÝZÇqµF­Qs,kì¾€ñ1"‘T*•ËåÝ Bßh***®ÝɉþëÞ½ÌBc÷ŒL"¹94ðšO‡–ž,ËpC†kê Q«o§þssh¯×ìì”bæÙåØœœüŸ~ÿËÎNÙÜÝF­VhC}ãP©ÕQgnÿ«§¯y»/ðbð·‘JÅ;]Z1sáBLãàX6åA‘µµ•±;/kkެB‘!?úc¤o4Z+bDDôéî[ÆîKƒÍÿ§¿±»ð 1"­Î°Wv`¤ }ãs±1™ÿO™¤Ñþú½exÙ6â¯_<8ÒÙÙÅÍÝ£Wï>'Nœ4èæjtñâE¥­]Ÿ¾ýª•¨Tª¦ïÌKŠóˆcwž—C_¥Vþ†««ë‰ÇÿøãÔøqï–––Öu­VË>ß·–ª¶pýúõ£ÇŽ=Ok¯†~RRRNNÎÒ¥7oÞÜËÓó7ÞˆŒ¬_ºeË–×Â;89»„¶h¹råç|:ócð#GvîÒÕÙÅuéÒO:tì¤_E£Ñøúù:t¨þ-äææò•Gµ|ùŠ';¹sçÚþN IDAT®®Ýº99»xûøN™:[â9uêTDDwg×þÜ¿ŸzáÂ…={9;»ôéÛïþýÔºwä™É¥¢ÈöNï õébËT[·÷·žÔÏëƒ×ýf òîl˶ðlöno÷_÷›=ÄwP;ÇgrœmLø:£z¸+Ì¥uo¨¥§ÕÔÞó†ùOèÝÞÏš/ÕÈþý¿ùÿôÇ)\€—š¯Þ±U*‰èرßGŒx³Ú¢U«VïÞ³gù§Ë’““çÌ™Ë0Ì{ïÍÕ/]»fµ•••H,þjýúÄÄAADsê”V«íÙ«Wý[P(iiiD4mêÔ]»~ŠŽŽî߿՞ˆÅ¢O–.õññIMK›?oþ‡}´zÕ*~Ñò+V®üÌÆÆföœ¹ïŽgfjúÙŠå666³fÏ™7oÞÎ?ÖÝ‹/öí×?õ~й¹yýZß0{+Ùö“i&2ñëáNåjÝù[…DÔ%HÙÆGqøJNfA…™\â`õè‹Ú,Gǯ攪­Ì¤½[Ù÷jiwèRvµ6;)£/e«4lÿ6}Ãì:“QÛ†,L$ýÛ8œŒÏ½‘^b.—X˜ˆù~>“1¼³Ë†C÷´†ü¢ 4ŽôçÎ3cæÌÐãÇOÐÐÕjõê5k6nXß½{wggç®]».Y²ø»ï¿×¯øá­[·öñññòô íµ½Q{ùòß~Û;`À¹LVÿôw±P(“&M\±â3Žû[l >¼k×®...ÂÃ?úè£ê-^´¸]»v>>>S¦L¾råÊâŋڶmëíí=eÊä?NŸ~ꎘ˜šúúú6èz[™DèfqüZnN±*5·üÜ­‚V^VD$3¯Ø˹™^ò°\û °òjJ1¿ÊõûSrÊ–kÓò*b®çù»X<ÙìÉøÜÌ‚Êüõ_· ÝíÌêØ©LÌ0t;«ìa¹6«°òvVßB¥ZGDe*mY¥¶¬R[ÿ=€a¯Ó_0þȷߎ‰9uæÌ™wÞ7kÖÌy|œ|§´´tà ÿMõ°,[YY©Ñhø§!!!úECÿ1tÓ¦Í æÏW©ÕÑÑÑßlÞLD jAoò¤I›7sàÀA''G}á¥K—–}ºüúõë:®j#üÇ zü‘%0ðO+++UjõÚ»!•JC‚ƒÿ:w¶A‡ËÚB*b˜EÎ0g¨"Bd C62©˜IÉ)rg“®Á¶ ¹D̈F"fD¢ê§[ó>új_y¥V"fÄ"¦¶ 啨2 *Gww»Uv;³ôVf)‡‘=À«Åà_Îrss9òí‘#ßnß¾ÝÇK?™÷Á,ÇѾ¨½ …âo]‘<êŒT*Õ‰Œœ?Aüõëéii‰¤[·®DÔ ôš5k6eòäŸ}¶êË/ø’òòò cHdäüyØØØ\½zmÜøñúIùjƒôêcvŽ{j7 M*½ÑÅõfzÉ鄼 5ë`-úšÓ™OÕ‚›©ýŽ£N¦y9˜y;š÷oãÐÜÕ2꯬Æï7OÓ}#×××·¢¢‚eY?__ssóôôŒ°°°§®ekkÛ¹sç½{£ÒRS ȧyƒZ¨jâÄ _oÚôÛÞGóEÉÉÉÅÅÅ ?\ÈåOœ8Ñ Öž¹µ),Õ°ç¨ßË.'"'yA©šã¨ T­Ñqžöf‰i%Uë+-¤&RÑ©ëyå*y9š=熈ˆå¸;Êî<(KÉ.ÖÑeßù,Ž#~&l¼ úW¯^ýîûï‡ÿë_žžžiiéÿYöi—.]D"‘\.Ÿ;wÎÜ÷æVTVt×jµqqWïÞ½;wîœÛyýÿøâË/òó ~øïv¾¤¡-èYXXL:å³ÏVòO]\\¥RéÆ_5*11aý† ÚÁº»q=!áÝwÇÅœúÆ!•I[6w{GfºçÄÕûYE†þULxÁIÄ"'Å»CÚ‡ø8”—•pC†kêÀ0 DzmœÂC=t'NxU±,«V« šø„Ð7.•J…_m€¦„1&€€ ô¡ }Aè®Þ1Žã4jZ£æ ùí;xY0"‘T*•ËåÝ Bßh***îÞI¾pþ|NN¶N‡ß¢4±Xlï`ß¾]xhË,Ë=}…g…Ð7Z‘žþÇ©S}úösvqeêøµr–eSSïŸ<þ»ÒÞÞÝÍM­VhC}ãP©Õ±ž882¬uc÷^nîîöEM™>Ãp¡¹ÆÁ±ìƒYvvöÆî¼@¼¼}²²2 zk„¾Ñèt:Ìê@Ub±ØÐgøú‚ÐY­X±Â×××ËËëòåË...¸qÔ‡CÿâÅ‹J[»²*· åKOÏ/;;{íÚµëÖ­;þ|hhè•+W }m/¼^¾«w´Z­H$ø=è333‰¨K—.Ddoÿ¼'„qTÂhÿÈwìø±e«0{Çàп֗oÙ²åµðNÎ.¡-Z®\ù9ÿ[‘üG„#GvîÒÕÙÅ577×XÝ6‚‚‚‘#Gz{{÷ïßÿ§Ÿ~ÒO×”””L›6ÍÏÏ/$$äÓO?åÆž={ DD.ñõkl‡ŸÿÑäÒOñ~ÿý÷=zx{{óGuëÖ­]»võôôlÛ¶íªU« ú[ÐôŒ3ÒÏÎΞ=g΢EÿoHdd^^Þƒìl¾|ÕªÕ»÷ìYþé²€€€äää9sæ2 óÞ{sõK×®Ymee¥P(.^¼Ø·_ÿÔû)æææFÙ…Æ5oÞ¼ÜÜ܃–””Ì;W_>þü7nDEEMœ8Q©TN˜0aРAÖÖÖ#GŽŒ555½~ýúÈ‘#ën§k×®ýâ‹/ø£ºvíÚ½{÷.]ºÔßßÿÎ;ï¿ÿ>Ã0³fÍ2È>€1'ô t:]¿¾}]]]]]]ùBµZ½zÍšýû¢Z´hADÎÎÎK–,þ÷ûèCÿÃ… Z·nÍ?615õõõ}5¦#JJJ>¼sçÎÀÀ@"=zô¢E‹ˆ¨´´tÿþýÛ·o "¢)S¦üðÃ&LËå …‚ˆlmmÍÍÍùÇu´S·yóæ………‘F£Y¿~ýîÝ»CCC‰ÈÉÉé£>Z°`BàUbœÐ÷÷÷oÛ¶mŸ¾ýúõë׿_߈D¢ää;¥¥¥ ÖWcY¶²²R£ÑðOCBBô‹B‚ƒÿ:w¶©ûm©©©:ŽOv" æÜ¿_«ÕòLD-[¶\¶l˲µ½ÕÕÖNÝôÕîܹSZZúúë¯ëé¿T*mønÀ‹È€¡/“ɈH¥Rég`T*Ã0R©T$<°ÿdL̉'fÏ™µï›o6³KDû¢öꇮº(yÔIDϳ©ö°jÓôúÃË—ÿòË/µxpzÄÃÃC$%&&êKâã¯{¸»óU‰DÒ»W¯O—-[·níÞ¨(–eý|}ÍÍÍÓÓ3¼þî•ÿÚª»»»X,¾qãÿTÄ<<<$I||<ÿôêÕ«ÞÞÞuÌhÕÖ…O~~>ÿT_¡ssóŒŒ Ï¿{å?€ 0ô­¬¬†2Á‚sçþÊÌÌ<|øðªU«FMDqqq›7sûöí{))ÑÑÑnn®"‘H.—Ï;gî{sþå—´´´{÷îýöÛÞ/¾ø²ÆÆ¯'$¼Þ¡¢¢Âpýo2–––}ûö]ºtéÍ›7/\¸°mÛ6"bÆÂÂbðàÁK—.½qãÆÙ³g7lØðÿ÷ÏÐŽ···½½ý_|‘––³iÓ¦W—Ëå3gΜ7oÞž={ÒÓÓSRRöíÛ·fÍCì2‹aO„®Y³ºCx‡1cdžµn3Á‚I“&M›:•ˆ,,,EG÷êݧcÇN7o&}ÿÝw|ý™3f,ú‹Öµ¾ýká]»ElظÑÑѱƖ++*’““_™ W¬XakkÛ¿ÿ… Ž?žŸ#¢O?ý´yóæ‘‘‘ãÇë­·Æ÷ íˆÅâõë×_¾|¹K—.ëÖ­{ï½÷j[}êÔ© .üúë¯;wîÜ»wïM›69884ò®€Q1Ó§LZ»~cA~ž±{",%®[»zöÜ÷]_¼¤÷ßÿþwýúõçÎ{ÎM4V;Дޛ=cùÊ/7zËéißlÞŒst/„øøøììì   ;wî¬ZµjøðáÆm^U }¥­]m‹òó^µ¯Ô>'N÷ŸÿüçîÝ»æææƒž3gŽqÛ€W•CÉ^­Zµ:yòä‹Ó¼ª^…o´¾¤Äbñ+s"…N§‹ÅÝBß8‘ÈÑÑ)3#ÝØ€Ƚ»wœœœ :Dè‡L*ëÔ¹ó±£GnÞH0ô¯£À‹O§ÓÝLLØõãŽ>ýôGGpõŽqHeR¿€æ©,úàï·|‹Ü8±Xìèè8(2ÒÛÛ»¼ÊoO5:„¾q0 ñl@@@Hhè«q¯PxN,˪Õjƒ&>!ôK¥RáÇ# )aŒ }AèB@@ú‚«wŒ†ã8Z£Ö¨9ÜŒˆ‘H*•Êårƒn¡o4wï$_8>''_Î8±Xlï`ß¾]xhË,ËnC}ãШÕééœ:Õ§o?gWü-€À±,›šzÿäñß•ööînnjµÚ@Bè‡J­ŽýóÌÀÁ‘a­Û»/ðBpswwpp8°/jÊô† }œÈ5Že<Ȳ³³7vGàâåí“••iÐ[³ ôF§ÓaVª‹Å†>ÇЄþÿ\¼xQik‡; À+̰¡ÏÇ(ÿŸ¯ß¤I“ ºÅ—×åË—]\\Êþ~WÕ°^jMqõÎ¥KÍLMÓÒÒfÏ™3sÖìíÛ¶6ÁFŸJ«ÕŠD¢á^ö¿þúkûöíõOãââJJJrss_´Â.]º4ÞN€q4EäÙÙÚÚÛÛ·iÓfÁ‚¿;FD;wîêÚ­›“³‹·ï”©ÓJKKùš;vüزU˜½ƒcpHèÆ_×VxðàÁÖm]é¸k×.¥­ÝÉ“'‰H£Ñ¸º¹_¸pˆJJJ&Nœäæîáç°té'üoNòŸ<Ž=Ú¹KWg×ÜÜÜ¢¢¢·Þú?gg—î=zÞºu» ŽÆ“\]]§L™EDk×®]¹r¥««ë Xh”ƒ«I¯Ó—ËdZŽeY±XôÉÒ¥>>>©iióçÍÿð£V¯Z•={ΜE‹þßÈȼ¼¼ÙÙDTcákáá÷ï§fee999=wÎÆÆæì¹sÝ»w¿víÇq-[¶$¢÷ÞûwâÄèèCÅEEcßyG©TN™2™ïƪU«×®Ymee¥P(¦M›žž‘~ôØÑâââÓgè»zñâžýú§ÞO1777ôaiß¾ýO?ýIDwïÞݱcyyy½h…ð hºÉüü‚5k×…‡‡‹D¢áÇwíÚÕÅÅ¥CxøG}tàÀA"*((ÐétýúöuuumÕªU¿¾}k+´U*ýüübÏž%¢ØØ³'L8{–ˆÎž;צM™LVZZº7*êã%KB‚ƒ;uê4}úômÛ·ë{òá­[·öññÑh4ûöï_²xqHpp§Žß}÷]}SS__ߦ™ü¹téÒˆ#:tè@DÞÞÞ#G޼ÿþ X؇ ­)Fú̓ˆ¨¢¢¢M›6›6}MD—.]ZöéòëׯWTTètºÊÊJFãïïß¶mÛ>}ûõëׯ¿¾ ‰D5Q‡ððsgÏuíÒ%77÷wÆ®^³F­VŸ={®C‡p"º—’¢Õj[´hÉw ¬U«?^Ê>¾¯YHHÿ Zµ–-[èûü×¹³Mppˆ(%%eݺu¹¹¹[¶l™1cÆíÛ·ïß¿Ÿ››û¢zxx4ÍÃiŠÐ?mfn¦°²²¶¶&¢òòò cHdäüyØØØ\½zmÜøñ,ËJ¥ÒƒöŸŒ‰9qâÄì9s£¢ö}óÍf±Xüd!uè¾fíºØØ³íÛ·³±±ñööºtùòùóçÇ{÷iÝ!©TZõ©Ñ¿ 5lØ0"ÊÍÍ埶jÕJ¿è,€—ZSL_xzzxyzò‰ODÉÉÉÅÅÅ ?\ضm[ooïüü<}M‰DÒ»W¯O—-[·níÞ¨(~l^caxx‡¤¤¤C‡uìкmë¶âââvíÚ‘—§§D"¹ví*ß앸8Ÿ'çjW»Æ?½v-Þ°¢N­[·ÎÈȨv á,€—š.Xtqq•J¥7~ššvøðáõ6ðåqqq›7sûöí{))ÑÑÑnn®"‘¨ÆB"rwwsrrúmïÞððDÔ!<ü×ß~ åÊÂÂbè!‹/NHHü36vݺu£FŽ|²'ƒZ¼xIBBâÙsç¶lÙ¢_t=!áµðMqDšŠB_©´Y»vÍ®]»ÂÃÃ7~½éÃ?äË-,,EG÷êݧcÇN7o&}ÿÝwµò:„‡K$’֭ȨC‡pNÇOèó>ÿ|e`óÀ~ýû3väÛ#'MšXcgV~ö™££cïÞ½ç}0oÖ¬YúòÊŠŠääd?o¯fú”Ik×o,¨2ÇM äáÃukWÏžû¾ ®€*Þ›=cùÊ/7zËéißlÞlüï£@“1àÕ;J[»Ëóór ·Q¨ƒCáð¢ÁôŽÑˆÅbœ(€ªt:X,6è&úÆÁˆDŽŽN™éÆî¼@îݽãäälÐá Bß8dRY§Î=róF‚¡ ^|:îfb®wôé?À ?åÔ¤wÙ=©LêÐ\"•E<ðý–o‘û'‹EFz{{—ò—‹úÆÁ0 Dz!¡¡/¹€Ñ±,«V« šø„Ð7.•J…Ÿä€¦„1&€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }AèB@@ú‚Є>€€ ô¡ }‘4¨ö…¿Î¨ð ú\ŸWÿú ý¾7°?ðiXè7èý^4˜Ó„>€€ ô¡ }AèB@@ú‚Є>€€4ì6 ð‚à8N£Ö¨5jŽeÝ—¦ÀˆDR©T.—×Vã(¯„-(שµ\SvÌ(†¤bFa&²·3LÃÖEè¼”***ŠŠ de•–<4v_ N$™››;:¹¸¸º°l ™Î¥äkÓä'&§?È/iú61±XdomìãRî`ëe×°Gè¼|4juéÃ’ô´ûÁ!-míìÅâW|žV¥Råçåܼ‘¨°¶±²j¦V««U((Õå_I¼÷fŸ0?ÇWþ€h4Ú÷2=/•J›™*”âú¯‹Ðxù¨ÔêÌÌ´Ða¶vö,«ÓjµÆî‘a‰Åb{'#¾u3¡S׈'C?¯”½z#å­~mü=ÒÃ&&•JZø»KDâ§VÍú¯8ŽeKKKm”JNËq¯þ6OacSRR"Õ0Š×踅e>nvMß+#òópx°ï¼F×°Bà¥Ä²¬H$Òj4ÆîHÓ‹Dl-g­9Žt:V, ç-ˆ$±NÇ6tú/1%4’WütÀ«Œ#â¸í¿¢‚‚Cûöê´Zƒ´Ï #}€—×x#ý¢Â³gþà‹Åb…µ"0¸…e³fÏÖ«Æí[6Íq5½ó×_uêÔ©}ûö±±±UKJKKMLLž¹Ág^½a¤ðòjäAt·½zôîÓ±KW‰DwéâsÇ ôI¢i]»víСCM¼QCCè¼´¸FDD$“Éd2¹¹¹…»‡Wii ˲ü²ô´ÔÓ§bŽ:pìHôµ+—µ~µ{w“O<~äÐÇŽ$ݼ¡oŠ_ªª¬<}*&þjœ¾©Fèe?~üâÅ‹k\´aÆàà`333OOÏ¥K—òg˜333íìì¶oßÎ×Y»v­››[AAuêÔ‰ˆ,,,$‰DbÌ)LïÀß°,›ý ËÊJÁ<þ‚?CL`P°¹…yyyÅ„ø›‰ Á-ZÑí[Ii÷S‚BBÖÖj•êáÿ}7XU©ºðW¬µRÒ¢É:ßXo |;³gÏÞ¾}{TTTdd$_¿÷,_¾|çΫV­ ¼uëÖäÉ“†Y¸p¡““ÓêÕ«g̘ѽ{÷òòò… îÚµËÚÚšã¸}ûöEFF&''ów’hú70=„>ÀËŠã/ãˆ#¢ÇŽ˲R©¬UëÖúÆ\\ør¹‰óÀkW®…¶Ð±ì½»wBZ´tptâY6³â8Žoª¼¢üÊÅ ¶vöAÁF ¸çdmm=cÆŒ?þxðàÁúBµZýÙgŸ?~<,,Œˆ\]]W¬X1cÆŒ… Ñ[o½5~üø‡¾ñÆ àײ±±!"£Ïé#ôà‘×:v‹ÄQyyÙÄOO/gW7"***J¾u³¤¤D§ÕrDz,˲åe¥¬N§´QÖØÔÅsg탂›vßÌ™3¿úê«ß~ûÍåñ;ß­[·JJJºwﮯòlEE…F£‘J¥DôÕW_YXXDGG§ÓuB輬´:í“7$xƦ4"’H¤b±˜ˆ¬¬žÞ>7®ÛÚ;ètºKþ²·wðôò‘H%¥%% ñ×ÔjµF£!"FC¿Í#ß”Ò67'§äa‰Ü¤Öûb6:F£Õ6Î·Õø«V«ÌÍͧM›¶dÉ’uëÖ‘JUYYYAD‡´¶¶®ºŠN§eY]½WZZªÑh²²²ärYÕUªÊ†Þ³Ñ!ô^Z8½SeÂZ_¨ÓjY–-++Ój4^>>R©Œˆ òóùš¦¦f"±¸  ßÞÁñɦ|ýü“o%Å]¾Ö¦T&k”NÖo?k*édÊ”Éëׯ߳g7_âëëknnž––Öºuë'7_VV6qâ¤ùóç%%%Mš4éСƒü©þî:kôÉ.\½¨ÕjµZ¥V©Š‹ŠîÝI¶QÚ2 cbb"‰ÒSS+++òssÒîßç+‹D"W7÷ÛII¹9Ù*UeIÉì̌ÿµÅ0þA–Wã.k5Mt?8þ$Gc¡Ç¡onn>?dèÈ5IDATcÆŒï¾ûž/‘Ëåï¿ÿþÌ™³víÚ•ššzçÎÝ»÷¬Xñ_yþüùJ¥röìÙ+W®LNNÞ¸q#_îêêÂ0ÌÁƒrssóòò±“ …‘>ÀËŠk¼-ßÎ_±gø§2™\ikëíëÇqœD"ñ ¼—|;õþ}+…ÂËÇ÷FB<Ÿ8^Þ>±äNòmUe¥T&srr®—DœíÚÕË-Zµæ'Ž ‹cë'e8–#"Ž}ÔàÄ ã¿úê«ÊÊJŽå8–5s†Ri³fÍÚ©S§I$’ÀÀÀ±cÇp,{âĉ;wžŠ9%‰VVk׬=fL¯ž=}}}ílm—,Y¼pÁÂ윖e‹‹ ¥ŸÏ€™>eÒÚõ òóŒÕh¨’‡¯\¾Ø£WŸòòrc÷¥I‹=3hÈ?W+OWï9»|ÚµZe”ŽËÿÛ||Xߎ¡®õš@ËHOûfófŒôà•Ñh}^a}€—U#^§ÿjà8N ¿ü<úðªxÖs›‚‚Ðx)‰D¢²²Rc÷¢©Õø³YDÄ0$‹JKË^ù_Ç­J§cÅbQC/üGè¼|‘È¢¼´ÔÔÜÜØ}i:ee–––5þx–TÌ8Z›§ç–¸Ù[6}ÇŒ%=·ÄÑÚB&nXê è]à•!“Ê\\Ü’ïÜ*--1v_šHiiIò[þ̓Uª®ÏQš‹Â=÷Iº›Y¤Õ6Î=_dZ-{7³hß™¤Í=” ‹qŒô^>R™ÔÞÉInfv79©´¤´¶_Ž}eˆD" K‹ àP¥­²¼¬ìÉ 6¢ëf­=c®ÜÏ.,Óé^ñ"‹¬Íýì•VJ‹†}¡ðòa†cY;[[ggçÚ¦¹_1,˪ÕꟈD ãi+µ0±s´SjtÜ+6—aH*f¬ÍEv L|Bè¼¼T*UsÂÄ0dg)¶³4ü÷~_r‚#¡ }AèB@@ú‚Є>€€ ô¡ }AèÈ£®e¤§·Ð˜éS&»ÐDþ?Re9ä}Q\IEND®B`‚GoFigure2-v0.9.0/Documentation/Doxygen/Images/QGoMainWindow.png0000644000175000017500000002761611667757442024234 0ustar mathieumathieu‰PNG  IHDRXf±þäœsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ9×gù IDATxÚíÝyœdeaèýß9§ÖÞ×Ùz6`†D@YÅFEcb¢MÔ¬zEÍó^ÉÍ{oÞ$^M4qys£Éu‰;ĨQpasYfXgëYzzßk;ËûGu3ôŠþ¾ŸOf¦»«êÔ©éê_=ç9Oúü­Y{¹‹¨¾HÇÊÕÔççÉ··gµFB€¤GKBpÈß›_=ôßÁßüT·Öf­­}ä¶qÈ¿ÿ³·ýhדºYöSyŒ‚ €Œ¥ûèžX¾ÿ‡>’}~"ÛvØÖ<öã‘ñŸ³¥O’fÌÎÍòÓfíídÀüÂáòHSèéê¤Ç,,,FAëG0#Ï}F‰àï¾¾'[øÊÇ9õìì¾—ûî¸7¿åRé8žëî>èž—~¤€4M Àٹy:ÚÊ„ñ<¨“ÅÅ’$¥»³D\¯‘…%ææçèíí¥Qo0¿¸@_O7Y}òLNOÓÕÑN±X\úåèmd‡=<î/ê ²,# æ‰ÂŒr˜’:™œš¦X,R.„Ô1a˜ca±J_o3³ódYF!Ÿ£-ŸÐÈÊLÏNÓ×ÛGÍ_ýÁÃI˜$ Q>î~š_X`qq‘ÞžnòùKÒŒ(˜Yz2-räÃŒF’cnn–þ~¨Õêtww4H¢vfggéíé&nÔˆ‚”,,FQ’,=ù>ñ0LÓŒ0 Ë©4M ˜˜œ¦T,)¥bž¹JJ£Q§¯¯—éérQŽr)G­Z#_*3;;KOw7¹´BBÄb-¥££,ã÷_ÒÏLAÀÔô¥÷Ýذ¢“}S‹üæÅÙ¾g’{öLÒÕÞÆl¢|¸Q§»3óнdiJ’$„QHódz9ÎÑü%qœP rÔ9ppŽóOZÉUßßË\v Ÿ¹öÞxÉ3™œ«òï·ì¥ZkpþÉkظj¯Ý¼‡œº‚ζ<Ÿºö~ŽÝ4H[)ÇÆ•GqÝÝû˜šO)—J,ÆaAÒ ³11W§ÜÖý¨‘„!µÊ/8¹‡(×Ï7o& :èʧŒÎÔxû/ofdbžoݾ—®¶"Ó• …ŒF’29›‘raJœ† vFŒÍÅô´å©jD>="æ:íQ„Õ,jÆZSÎ'œ¨ðš Ö³XMøÚͻȗÛ8y}™6ÃU7íäÅ[Öd)×Ü~€£W¶³P­qÙYGqÝ=)E!{&ê´‡ÓYމ™„¾®vfjÏ–â 2’$&—Ë5ƒ/ ©×éΧ,6rdAŽ$M)G… ÆôBÊkÎ[Çäl…ïo?@G!âŒcºèë(ñoßßů>÷(‚ ãSßÞYÊæµe6Ÿ¶ž[§³Tàî]³œ¾©›»wM’ÏGDù2 È ?•‘Aééø"9 Šr¤a´ô£ä"Âra@„TfFi/886M×ÀZÕ:aR‚xî®NƦæÈå"È2IB®VopòK~‰ók§ºó8ê·l§±óŠƒ/¤ZôÇya&ýBH3l‹9eC'×Þ=F”+°PKéh+±m×§ÕÃ}Ãì«0Ô[dj¾NO{ŽOüÇ}œ²±‹cÖöóÉoÜÉsOâ¾=“ôwæùçoÝÇÅ[†˜«$ v6¸`s/_úþ~^}î:nÚ~€Z’'­Ç$µ Ç­.°X­q`ªÎŠžÝås•Œe´•K¬íl0Е疇ê”KE*ŒîîNžâìcû¹æ¶aÎß² ¥|¤l½oœ3žÙ϶=Ó„YB9ЈÎuí»¶‹õ+»¸gï½ýE‚ `¡‘²*¬sÁqý|ã‡ä‹eºs5Öö˜Y¨±m_•sŽëc|zž±JL’ë"É"f*\tj/·>8É1k»ˆëunß•2Øñ…ï=ijŽ òAÊìBÂM÷ìàÂSײuûžsÊzÚr)3•„®_ºa/8sˆÑ©³µ„J#£XÌ3:[çĵ ›»Ë|ãî9z;ËúøH¿à}ETj1õxB>"I3*µÍ9 $)“s &ë%Vôt1¹XmŽ^gµ¬ìbÓê2Ó‹)õd’4k¾ÐÊÕêIsˆ¿Pæüµgsõâ(Òm¨5v¸ó¥Ç0<Ù ÍæXÛ[ྑßpž„ˆ ;øÂ¶.=kÅ|ž‡ΓÆfê\²eˆïocåžq.8eß½ëkúÊ OÔyÞ–µœ®ÒU(ò\{Wóöw¶M°¢³Ìôâõzž, ¸ùÁYú»ŠTÒ<÷¥|D¡P¤‘$윈I‰XÛWàÁ1ØúÐ"s Võµóï[wóâ³Ö3:9Ïbâ8¡RÏØ´ªƒ›¶rìºn:JyîÛ7 AÀÖí#\vÞ1ÜùÐ8KÌUSîÙ;Ãb¶Þ?Íšþ÷¨òè‡ ƒ4%®fœ½¢ƒ¶bÄÔl…8 Ù²iퟡ¿«Èg®ÛÆÁNâ4å¾½Sœ{ÒÑHBN>f€( Ø?Qcr¾ÁÄBJ¥‘°kdšZ…F|äó%FƒõÝyÆçv5H²€ûGª õ—¸oߥ¤Yóq9t+–Ÿ`éYvèTô ²Œ4{xŽY󱂔€¤Q##ºò ::ÚÙ;Y#$#ÌIãAÒV©VÉ ¤AT`°#c®õ4AFeÄiF†þ°J?B.Ì9p°ùs4Ã)n4è# Æ&¦£ˆ0H’Œ,MX½f5zñ‰©æÏøÒi)i£ÊºG3¼ã‚?þ§Û³\RÈì›ÝCWnžŽNjõÄÃÒã†ÖÒ/ÐeµFB©˜kEX–6ç1fA@„¤YJ°4Q!d)­IüYšR·ÌTb ù\ë oùÈli.Ss¾Sú„—Öã±ô5È’¤y߈‚$ÍBZû" 2š[¶SÙ!ÔŸÌc²<çãÛ¶t]ËM–6·- ÂÃ&øgYÖœ›eaÔº\=nŽªEaКàžù YzbÏ“q}éÑÃç¹i\çç^GùæË¸¸¶ô"/#Ë Ê5çVŽíÛAî§w‘¶žðŽ'#[ú¡,,)$é‰ûQ‹.<úB ?åžøv/†-ÅTüÙ¶åQºŸìÞy¢×ý³ñ=ý¶MzúÁ¯æåë{›7¿ô*lù0Äx2 hÙ§iÚ|Õ,¿}ä­¤Yö˜÷óÈûüX# Ov¤£õ92Ò$! £Ç½Žpé~…áòþ?lo><¢ð(û„Öã–~8iiÔ x”C<Fi’´öéòcܼJ?üü½škNê¬Õk rQäTIz‚¢(boWžèŠ+®¸2Ë2æç¸òÊ?ezzŽáá½Äq̆ÉåóÔëu–N<&fgfxðÁ€€öÎNÂ0$ISÂ("CvîØAïÀ@3¢¨yl2 šk×, q‡QD­^eìàÝÝË ÙŒ†¥Û™ŸŸgn~Žr¹=»vÒÕÓÓŠ¬'×äòåê;|€Z­F.—gqa±u=ADQsND’¦ a”kÅOF°4—fùúÒ,cÿþ}LOMÓÑÙI”˵~-ߟ(ŠšsDÙ¶Ö} ›ûex÷nzûû›‡¢ˆ4˘œœ¤P,.}.ß<Œ²t¬d9`—·#C¶o»‡þÁì|èJmíÍË.­4?7ÇÂâ"í­í^¾l#ŽÞ³›}{÷R*•)·µ5ã2ŠHã„ýû÷ÑÝÓûˆÛ¬T«|÷{ßcÍÐwÞy'G}4Åb‘;w27?ÏÚuë ¨ÕjKÇ¡ñãéþ‘ÁÌÜþá’KÎ¥^›ÿ—Ý7~øá‡û°g÷nrМÇÇ1Ck×rÎ9ÏæÊ?ýo¼é—sÅ»ÞÅôäögÿ¶¶¶fS,ÅTwW¸Áôä${vïfíºuLNL´FGÆG²°°ÈÔÄ8å¶2°rÕ*8@OOc££ôôôR­Uؽs'Õj…žÞ^W$ ]]Ýl»çîÖHÍÜì,{ví¢­½¹ãââ"¥r™ÎŽN:»^œ0Žc Å"Q”crr‚(—ctd„öövöìÚE­VcÕêÕÌÍÍ!µZ•(—£··—ɉ â8æ¸ãOXZø¯y}qœ°rÕ*æçØ»g…b‘\.GµZe`Å v=ôå¶vJ¥]ÝÝÌÎΰ0?Ïê5CLMN•jÈèèêbÏîݬY³†ÑÑQâ8fqq‘$‰‰ã˜4I(Š´µ·±båjÒ´¹?Ò´Dã£Ôë ¦§¦xðþûXµz5 ‹T* tvvs÷?$—ÏqÔÑ›ùZ·~={vïftô cGhïêbr|Œ«VS¯Õ¸ç®;é `°5Ò–$ »víbhÍW^y%wÞy—_þ›´µµñ¦ßúm^|é¥üѽ‹éé_ºü\Œ`5Ç@w§\öê·òwú3zº»›/"Ê’¤'ô¶F,²Œ8Ž—VeŽ˜žžáÔSNá÷~ï÷ˆ¢¨5JÄÒäË ÈE9ÆFrô1G351AßÀ½}}ÔëuæfghoogÅÊUttv±~ýFF¤·¯¯F¥2ƒƒÌNÏ008HÿÀ Õjuy8 €8ŽéëïçÀþ} R«ÖhkogÅŠ•´wtÏåXœŸxÂ.ÂKÓ¬fù\žÞ¾> Å"I’rÔ1Ç!«× Q*•(•ˬ_¿‘±ƒY=4D¹­í°ë‹¢ˆ+W2=9ÉÈÈ«††\¹’8‰Y»n=A008H±TbÃQG199A¹Tf݆ärk×­Ê¥6Ö ­cvf†U«WS©Véïï§»»‡¸Q§««›ÁÁA˜ GE¥Rm „æa¼|>Ïþ}û\±’‰ñ1ŽyÆ3™›# `pp%s3Ó¬Z³†+V¶?²,#‰…bÎînêÕ*ƒ+V‘&Í뇆˜y8’=œ/ˆã˜ùùÞóž÷Pn+“¤)—^zéÒaØÐ_¾?'–'Q‡AÀððwÝuù|Ž$I|Œ%é <‡Í¬åˆ8ù¤“èííåô-[Ø´énºéû\à ¼ò/oͽI’„0—gaa(ʱfí:öîÙÍú ¯¿ŸžÞ^f¦¦(–J͹Pôöõ177G¡X$,6'­Û°‰ñq‚0¤T*“$IsÒ}–‘¦)íí¬\¹š hko§V­033Mo_?]Ý=ÔjUò…Bkû–¯uttP(ˆÂˆR¹ÄÂÂ<ÕJ•þþ>&ÇÇéêî! ¥âÒaÌŒ5ëÖ3zð qÜ [ºýåý3:2B¬[¿žƒP(éììbßðV¬jrK3’$a`p¸Ñ`jr‚¾þ ½½¶öv†‡wÑÑÑÉÔä4=½½¤iÂìÜ Ý½½Ôª5â¸AßÀišÒÖÖÖú¥¶<­½­ƒ b~~ GŞݻX»n ó ÌÌL³jhˆé©Ir¹<å¥QÇC#«³³‹4M©×jt÷ö2>6ÆÀÀ ¸ÁÜìÍãË'>„!Ç{,«V®„,ã /à[×\ùçœM.—çæ›oæo¼œ………Çœ“§§ß«¯4ƒ?ºâÅÜtËIôõ0::Foo¯±$=Žpii”`ôàHÇqs"x’$ÉÒû„%„KkBÄq|ؓꑓܗ'^:Ó~ùpÝcýûG}îÑžðœÍèeë2GÞÎÚ¦å¿OŒÑÖÞN©T~Ôë[þ¾ ¨T*ÌÏÎÐÛ?pØ(ß÷±|êæ#ïçcžB½´€Î¡Ûüh—kþÙ|/¶å}ä÷?Þ~Y¾½å5zërQöÿaùñž››cï¾}œx Ôëuª~Ž$IÂÜÜ,»wï§78~ó±´µ•Ý1’ô8¢(âû7Þ@0r`6??ÇOçTß#á?“;æÐœÇ{¥¿¥¿¨#¹\ŽF£áOÔÏŒ`i~b¥R¡½­ƒ\>çn‘¤Ç‘Ïç¹ã¶+ ¬^³–ŸôŠ¢P«T‹‘r[[k(MÒÏT>þÓërK’ôÄž=—–žZ:‹0yœo^:lõ¯|yEêô°EšžÓÓúTš’úXHO YúØ‹îI’–›i©wŽ  G>©¦80B¥R!ŸËµbëѤKï}vߎ쟘l†Öï6|ééõ¤W’ôµÖÁÊÒ”àÑ¥péÍkk«W­bvv†;wRnk£··÷°ÈZ~ÊÍŠEþâk_gç¿H¾¯×½ã Nïë%Nâågh²¥ùM˲Ó4m®L…—$IzZ —Þ+5˜Ë¢(brb‚¾þþfuE;Çê웬pTW¸m“ ËS„ù"mårëÕlšeP,rþJ fL ´ñŠwÿ:¿Ñu:õ´y&âôô4QÑÖÖÖš ]Y\¤·¯Ÿ$‰}…,I’ž¶‚ àÛ×|‹ÖiA}ýýÍõoÒ”bpËÅö!¦gçY]h£^ÌñÝ[à7Ž]¤k` uzE|àëßà®,ã7ÞHõ-o¡½½Ý=»(wÙË΀´9RÖÕÕEåˆãæ™gù|ž\WWk˜kìH’¤§s`ä²,£Ñh0;3³ô^t)Õ0dU¾B©£‹(ê`¶1YJØÉ?]{7¿ýòAr¹‡ésW]Í}W_MG±À^Ä‹6nä™Çǃ÷¯¡Ê"õF8މr9æff¶¶6â8¦Ñh4ß&§§¯]’$IOGËëbæ–GŒzzû€æ[ÌAÇüûݰm:á¨ÁŒŽbÈd­Äøð,íŇGšâz³~ùeܽ{7SÛïe±k4‚ááa®¿é^ðüKZëJ%qL{GQ”#IbÒ¥·~Éåò¤©oÃ!I’žÞ{«œ4M™Ÿ›£££“,Mi$!Å Á—¯­²XÊØÝÓQ¬s\ÇgÕK.—'Ž›‡ô`h~žßã›øïÿþ7ì»k+=ð›ŽÙÄÔØ3#á„ k¾QñâÂaQ,!ËhÔëÔêu:;:±¢¸$IÒÓ-°Zë`tw÷Јd@½³y};¯;ù^Hk uǬìh0Ø]äègl¡'‡Eغƒ„w¾ìøòÄÇyàþ{)Šôwu²¢\&Í2R HS::; ‚°ù~@”ËÑQ('qk£$I’žŽ‚å·ö=˜ÅËouKïž×\z!  „ $£ùÞwiš>fE@KK/AaØZl+Z^GkÉ‘ïq(I’ôt–‹"n¼áúæ¬Vä2‚”i+·žØ{íŇ\¶R‡¬ÖÑ\¢uOð=ÿ$I’žÒ 9¬”KÓ”±±ƒ?ñÐÉ2(–JD­ÅLªÕ Yæ›åH’¤§¿z½A__ÿr`%¬^3D>—ÿ‰ßpÆáï²¾¬$Iúùår<ôàÍÀÊ2ƒ(—sÏH’$= Y–‘Ïç—NšóÏ3\A]’$驺 $I’ ,I’$K’$ÉÀ’$I’%I’d`I’$X’$I2°$I’ ,I’$K’$I–$I’%I’d`I’$X’$I2°$I’ ,I’$K’$I–$I’%I’d`I’$ÉÀ’$I2°$I’ ,I’$X’$I–$I’%I’d`I’$ÉÀ’$I2°$I’ ,I’$X’$I–$I’%I’$K’$ÉÀ’$I2°$I’d`I’$X’$I–$I’%I’$K’$ÉÀ’$I2°$I’d`I’$X’$I–$I’ ,I’$K’$ÉÀ’$I’%I’d`I’$X’$I–$I’ ,I’$K’$ÉÀ’$I’%I’d`I’$X’$I2°$I’ ,I’$K’$ÉÀ’$I’%I’d`I’$X’$I2°$I’ ,I’$K’$I–$I’%I’d`I’$ÉÀ’$I2°$I’ ,I’$K’$I–$I’%I’d`I’$ÉÀ’$I2°$I’ ,I’$X’$I–$I’%I’$K’$ÉÀ’$I2°$I’ ,I’$X’$I–$I’%I’$K’$ÉÀ’$I2°$I’d`I’$X’$IOËÀ* îI’¤§H½^'¬×ëî I’¤§H¡Pð¡$IÒSÍÀ’$I2°$I’ ,I’$K’$I–$I’%I’d`I’$ÉÀ’$I2°$I’ ,I’$X’$I–$I’%I’d`I’$ÉÀ’$I2°$I’ ,I’$X’$I–$I’%I’$K’$ÉÀ’$I2°$I’d`I’$X’$I–$I’%I’$K’$ÉÀ’$I2°$I’d`I’$X’$I–$I’ ,I’$K’$ÉÀ’$I’%I’d`I’$X’$I–$I’ ,I’$K’$ÉÀ’$I’%I’d`I’$XÒ/º,Ëû3‚ h}îÐGû¾ ñ=?ê¶~Ô厼íÇ»®(Šˆ¢èq¿ÿÈë?ò6½¯‡n@E„aø¸ÛóD¶Q’žnrîéÉÅU¤iJ>Ÿ'_(0>6F#Žéîꢳ³“ùùùVp¤iJ©T"&&&h4”KeúúY\\|B255E’$DQDwww+r*•Jó:€ÎŽŠÅâÜî|>Ï÷¾w…Bž“O>™B¡ð˜ß¿|ý ‹‹”J%:;:Ȳ¬õ¹ö¶6J¥ÓÓÓÄIBG{;µZ{ï½—ÎÎNŽ;î¸Öþz¢Ò4å¶Ûn£^¯sÊ)§Ïç¬ËKÒÿiÁ¾½ÃY¡P P(ø&ý–ãêÎÞÉÇþþï¹ýöÛX\¬°~ýz.}Ñ yÃÞ@.×| †!×]wÿü/ÿ›{î¹›……Eúúû9夓xï{ÿ+]]]­ë Ã0 IÓ”4M[Ÿ{Å+^Áî=ÃäóyþöCäÌ3Ïà︂o]s F÷½ï}\ú¢‘¦éa#Jiš¶"®«»§õù{·ocíÚµ­˜J’¤u¹åë¸ýŽ;xå+/ãìsÎæ+_þ ¿û»¿ÃW¿úU^ø‚òWõ—¤iÊ«^ý+ ïásÿú¯lß¾_ýµ×²qãnÞº•\.G.—#Ë2Ò4% ›ƒçI’¶OÃ0$æææ8åÔÓåŽ;îà¨ëæv-_öÐû´¼Ï’$i~ú=ËCÇ>ÏIú‰½ð. l»ç.öïsKúÏü Ý~û¼úÕ¯fÿ¼éMobÍêUüëç>Ï;®x'·þà|êSŸ"n4øÄ'>ÉÛÞþvªÕ*—¿ñr†V¯a||œoç;LLNÒÙÙ @ww7ÃÃÃŒŽŽ±zõ*Ö ­env€##ÜÿýüïO}š3Î8©©i¹4ÑIDAT>÷ùÏ399 Àìì,AP(˜œœ`tt €£9†b¡@µZ%nÔy÷»ßE¹\¦««‹F£Áðð0Õj•“N:‰ƒ2;;ÇñÇofaaŽ?ž±±1n¸þvïÚIwwßþöwؽ{ߺæªÕ*sssÜ~ûídYFOoÇ{ò'ïaõêÕ„aHÇÜÿÀóyN:åî¾ënÚÚÛ8jãFæææÈ²ŒîînöîÝËÌÌ ›6m¢£½ñ0$—Ë‘¦Åbb±È½÷ÞK£Ñà¸Í› ƒ€jµÊþýû™›chõjzz{Ù3ýéOñ‘¿û;þë{ßË?ô!®½ö6¬_OÄqÌÛÞö6ÎzöÙ\tÑEœqæ³øÝßùFë6Ã0dýºu|ñ‹_¤Zkð¹Ï}Ž……Ö¬YÓúž(ŠøøÇ?ÎɧœÆ^Äyç_È™gžÉ7¾ñDQD._àƒü ýØÿGµZa±RáM¿õÛ¼ôe¿Ì›ßüfž}ö9\pá…¼ñMo¢T*Q(yÎsÎebb‚›o¾…mÛ·³ÿ~6oÞÌÄÄ8###Œ3>>Ά ëééîbxß^þþïÿž/~ዤiÊÁÑQžÿüpÙ«…¾à…œwþyœsÎ9¼ÿ Còù<þð‡9ûìsxîyçóÊË.£V«µöwElÛ¶óÏ¿€ç<÷<λàBN:éd¾ô¥/E9¾óïrιÏáãŸø$Aðð<ûìsgxï^.¸ð"~÷÷~—¶öÿóJ2°¤ŸåÀ:p`?÷lÛÀe—½’jµÊìì,]]]¼ö× €o}ë[ìØ¹“;vpÖYgqþyçýÈGxßûÞÇ'?ùÏÜrË­‹þò/þ’¿ùà‡8ñÄùÇüùðG>Â'?ùÏäóyòù<¯ý똙᳟ý ŸùÌg¹üòËY³zõa£kÏxÆ3ùèG?Â×þý«|ì£æàÈAÞô[¿ÕŠ–J¥ÊȤI YÆÜÜ,###ìÝ·|àýT*>ñ‰OróÍ·…!/yñK¸í¶Û¸ûî»H’„·üöo333Ëää7Ýt›6m¢½½ZµÊøÄ$£££ÄqÂÔÔ÷ß?gžy&ï|ç;™œœâøk濾÷J¦§§ùÓ+ßËé[Ngßþý­û477Ço¼îõÜ´u+¿óÖ·ò¾¿üKFFFxã›~‹áá=lÚ´‰F½Î~ðî»ï>n¹åV*• ·ßq_ý·caaK.¹„F½æ^I–ô³¬^oP­V[á³^išÒÛÓÓ ƒùyâF @WWgó̺(Ï_½ï}¼ë]ïâŠ+®àꫯ"Êåùܾ@[[oÛÛxåe—ñö·ý!ÿëþb© 4ç¶e /ù¥—ðŽw\Á?ü!¯ýµ_=ìl»,Ë(•Š|èƒâ’ç¿€×½þ LÏÌ066F½V{Ì`xÏ¿‡×¼æWÙ¼y3Û·o' ÃÖ¿o»ý6®¿þzzzxÝ^O¹\æÎ;ïä+W] Àó.¾øáù_@þ34´†ßÿýßãU—½Šþþ~æççI’”­[ofvv–cŽ9†Ë/¿œ·¾õ- 5Ÿ¤ÂíÛ·3<<Ìúµkù/ÿåí¼á ¯gË–-ÌÏÏsã 7rÌ1G³jÕ*î¿ÿ~î¼óNfffxæ3ŸÉÕW]Í7¿u /yÉK¨T*”d`I?«²,cpp¡¥Csûöík-cP*·qí·¿À±Ï|&ýýý‹E¶nÝÊüÜÕÊ"ßüÿà²W¾r¹nZ“¿£(¢­­L£^§kéLÁùùùÃã©XâU—½Š4MäYg=›8Ž—¯Š8ŽyÞ%Ïçúëoàÿú£wsÕ—¿ÜŠ•Ç;W±­­r…¥`Ìhn׆ ëéïïç–[nå_ÿ:[¶œFOO/Ï:óL>óÙÏòï4ïï‹_üâÖ¶<šb±H8«°R©¦)­‰ýËÓjµišR(ÃfÄ—Î~œ[˜gÅŠ ­YÃŽ;øü¾È–-§ñüK.ák_ÿ:<ð}}½¬^µÊÿ¸’ ,ég=°ÚÛÛyùË_ÀïÿÁrÏ=÷pàÀ>ðþÿÉ-·ÜÂÊ•+øõßøu6¿™_ù•W3;;Ç›ßú;lÛ¶,K;ƒ.ElÙrsss\uõ¿122§?õéf´\z)qÜ8$F¹ôÒqî¹çðö·ý!ù|þáe²æ™yÕj•þ>.~Þó=Ø:T÷˜÷çqîëÐÐýýýLMM1:6Æ…^D–ļô¥/åÆol~ÏšÕ¬ZÛ ¤G»æ,k~úù$iN>/‹<´cwßs?øÁš£v›6m¢»»‹##\ý lÛ¶û–&üŸõ¬³ˆã˜K/}‹‹‹\uÕU\|ñÅ<÷¹Ïe||œ|•+WÑßßߊ`IúIó,BéI‚€ùùy.¿ü7Ù³gøë¿æìsÎ¥­­ùùy¸ê+_¡\*Q«Vù‹ÿ÷/˜žžáª«®â›ßü&år™……Â0díÚµdYÆŸÿ?gû¶í¼ÿýïç#ù•J…£>Šw¾ó ª• •Jµuø­\.óõ¯}­i­E?É(‹¼âå/ç‹_úçœs.§vý80qx,hVOš¤­z´ò* œqÆé­³·œv*‹• ]|Q+Z^þò—“&Í3ô2jµËAóðrˇ«Õ*õz È8ñ„xé/½„Ï|ö_¹à‚ ééé¡P(,Í X³f W¾÷JÞü–·ð²_~9ù|žZ­Æå—ÿ&›7G¼ô¥/åÏþŸÿ¾´}[xîyÏ¥¯¯ÉÉIžóœs) ­e($é'þ{Âu°¤'7‚µ<ߪ»§—=ȵ×^ËwÝ͇?üa^øÂòÉú'rù\+@ºº{¸ãöÛ¸þ†¨,VZ;ÄùçŸÏšÕ«™%—ˆ!_þò—Ùµ{7Ö¯ç5¯yMk!Ò­7ßL­ZåÄO¤¯¯¯5S(ØzóÍLOOqâ '²råJÒ4峟ýWâ$áU—]ÆÝwßÅØø8—<ïbJ¥2_ûÚ×È œýìg†!wÜqó œqúéôõõ±õæ›™œœäÄN`åÊ•dYÆض};œvê© â8æ–[o¥^¯qâñ'008ØZLõ®»î¢³³“SO=•z½ÎÖ­[)•ËœyÆ4 n½õVÒ,ãÙgE.—£££ƒÏþóì?p€×þÚk¹ëî;Y\¬ðì³Î"ŸÏÓÕÕÉîÝÃ\}õÕTkUÎ;ï<Î:ëÙÌLOµÖðºñÆ £ˆSN9…þ~¾wÝuÌÍÍrê)§200ðc/x*I?Îï…C×Á2°¤ÿÄÓ²0 [o ó±}Œ¿ýðGøÍ׿Žw¿û݇͡Z~û— €4ÍH’¤5ª³üË9´Ò4%ŽãÖí,ÏIZ^€ôзªÉår­ÈXþÚòÄû8Ž[ x._ß¡_[Þ®C¿~äõz³,k-è¹¼,ÄúÞåu§–'âùïåëZ+¶/oóò×—ïg¸´.V$KûçÐQÅC}¬ý"I–ô4Ñêìì$Œš¿è§§&}?=Iú ,ç`IOå¨0 1båa)IúÅc`IOadú瑟—$ýâp™I’$K’$ÉÀ’$I2°$I’d`I’$X’$I–$I’ ,I’$K’$ÉÀ’$I’%I’d`I’$X’$I–$I’ ,I’$K’$ÉÀ’$I’%I’d`I’$X’$I2°$I’ ,I’$K’$I–$I’%I’d`I’$X’$I2°$I’ ,I’$K’$I–$I’%I’d`I’$ÉÀ’$I2°$I’ ,I’$X’$I–$I’%I’d`I’$ÉÀ’$I2°$I’ ,I’$X’$I–$I’%I’$K’$ÉÀ’$I2°$I’d`I’$X’$I–$I’%I’$K’$ÉÀ’$I2°$I’d`I’$X’$I–$I’ ,I’$K’$ÉÀ’$I2°$I’d`I’$X’$I¿8U(Ü ’$IO‘z½NX¯×Ý’$IO‘B¡à!BI’¤§š%I’d`I’$X’$I–$I’ ,I’$K’$ÉÀ’$I’%I’d`I’$X’$I2°$I’ ,I’$K’$ÉÀ’$I’%I’d`I’$X’$I2°$I’ ,I’$K’$I–$I’%I’d`I’$ÉÀ’$I2°$I’ ,I’$K’$I–$I’%I’d`I’$ÉÀ’$I2°$I’ ,I’$X’$I–$I’%I’$K’$ÉÀ’$I2°$I’ ,I’$X’$I–$I’%I’$K’$ÉÀ’$I2°$I’d`I’$X’$I–$I’ ,I’$K’$ÉÀ’$I2°$I’d`I’$X’$I–$I’ ,I’$K’$ÉÀ’$I’%I’d`I’$X’$I–$I’ ,I’$K’$ÉÀ’$I’%I’d`I’$X’$I2°$I’ ,I’$K’$I–$I’%I’d`I’$X’$I2°$I’ ,I’$K’$I–$I’%I’d`I’$ÉÀ’$I2°$I’ ,I’$X’$I–$I’%I’ô Xa{C’$éIhvÔòGF.KSF X*‘e™{H’$éIÊårÍ?ËmmK%ÒÔ¸’$Izò2V®XÅÎ;ÉeY 4J’$éÉ ˆ“˜ÈAˆÓ¯$I’ž‚ÄZŠ*Ï"”$IzŠX’$IOÒò ‚Gž(h`I’$=IAei–Q«ÖZ¡e`I’$ý˜¹ ‚€(–J4ÿf`I’$ýØ–G®²,%nÄ,ÌÏÓ¨ÕÈh†WÎ]$I’ô¤S‹|!O…DQÔúÜÿà ™ÂµvIEND®B`‚GoFigure2-v0.9.0/Documentation/Doxygen/Images/ReadMe.txt0000644000175000017500000000033311667757442022724 0ustar mathieumathieuThis folder contain screenshots for GUI classes (whenever it was possible to generate one). For the sake of style, images were all generated on Fedora Core 12 with Qt4.6.2, and with Fedora Style for windows appearance. GoFigure2-v0.9.0/Documentation/Doxygen/Images/QGoLUTDialog.png0000644000175000017500000003040211667757442023727 0ustar mathieumathieu‰PNG  IHDRIÓƒbvnsBITÛáOàtEXtSoftwaregnome-screenshotï¿> IDATxœíy@TUßÇ÷ÞÙ`Øw@QTÄÝ4µÔ\ÊÊȽMÍ]³¬,4ËÔ|2÷¥'Ó|*ÍÝW3sK d‡f¿÷¼\‡aP¸žóǽçþÎ9ßs¸ß9ç.s/U4~`0˜Vȉ_Y®òÌK/½¿RäÑîíWžkvI æ)àØ]WœñçÖØÕ‡Þ~éý•¼ÿä—jì& ƒÁ@I™ÆD36ó(ÒÍYã‡÷謽yðÈØ¹ÊÊ&“ŠÁ`l¥¤LSú 2ýÊIã#º¿À0ÈÍYR¤Ö@ŸÃàÏ­ñ@äÑBæè¢!AæåøG銄EB»,•ÇÆšc6ýy¿ñMÁ`0(} Uª+n&žzaÈ«í\êÏÈV<¶?çåá*÷'I²ºì: ¿p%Y§Óøète©š" KÁ¶Wa†Ä Ô¸–ZRP\šzãD„{{¹W¯èÌ…Dš¦ÃÂ}½<Ì«íÂ}¼<·ËßG«Ó•”–Q>vñbõŽÉ0êûêÙíBÚ» ÇõpsÓ úáÐÕ“‰÷ŒFÚÏé´ÜßÇ« ¸„ ãóɸÚÅFÉ &z׉´tEnpÃ0I)é#žkÓol´›“¸\k¸r#ï×ÿ¦‡· ãó©Ú6+ƒÜ¨¦Æø¹;Ò«4ÿÜÌ;qí~¨<àZJú°^Á1q]<œ%4ú³I÷÷œIŠŒ°Úuê¨7ñzúú9ƒ<]öž¾áé"éá§7>Œ²± Tu…¦ÓRËBJUeíýÑÁå¯Àš=Wò ”Vöþëb⯋G‰¼õ{¯Ü/(¾s÷>»ºvÏåÜ‚â{Ùyl»öŸ¹éã*íî£Ñ~?™ž|[ÖFnYÎå«×WÏèå }"ý­ã¿<8:¶}ˆ(wg E‘%eš³É÷\ÌèÔ¡Y¤@@M~©CßNZ½Ñ\²U?0Œ­ØÌT·YÖ}8bæªÃì‚9Ñ2†$ˆšçäVŽ]¼Ø¼œ HH8“bcAþ0E‘ÀžHS°voã¶N§ P‡`8záöß7 {vëB’¤F£=“¦ ô3{{tl{ ÂÙAøþȨéÿú³B£½sG1}tמ~ ƒ² Ëü<uièöÉæ_㦅›N»H³¦€ä;z#èåæ³ëtFEšfʈÎ};TjWo´ pñ|;wÇuû“ºD†[ÊNIͨ­^³)Gdžg”)Ë4þNßͲ± KBuÔX[K-Å@€«xÞ›½ˆ û®ÜÌ®kd¢ivA–ã'Tõ«¥ÊðJ¿vi÷”·³K;†xLýõŽsÅ%¥n®Ï ;H$Š|µ«£X*Th yÊr`€h/w×L‰ùb!¯cˆ'û=’cÎøjL¸Î`ÒL.ŽbsÉVýœ–шlÌýÇzjPL¯™«³~¶tõÌU‡Åô²ôAXÛ°Öãm3±òزQsòXvyGÿþì¨“ÅØýè¥R£õ÷tb—“oúùz‹Eò_„ïdêrÝܵÿ yÿ^8œ$‰ˆ`÷[y%2)Õ3ÂÖî¹|.%Wîí¸jæ @/çèv^÷ ËjÜÔ-Ü»Bk ÈS–/ßyÞ`DÈËÃ14È¿\UÜ·S|ºå”"_íã&ÝüѰîí}ݤ©å•RÉCÍ•Ú:ê=ŸšË†eæª>ÚxŠO¿,~…G‘¬`g1iKUn½Á؈–ZŠ ñs3°ŸGn9x5ùž:<,¸¤Tuë¶‚Ý*‹:u 7W‰šYhyüHº]øõŽsà‹ÉÏwnã5ü¹¶ÿÚ}ÕÕEf ^¿ÿêœ×»÷‰ôOÉ,ún÷ß"‘¨CxØŠUåg©H( †ôj3ª_»Þý÷$Ü2—œ]ôà“M§`Å/„ú¹°%[õC:°y©>n¿ð|O³½Yf®:üÂó=­öZ· FºŽúV\½=aû¤ØI€&ư‰“¶ÇÆM´%{3`21BÊb•f¬$™÷©ó׳]”%¥4z™Tä âWhTQ¡‡‹ ׳£:w¼–’®TkÜe’6~.|YÛ¦ýg2t“¯»ãoK^-TUÞÎ.ýãÂí¢UÇG—%×ÌyÑRC°¯LQR!ÙUuYE¨_­õž}4%ÞÌ÷öò(*V–k .Ž"¿R£êbS– ­Nß¾Q-5‹é×%üuólJ^‡ˆ°"¥ZBhö|ý»õ^¾ú³­Yºˆ¦«U³ž´{ÅÞÞžp=³¨s/¹·¬²Rcõ_³ô˜“£cÛÐà»Y÷t Õ¯T,0o’IEƒ‘â=Ü®ÜÈóòô€K鹡~.lÉõx¦­ÓéÃmîÀfÆ<ñ©Ô꫾• «Þ«õ\š%±òØØI±“Kˆ.Q]Ï^ YKÎÈÑ$[²7B‘0'÷áÉðÎm½öœ¹-•JI’Ôju%¥*?sdy¥'àAÓ ,÷~’$h!„H’°ª¢ú&D >Þð¿A=BCü\äÞÎÏwìÝÑêÊ?‚Ãç2,;F]iŠÄæ¾bl«W«7‘IÁ~O@0€Ø Þ*ê A-5£3˜D^L— £çoWj4!¨b1C‚òºÎ<Ò „ÊUÅ&DRæþ¬¶#YD¡²òrrÜ‹‘ðçnÝÌRvnë=¸GIV¹þCÈò A™èÑÔ÷I:°‰à?ú¢™‡÷œ^IL¶´áѱw÷èÎì*E’@’„±êmªõÏÉÍŒê2 uAQk¢`qÂâX€.sFÙž½Iø:”v¯¸C°Ç°>móŠËO&¦L´¿»ã Ñòÿ%ç[[©åóù™¹*v¹OdÀ_É顾Îì->wrU÷ ËjÛäæ,))QýôG2¿,~EÀ§½2sT@|»0ån1IPF“±Wßâ ÆÃ]h®]"gæÖV8iyàj5×âól¬ÂŠF·Ô,fÿ™›=#üBý\âߎùtËéÐÐ ùñns‹:D„%¥¤ktF‘€çéâp&)#:Ü÷ñAø#a¡‰#z½ñÑÔ¹[»H„¢@-‹«)'Ø]\$ Ê”ëôúç#ýÀ`¤ÿýI¯S¯êÍìá»çÔ  çk€-YgÐ?y6DÕ9yâµ³±-Ï¥±öŽŽêì·QÛœÜÆÆlOؾzäjE‚L6н¸m{ö&%$$`ÝžË_Oàæ,žúJô”Q]Q©Ñ=‘FQTmù|žR­½”žÛ3ÂoÆèîÃû†ùy8Àý²n¿ÆMWnäûyH·}6ân®ªX­ñp‘øàœâ•:¸˜šÓ»£ÿgŸKÉ,¢¦¿«L*Š[¼ßÍÅ• ö•X,¼ŸmªµÞÚÏÖ øü’2-UT9Þn\K-Å ôÒígWMàåôÉø>_n?×><¬[×NkCÈÑÑ!õnq¿.£cÛ‡¸µ—»#ôhœdÿbF"‘Y?íòÕdW‘Édú¿³nV;’P$Ì+.€¨0ŸÍT¨ªÜ{:|jΘ•Zã Ý‚«·Ô×Ýñߟ¾ 2©Žž¿íáá–“×Èl^ÌS%«Ã陫GuŽdÌn¯zžÜÚ†ÿgUùÔHÂö„$uR¬<6A‘@d9r¶y“Uv»||¡³»÷üu'œ¹™[\n¢Í ;9¥;_÷õõ¶lˆU‚6mäk÷^Ý›pCY¦ ôvÖè'®Üÿ÷_!!!µm ÔÓDâÍ<GQÏ~AÞΙ¹ª¿\ŠemÛ„¬?pu÷ÿÒŠÕšNm¼:†x–”i÷œJ—9»IXj®£Þº‡†ÛXÅ“·ÔJ %/Ý~V«7E{Ìz­Û½¬„eþ¾>ÿ9~=õn1àå*]»ç²Þh²jÃ0ðÛo¿õèÚùzú­Íûþ¾“¯qr”ZýO=ÝÝþ÷OVJf!Í0Á¾²_ÙÝ\õG’Ê*õ}#¼]öœJ¯¾£î?s3ñf¾HÀS•ë~8|õNNæìÔèlæåõm¡Î:Î\uxæªÃ;u¬-…'ˆÇ²¦ ¿(nÒ´û…jËÆÇÇE˜— 6 Û ‹'-€ÉKˆÅÄI?m7Ç,ù­†.¶ &“©°HYVöÀ`4"‘ÐÍÕÅÃÝ RÓ3 ƒŸ¯7{¢%5í¦Áh4¯2ˆÉÏ/R©ËŒFâ9;9ùúzñx¼:6Æû9yZ­Öh4@ŠDBo/™Ì©TjƒÁ@¤H(trrôöö$ ë#Ø:ê­G°ÍUX•Óˆ–Z¢ÕênÝΤF&s‘X×h4YÙ•¡@àããuÿ~Í0Aþn®.©éëçr‘ EñþóŸqqqã>û90´=/ HÊjÂb2™î)²+*+B cD»¢"eaQ1Í0ŽR‰D’_PH‘dçNÌ"}½½ôƒJ]FQ¤—§§§‡[Íý`s6'΢ãG÷½1fìܳHÅ¿NzqØè²Ê‡÷ŸMÌå»z[Q ²Œ^òVv!))iî¡W&ÆÄÀÃÛÑ€\ž`ñSˆÿ5퉄yfH»qkÃÜA2¾P(;¸x¸‡¯X>+..nÆ·¥®¾<¾€$)ÂÞ7‡ÙWGÉŸGöö4òAeý?aÑé7O½ôòk¥å¾@Óèò‰ÝõowéÒe6¬^shn(äg@ò‰(^;ÉÒØudÇ`ê@À—ÈÜ‚.Ú ëÄM_yࡽѳko‘4lô‰£ûüÃ{Ëœ¥õÆ«Ë*rn^4l´ÎH[Ùðá¸}7¯´¶ÌÌÓ%ýæ-½Vsä_ãÜ=ÃÂÚ¹uã´ƒD¶ü›iqqq¬8€Go‰HÀçQ'í·1þ…!¯M´ÆâŠ7BPÿ¸ÁÏòè]©Õ»:;¼<Šgw Íö¹ré’“DPY^ñ8±á4ÌÛ-Ónî5~ì­«µ‚bjÿ””–””–TOg÷À:26ççÒ¥¿ååV)­¶Þ\uݾž–1™w3¥Âz ·Qƒù XtoÃo7àÂ=§7ÒÓØÏ®]¿@Òµ«ìª½uq•ªtÔ𡣆U©žÝ‡^;:9>tÀ¼ºsÇO~þþvÔSOÇÛåååS¦L  jÖnéү̿à©-ÝŒR©ì3köìË—¯XÎØ ‚^¯gŽ9ÝÍ? ðð?´Äó.2™yõäÉSýbb||ýBBÛ|0}FEÅãGž>}ºŽÒàÇìÙ«·¯_d§Îß~»ê™üAR 3E•ªdÔð¡jµJ­V>T¥*±ÿäµÖOõVKâ1 ͦмÝeR¡L*¬­Ø±ã&ìÜñ›BÓ¦_Ù9nüDËê~غ©{T¤§«cD»ß|Uwù¿þçç¾½ºyº:ùyM}ÿ튊uêoOÇÛ~¸ ýFú±clÿiÛÎÿìܼyKÝé,………ÃGŒìѽǚ￯þªgK6mÞüóÏ?ÿþûîÿ;rdÃÆ¶H¢(ò«¥Kÿ¹rù—_þ“ž–¶èóÏm,mõêï·ý´}ù7Ëÿ¹²aýºÝ»w÷Ýj›zC0 ²ú”–ªF½<´cd§+W¯_¹z½cd§Q/--U™Ø·ÌUÏh—;ƒ­ž‚Ä0hii©þ÷Ôö¿ý¼}ÛÆõëØ˜Ý{@rZÆÍÛŠ›·µ;&n쥿/Þ»waПÇþàQ¼Øþ/˜ _µrÅ?l]þí¿®&§oØôî_ùvÅò:Ê'Hò«e+“Ò~ݽ7-õú'T‡þñ¼]QQqðС/—,騡Cß¾}gΜ¹ãçŸëHgÉÍÍöòðþýcW­ú¶Þ '-XСCDŸÞ½gÏšõË/¿Ú¢ê7ÞèׯŸŸŸ_ï^½>ÿüó#GŽÚRšÁ`ø~ÍšM7ôïßß××·_¿~K–,ÞöÓO èŽ" ^·fÝFÇãñÖ¬Ûøú˜8¡P`o]uÑ.TîïíÎ~F¼ü›XQQ~ðÀ¾¥_Ó1²ÓsÏ÷›5gþöŸ~d7¹¸¸€§‡§§——§W oöfñððxñ¥!¿ìÜ;wl;~‚Å;Œ ß·jÓÖûèëçÛÉWßlûqkåyó­˜Øþ~þþ½ûôýbñÒ#‡>­æ?…‹ ÷ “ÉÔ©Sgv5ªK—/¿\Ê0Lméìê+¯Ž~qðàe_mK‘‘‘ìBçÎîÞ½Ë0L¯§fILL\öÍòÔÔT­VKÓ´N§3µ•fÎuçNfEEŰ—‡›S†aó6èVÞÖNõ1B$–L›1˼‰ IËUx’¹cÀÊøó§% ›r=%eò„·ÀÝ»÷L&Sdç(6¦KT×%ñ‹h†!I=Ê[[+Ìã&Nž;kúÄÉïž:ybÅ¿Väç³éwnߪ¨(öâ@s1:­Ö`4òùüËOüçʲ¥KRSS´-ÍÐlp½JlÁn |áÔéÓyyy¾¾¾Píþa«‹7FóúcFŽñÉÂ]]]““SÞ}ï=[›ÄÀáCe2™eú3ueÕh4êõ¶¾DÒ ûKFdl ØçŸûøú:88°)ùùù 7èF= :VªÁh½^G’$›KoÐW{ép•bõz}ßçžGM}orï¾ÏyxxÜÏÊb3²eî=xØjÿ¡iÃÐÕË×h4¯½2|øˆQó?Zèêêr=%yê{ïhµsEæOO6x| sò`¹œÇ㥤$³«×’’BCCI’¬-]ýú«¯žþ¹W^­T*ÀÑÑ”ʇïN¿Qå…Þ©©©ìBJÊõzí;w•}¶è³nݺ…„„”T}³B¥µmÓÆÁÁ!''7¸*ÏØíV1`õÑTj·lÜ@›v•61[6nÐTjÍì(S=£]>ìxWcJ``0ÇKIJfÓ“¯] %€D °{‚¹uK9æÍ±çÏ}ë­ñ–é!!mr²s‚‚B,?€ˆË¿sëöƒ²²?YÔµk7¹Ÿ¿iÓæ‰&¤§§Y0«£4¡P8þ¼ùÎ×ê´½{õ2™LIIÉwïÞ?^#:ª•žu²J4èuû÷íÉȸ±âÛÕðñ‚¹i©©cÞ|K,Yån&•õP}Vû0E*u>bÔÒ%_xzzªÕêë×Μ=—ÝêççOÄñ?>ß/† WW·:Š;ïÃwÞ{_&s±¨ …ÂÙs?\¸`žN§íÙ«·ÉhLII¾w7söÜk,ßÏßÇçÿ°eãØño¤§mÙ´¾ªìÇú›ÉÛ/ j^ŽŽŽþïñ?W­úöü4dˆH$š0~üÔ©SØ­µ¥³PµyÓ¦ &Žy3nÿ¾½?lÝ2wÞüž½zu‹Ž^¸ðã÷ßüÞ{ï7¶¸XùÆë¯Ï˜>½^…nn®k×®Y²äËM7vïÑcÑ¢E¶—6{Ö,w7÷ ë7Ìž=‡Çã…‡‡Oš8±½ÔŠA ÃX_ttrüu÷ž·Þx­oÏh„««ë¯¿ïutr4G"@PõŒv•Á0´Yeʲå+?Y¸`İ…BÑ[ãÆ¿ýî{ìV77×O}ñåâÏ‹‹Š†ÉÎ/®£X’"e22×Â.L›>ÃÕÕuóÆuóçÌâóyaíÂÇŸX[ù2™ì_«×,ûêË-›6tëÞããO>›ñÁ«ÙªÓà™#1óƒ©k7lj±ïûçŸ^|iÈý,…ùÀ ÓtôúßwïzwÊ4¥ºæ[ÕjÕØ7_€_ví‘É\,7ݺy#*º{eå½€SNÞÏ?m>b„sÕn¯‘Üœì¶n}†Nalæá=Õqr–íüm»`ÃNkˈyBšiNŽá6!Tû5g''¨- ŽŒ˜'¡Ûҽݭ[·¥õa¦iiÔ/ÌYŸ® ·1O I’¸¿ 8¤M3?>ñ™Âd25ôñuØÛ ÂÅYV\¬Jë?aƒiNJ”*W‚hÀ )ØÛ˜ÇP$Õ¡SäßÏ÷èÙÓÝÝ“²ù‘š˜¦ƒ¦¥²èŸ+—»té* mψ½y I‘>Þ¾;F&]»Zþ ¼ÆÀbšŠ¢œe²Ž:º»»‹D¢ú3<{ó‚ øBAhh¨¿ŸŸ‰6ác-’$y<¾øÑï^l{c ÅãIl~6¦Å‚¨0n‚½Ápìm †›`oc0Ü{ƒá&ØÛ 7ÁÞÆ`¸ ö6ÃM°·1n‚½Ápìm †›`oc0Ü{ƒá&ØÛ 7ÁÞÆ`¸ ö6ÃM°·1n‚½Ápìm †›4àyinîM§ƒÁØ‚í¯ÙÁã6ÃM°·1n‚½Ápìm †›`oc0Ü{ƒá&ØÛ 7ÁÞÆ`¸ ‰’Û‰IDATö6×pwwG©Õj‚ ,ÓÿüóO„ÐË/¿Ì®¾ûíÛ·óù|N‡ªâêêj혧 ~'×èܹ3$''[½a·K—.lºÕjHHˆZ­ …2™Ìd2•”””––6»pÌSÛ\ÃìmËD//////•J•““c–”””‘‘áíí=sæLØ·oŸ··7k{Lk{›kÔèm«Áœ ˆN:Y†Õ˜ ÓªÁÞæux;))‰]•ËåNNN999æ¹7ö6÷ÀÞæ ""‚a˜´´4Ëô¶ÍV«að·9Exx8ŸÏÏÈÈÐjµ–éVòÕ*{4^RR’——×¼z1Mö6§¨qjM’dXXddd°)½zõ€Ë—/[å²:µŽiÕ`osŠÚ¼Íãñ OŸ>A¼ú꫃.**:qâ€'äœ{›S°Þþä“O ¾ÿþ{0™Lüñœ8qB¥RíÛ·¦éwÞyÇÒÀßß¿9›PoE¶Ëk9š—,Yb©Ùd2‰Åbûö³™)S¦°>ûì3›f¯ý`æSB%Êâz? *– ˆcÇŽ!„8ðûï¿#„Ì7<ÖPo®&µ{öìA:thß¾}¡ÔÔT¸téRffæúõëׯ_ÿÝwßÑlM°¥"åµ(Í“'OfïØ±!tñâEÛÒš-yå•WΟ?2dˆ-Mk ‘¶X5%éê̦6•·{ôèÁ>²‡]ÍÊÊ2 õÔ›«‰¨·Þ®]»"„6oÞ Aäää †èèh„Prròõë×·mÛæââbKQͦÙvy-G³%7n¤iº{÷îöíg+6mÚ„òöö¶Jo¶ŽµÝÛMuïJLL °·:Råîî~óæÍzêÍe/µùùùýû÷gÇꈈŸ¿þúkúôéð覮Ž;ŠÅ⸸¸fkB½Ù.¯åh63`À€iÓ¦­ZµêÊ•+Û¶m³±!M¡ÙŠ®]»æååX¥·¨ý™¥©Ž·»ví ‰‰‰.‘HØåºêÍe/µùùù J¥2::úøñãeee3f̸|ùòÚµk===»wïn2™ØÇ 6[ê­Èvy-G3‹££ã¶mÛ233ãããÔ¦Ðl ÇëÔ©ÓµkתojQûóCµMTnttôƒîÝ»š}õêÕzfΜYw.{©‚ ¦M›¶zõêÔÔÔ7ß|óöíÛæççåå¹¹¹ÙXTóhf l‘×lÝncç¬\¹2((hÀ€¦A i Í–´oß^$ÕXQ‹ÚŸYšjÜ )--e çΫ7 Þ\öRëääôÛo¿­[·nåÊ•½zõº}ûö¡C‡L&{ÿv=;fKQÍ£¹AòZˆf–^xaêÔ©?üðÃéÓ§Ú¦ÐlIþlQûóCšè\Zjj*Bè÷ßß¿?BèÈ‘#A,]ºtÅŠuÔ˜Øn˜ZŸ[·n!„.]ºÄžª]ºté‚ B‰‰‰›6mR©T%%%¡¡¡µÕüš$¯…hGGG…B‘››+“ÉØ»÷³%kÖ¬A²«vÙŸíž¼K—.—.]2™LJ¥rÍš5‰„ÏçëõúãÇ×P[b3P·Ú±cÇ¢ª?~œÇã­[·®¢¢¢²²òàÁƒmÛ¶­£]ͯ¹AòZˆfxtzäÈ‘æ,vïgKΞ=[RRÂúÓ^û³íÞ&f~0uí†M¥%Êz us÷xre æI°e”ÍÍÉþaëV|Ï)ÃM°·1nÒ➻´ ¨)Ñ*]P_@é¶”\£ Ëea}Á-Q³EN¾Ã£i ‰ ¨i¹J@}-K¨-ãã‹€*ËN+O°TVCbmË–ÁPïòS&Ë‘ÝÀã6ÃM°·1n‚½Ápìm †›`oc0Ü{ƒá&ØÛ 7ÁÞÆ`¸ ö6ÃM°·1n‚½Ápìm †›`oc0Ü{ƒá&ØÛ 7ÁÞÆ`¸ ö6ÃM°·1n‚½Ápìm †›`oc0Ü{ƒá&ØÛ 7iqÏ'7V[À<5,ûT]m¡…RYÓr®„´6ð¸Ápìm †›`oc0Ü{ƒá&ØÛ 7ÁÞÆ`¸I®•(‹›Nƒyºàqƒá&ØÛ 7ÁÞÆ`¸ ö6ÃM°·1n‚½Ápìm †›`oc0Ü{ƒá&ØÛ 7ÁÞÆ`¸ ö6ÃM°·1n‚½Ápìm †›`oc0Ü{ƒá&ØÛ 7ÁÞÆ`¸I‹{g¦Fš6Ñ4 do!ÍAPIQµîœ²œ)ÕÐ÷;„ €O2 ééHD2bo·ŒFcNvNZÚuµJeo-MI’ÎNÎáAA|>¿zP”˜² JÒïä””7¿Âf†¢HO‡¡~/÷`{»¥ÃÐtqQѵk‰ýcû…„ReoEM‹ÑhTÜËüëÌE‘”õaci]\Zv-ýÞ›ƒ£ÚySÕ8†Ñhºq/oÿ©ë|>ßI,s“Úº`o·tL4œ”4`ÀÀàÐP{kiø|~Û°pÅ¿pþœ§‡‡X*µ PV0É7o½&÷¶‹Âf†Ïçu ä‘Ô‘³é2g'Û½Íñï<.€JU(—Û[G³âXV¦6Ҧꛌ4*PU†x4¿*;Ò6È«@Ua¤p~Û­†a(ŠBÏȉ4àñx4Mרd„€¦ŸÁ¡hšiP‹ñ¸ÁpìmLò÷ßSUQQao!Ï"ØÛ­ôäåå͘1#$$D$yyy=úâÅ‹OR í<‰ø¦ë[ÈÊÊzûí·ýüüD"Q›6m.\øàÁóVö;«¼¼œ]MJJòòòš={6Ã0M'©¡û ö6ÇÉÊÊêÙ³gNNÎO?ý”‘‘qìØ±Ž;ÆÇÇÛ[W‹æîÝ»={ö,++Û»woFFƦM›  Ñhª_¹reàÀ“&Múþûï‰Ý\ÒÄ`osœ9sæDEE8p _¿~QQQ‹/Þ½{7»uÇŽQQQ‰ÄÝÝ}òäÉåååpéÒ%wêÔ©®]»J$’¾}ûÞ½{—G­^½:<<\,ûûûñÅæŠ6nÜØ¡C‰D"—Ë—.]Ê0Ló7öi1oÞ¼èèè={öôêÕ+00pàÀ'Ož¬¨¨Xµj•Uä… ^|ñÅéÓ§/_¾Ü.Rë{»ÕЈY܃þøãyóæY¥;;;³ $I®ZµêæÍ›HII™?¾yú·téÒÍ›7_»vÏçÏœ9“M_²dÉŠ+–.]š‘‘qèСàà`6ý›o¾Ù¼yóêÕ«322~üñÇ;w.[¶Ì\T#”#¦ +¶^}Á‚8˜síÚµŸþ™Mÿè£fÏž³k×®û÷ïgffîÝ»oÅŠ•5õ´våFwˆ-¬X±<1ñêØ±ã._¾œsêÔéaÆI¥sçᔇâñx?ÿ¼#<<|èÐaÙÙ9M' ásiœ1¨QW•Nûí·ï¾û^aa¡““Sß¾}?_´1Œ«‹Ë†õëãããׯßУGø/¾xçÝwƒƒ1k|´ŠÃ|öé§R©ôóÏ?ÏÍÍuww?~<3gö,77×5kÖNŸ>ƒÇãµoß~òäIˆa¬Šzš4¶Cl!X.O8}jÙ²oÞ|3N­V{{{¿úÊ+}´@$Ví1Œ€Ïÿå—ÿ¼þúÇÿãèQoo¯&RÕPˆ™L]»aSi‰ÒÞJ05cÐëß½ëÝ)ÓØ#½g‡ŸÚ6|Äg™‹Uúõþã–Ïú¬uÈ[OŽ~±O¤¿ ÞÈÜœì¶nÅãvk¡1³2Nƒ;¤°·[¡FLAÝÜëú‘s‰²ø Ù™Æuˆ-ÔÝiÐzú {»•Ш³)Ê⢺‹|Aö¦Qb uw´ž~ÃÞn$YQQÁù'¥YBÓtmí% (²¢¢’óOJ³„¦Š"ñsN¹A¸8ËŠ‹•žžÏÐS„J”JW‚¨Á½|ŠðvqÈ).ðtl~aö"§¸ÜÛE* `nìí–ER:Eþ}ñ|ž=ÝÝ=9?XÑ4£Týsår—.]Baõ72ª½üð¹Œ!½Úz:Q ÙÝ[#4î=8ö÷^ÛºIðßÇÞnééãíÛ±cdÒµ«åÊiš¶·¢¦…¢(g™¬c‡Žîîî"‘¨z€«”,wqêÒ^žp-«PUIÓ­øÇ¤¶@Q¤—‹CTû`O7gÛr ØÛ-‚ øBAhh¨¿ŸŸ‰6µ–9OI’<_,‘Ô¼• äî|©ÈÃÛÃÍXóã9û^Ò£!ÆìíÖÅãIª=©û™… ÀÑòp|†N.6޼a0Ï,ØÛ 7ÁÞÆ`¸ ö6ÃM°·1n‚½Ápìm †›`oc0Ü{ƒá&ØÛ 7ÁÞÆ`¸ÉÃûÉss²í«ƒÁ<]ˆ™Lµ· óôùWúüï«ÃNIEND®B`‚GoFigure2-v0.9.0/Documentation/Doxygen/CMakeLists.txt0000644000175000017500000000434411667757442022367 0ustar mathieumathieu# important note to link to external documentation # * qt.tags is located in ${QT_DOC_DIR}/html/qt.tags # * VTK Nightly doxygen tag file can be downloaded here: # http://www.vtk.org/files/Nightly/vtkNightlyDoc.tag.gz # http://www.vtk.org/files/Nightly/vtkNightlyDoc.tag # * ITK can be downloaded here: # SET( VTK_DOX_TAG ) SET( VTK_URL ) SET( ITK_DOC_TAG ) SET( ITK_URL ) IF( LINK_EXTERNAL_DOC ) OPTION( DOXYGEN_NIGHTLY_LINK "Link doxygen to the nightly doxygen of VTK and ITK" ON ) IF( DOXYGEN_NIGHTLY_LINK ) FILE( DOWNLOAD http://www.vtk.org/files/nightly/vtkNightlyDoc.tag ${GOFIGURE2_BINARY_DIR}/Documentation/vtkNightlyDoc.tag ) SET( VTK_DOX_TAG ${GOFIGURE2_BINARY_DIR}/Documentation/vtkNightlyDoc.tag CACHE FILEPATH "" FORCE ) SET( VTK_URL "http://www.vtk.org/doc/nightly/html" ) FILE( DOWNLOAD http://public.kitware.com/pub/itk/NightlyDoxygen/InsightDoxygen.tag ${GOFIGURE2_BINARY_DIR}/Documentation/InsightDoxygen.tag ) SET( ITK_DOX_TAG ${GOFIGURE2_BINARY_DIR}/Documentation/InsightDoxygen.tag CACHE FILEPATH "" FORCE ) SET( ITK_URL "http://www.itk.org/Doxygen/html" ) ELSE( DOXYGEN_NIGHTLY_LINK ) FIND_FILE( VTK_DOX_TAG NAMES vtkNightlyDoc.tag HINTS /usr/share DOC "Tag file for release of VTK" ) SET( VTK_URL "http://www.vtk.org/doc/release/${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION}/html" ) FIND_FILE( ITK_DOX_TAG NAMES InsightDoxygen.tag HINTS /usr/share DOC "Tag file for release of ITK" ) SET( ITK_URL "http://www.itk.org/Doxygen${ITK_VERSION_MAJOR}${ITK_VERSION_MINOR}/html" ) ENDIF( DOXYGEN_NIGHTLY_LINK ) FILE( COPY ${QT_DOC_DIR}/html/qt.tags DESTINATION ${GOFIGURE2_BINARY_DIR}/Documentation/ ) SET( QT_DOX_TAG ${GOFIGURE2_BINARY_DIR}/Documentation/qt.tags ) SET( QT_URL "http://doc.trolltech.com/4.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}" ) ENDIF( LINK_EXTERNAL_DOC ) CONFIGURE_FILE ( ${GOFIGURE2_SOURCE_DIR}/Documentation/Doxygen/Doxyfile.txt.in ${GOFIGURE2_BINARY_DIR}/Doxyfile.txt ) ADD_CUSTOM_TARGET(doc ALL ${DOXYGEN_EXECUTABLE} ${GOFIGURE2_BINARY_DIR}/Doxyfile.txt DEPENDS ${GOFIGURE2_BINARY_DIR}/Doxyfile.txt ) GoFigure2-v0.9.0/Documentation/Doxygen/Doxyfile.txt.in0000644000175000017500000021434311667757442022562 0ustar mathieumathieu# Doxyfile 1.7.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = @PROJECT_NAME@ # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @GOFIGURE2_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = @GOFIGURE2_BINARY_DIR@/Documentation # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = @GOFIGURE2_SOURCE_DIR@ # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = @GOFIGURE2_SOURCE_DIR@/ # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 2 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = YES # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = YES # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = YES # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @GOFIGURE2_SOURCE_DIR@ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.m \ *.mm \ *.dox \ *.py \ *.f90 \ *.f \ *.vhd \ *.vhdl \ *.C \ *.CC \ *.C++ \ *.II \ *.I++ \ *.H \ *.HH \ *.H++ \ *.CS \ *.PHP \ *.PHP3 \ *.M \ *.MM \ *.PY \ *.F90 \ *.F \ *.VHD \ *.VHDL \ *.C \ *.H \ *.tlh \ *.diff \ *.patch \ *.moc \ *.xpm \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = @GOFIGURE2_BINARY_DIR@ \ @GOFIGURE2_SOURCE_DIR@/Examples \ @GOFIGURE2_SOURCE_DIR@/BUILD \ @GOFIGURE2_SOURCE_DIR@/Code/Attic \ @GOFIGURE2_SOURCE_DIR@/Code/ExternalCode/PoissonReconstruction \ @GOFIGURE2_SOURCE_DIR@/Testing \ @GOFIGURE2_SOURCE_DIR@/KWStyle # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = moc_*.cxx \ ui_*.h \ */.git/* \ */*.dir/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = @GOFIGURE2_SOURCE_DIR@/Examples # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = YES # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = @GOFIGURE2_SOURCE_DIR@/Documentation/Doxygen/Images/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 3 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # If the HTML_TIMESTAMP tag is set to YES then the generated HTML # documentation will contain the timesstamp. HTML_TIMESTAMP = YES # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = @GOFIGURE2_SOURCE_DIR@/Documentation/Doxygen/DoxygenStyle.css # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvances is that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = @VTK_DOX_TAG@=@VTK_URL@ \ @QT_DOX_TAG@=@QT_URL@ \ @ITK_DOX_TAG@=@ITK_URL@ # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = GOFIGURE2.tag # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 1000 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES